Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.harvesttownship.game.ui;
- import java.util.ArrayList;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.graphics.g2d.TextureRegion;
- public class CircularMenu {
- public static final int
- LEFT = 0,
- RIGHT = 1;
- public interface CircularMenuItemListener {
- void onSelect();
- }
- class CircularMenuItem {
- private float x, y;
- private TextureRegion tex;
- private CircularMenuItemListener listener;
- public CircularMenuItem(float x, float y, TextureRegion tex, CircularMenuItemListener listener) {
- this.x = x;
- this.y = y;
- this.tex = tex;
- this.listener = listener;
- }
- public void select() {
- listener.onSelect();
- }
- public void render(SpriteBatch batch, float centerX, float centerY) {
- batch.draw(tex, x + centerX, y + centerY);
- }
- public float getX() {
- return x;
- }
- public void setX(float x) {
- this.x = x;
- }
- public float getY() {
- return y;
- }
- public void setY(float y) {
- this.y = y;
- }
- public void setPosition(float x, float y) {
- setX(x);
- setY(y);
- }
- public TextureRegion getTexture() {
- return tex;
- }
- }
- private ArrayList<CircularMenuItem> items;
- private int x, y;
- private int topItem = 0;
- private int direction;
- private int radius;
- private boolean moving;
- public CircularMenu(int x, int y, int radius) {
- items = new ArrayList<CircularMenuItem>();
- this.x = x;
- this.y = y;
- this.radius = radius;
- }
- private double getCirclularItemAngle(int item) {
- // 2pi = 360 degrees
- // 360 degrees / number of items = degree of each item
- double angle = ((Math.PI * 2) / items.size());
- // 90 degrees - (degree of item * item index) = 90 degrees - item render degree
- angle = (Math.PI / 2) - (angle * item);
- // item render degree
- return (angle < 0) ? (Math.PI * 2) + angle : angle;
- }
- private double getCartesianX(double angle) {
- // polar: (r, angle) cartesian: (x, y)
- // cos(angle) => x
- return radius * Math.cos(angle);
- }
- private double getCartesianY(double angle) {
- // polar: (r, angle) cartesian: (x, y)
- // sin(angle) => y
- return radius * Math.sin(angle);
- }
- private double getCircularItemX(int item) {
- return getCartesianX(getCirclularItemAngle(item));
- }
- private double getCircularItemY(int item) {
- return getCartesianY(getCirclularItemAngle(item));
- }
- public void move(int direction) {
- // Shift items left
- if (direction == LEFT) {
- this.direction = LEFT;
- if (topItem + 1 >= items.size())
- topItem = 0;
- else
- topItem++;
- // Shift items right
- } else if (direction == RIGHT) {
- this.direction = RIGHT;
- if (topItem - 1 < 0)
- topItem = items.size() - 1;
- else
- topItem--;
- }
- }
- public void update(float delta) {
- // Check if defined top item is at the top of the menu, if not move it there
- double diffY = items.get(topItem).y - getCircularItemY(0);
- // Round diff down
- diffY = Math.floor(diffY * 100) / 100;
- moving = true;
- if (diffY >= -1 && diffY <= 1)
- moving = false;
- // Move all menu items ±1 angle each frame until top item is at the top of the menu
- if (moving) {
- for (CircularMenuItem item : items) {
- // Convert current (x, y) to angle
- double angle = Math.atan2(item.getY(), item.getX());
- // Convert (angle ± 1) to (x, y), left (+1) by default
- float x = (float) (radius * Math.cos(angle + 0.1d));
- float y = (float) (radius * Math.sin(angle + 0.1d));
- if (direction == RIGHT) {
- x = (float) (radius * Math.cos(angle - 0.1d));
- y = (float) (radius * Math.sin(angle - 0.1d));
- }
- // Set position
- item.setPosition(x, y);
- }
- }
- }
- public void select() {
- int item = -1;
- int highY = -1;
- for (int i = 0; i < items.size(); i++) {
- if (items.get(i).getY() > highY) {
- highY = (int) items.get(i).getY();
- item = i;
- }
- }
- items.get(item).select();
- }
- public void render(SpriteBatch batch, float delta) {
- update(delta);
- for (CircularMenuItem item : items)
- item.render(batch, x, y);
- }
- public void addItem(TextureRegion tex, CircularMenuItemListener listener) {
- addItem(new CircularMenuItem(0, 0, tex, listener));
- }
- public void addItem(CircularMenuItem item) {
- items.add(item);
- // Update item positions to be evened out
- for (int i = 0; i < items.size(); i++) {
- float x = (float) getCircularItemX(i);
- float y = (float) getCircularItemY(i);
- items.get(i).setPosition(x, y);
- }
- }
- public int getRadius() {
- return radius;
- }
- public void setRadius(int radius) {
- this.radius = radius;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement