I'm making a libgdx game where the player dodges falling objects. To move the player I have it set so that on desktop he moves left and right when you press A and D respectively. I am trying to implement three different methods for the android version:
- The player puts their finger on the screen and drags the character left and right.
- The screen is split into two vertical halves and each half acts as a 'move left' or 'move right' directional button. So if you pressed the left half, the character would move left and if you pressed the right half, the character would move to the right.
- Use the accelerometer to move the character.
I would prefer to implement method 2 but I would use method 1 if I can't get method 2 to work. Method 3 is just a bonus.
So far during my experimenting, the problem for method 1 has been that the character doesn't follow my finger exactly as it is on the screen. The problem for method 2 has been that I can't figure out how to get it to work. Likewise with method 3.
I would very much appreciate it if anyone could point out where I'm going wrong and/or suggest how to fix it.
Here are my relevant classes (sorry about all the commented out stuff, that's just some of my experimental code):
public class Player extends Entity {
OrthographicCamera camera;
Rectangle rectangle;
Vector3 touchPos;
MoveHelper moveHelper;
public Player(Vector2 pos, Vector2 direction) {
super(TextureManager.PLAYER, pos, direction);
rectangle = new Rectangle(); //for hitbox
moveHelper = new MoveHelper();
}
@Override
public void update() {
camera = new OrthographicCamera(240, 400);
camera.position.set(240 / 2, 400 / 2, 0);
rectangle.set(pos.x, pos.y + 40, 32, 22); //hitbox
touchPos = new Vector3();
moveHelper.left.set(0, 40, 120, 360);
moveHelper.right.set(121, 40, 119, 360);
pos.add(direction);{
//if (Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer)) [method 3]
//float accelX = Gdx.input.getAccelerometerX();
//pos.x = Gdx.input.getAccelerometerX();
//camera.unproject(touchPos);
if (Gdx.input.isTouched()){ //[method 2 below]
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if (moveHelper.left.contains(touchPos.x, touchPos.y)){
setDirection(-300, 0);}
else if (moveHelper.right.contains(touchPos.x, touchPos.y)){
setDirection(300, 0);}
else
setDirection(0, 0);
//[dragging method 1 below]
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
pos.x = touchPos.x;// - 16;//240 / 2 - 32;
//if (touchPos.x > Gdx.input.getX() && touchPos.x < Gdx.input.getX()){// + sprite.getWidth()) {
// if (touchPos.y > Gdx.input.getY() && touchPos.y < Gdx.input.getY()){// + sprite.getHeight()) {
// pos.x = touchPos.x;}}
//}
if(Gdx.input.isKeyPressed(Keys.A)) // left
setDirection(-300, 0);
else if(Gdx.input.isKeyPressed(Keys.D)) // right
setDirection(300, 0);
else
setDirection(0, 0);}
// make sure player stays inside stage
if (pos.x < 0) pos.x = 0;
else if (pos.x > 240 - 32) pos.x = 240 - 32;
}
}
}
My feeble attempt at making an input helper class:
public class MoveHelper {
public Rectangle left;
public Rectangle right;
public MoveHelper() {
left = new Rectangle ();
right = new Rectangle ();
}
//public void update() {
//left.set(0, 40, 120, 360);
//right.set(121, 40, 119, 360);
//}
}
My entity class which is extended by player:
public abstract class Entity {
protected Texture texture;
protected Vector2 pos, direction;
public Entity(Texture texture, Vector2 pos, Vector2 direction) {
this.texture = texture;
this.pos = pos;
this.direction = direction;
}
public abstract void update();
public void render(SpriteBatch sb) {
sb.draw(texture, pos.x, pos.y);
}
public Vector2 getPosition() {
return pos;
}
public Rectangle getBounds() {
return new Rectangle(pos.x, pos.y, texture.getWidth(), texture.getHeight());
}
public void setDirection(float x, float y) {
direction.set(x, y);
direction.scl(Gdx.graphics.getDeltaTime());
}
}
My entitymanager class:
public class EntityManager {
private final Array<Entity> entities = new Array<Entity>();
private final Player player;
public EntityManager(int amount) {
player = new Player(new Vector2(110, 15), new Vector2(0, 35));
for (int i = 0; i < amount; i++) {
float x = MathUtils.random(0, ManicMeltdowns.WIDTH - TextureManager.DROPS.getWidth());
float y = MathUtils.random(ManicMeltdowns.HEIGHT, ManicMeltdowns.HEIGHT * 3);
//float speed = MathUtils.random(2, 5);
float speed = 2;
addEntity(new Drops(new Vector2 (x, y), new Vector2(0, -speed)));
}
}
public void update() {
for (Entity e : entities)
e.update();
player.update();
//checkCollisions();
}
public void render(SpriteBatch sb) {
for (Entity e : entities)
e.render(sb);
player.render(sb);
}
private void checkCollisions() {
for (Drops e : getDrops()) {
if (e.getBounds().overlaps(player.rectangle)) {
//(e.getBounds().overlaps(player.getBounds())) {
ScreenManager.setScreen(new GameOverScreen());
}
}
}
public void addEntity(Entity entity) {
entities.add(entity);
}
private Array<Drops> getDrops() {
Array<Drops> ret = new Array<Drops>();
for (Entity e : entities)
if (e instanceof Drops)
ret.add((Drops)e);
return ret;
}
}
All of this is finally output in my gamescreen simply as "entityManager.update();" and "entityManager.render(sb);"
I know my code is terrible but any help would be great. Many thanks!
getBounds
or your rendering code. Please clean it up to only include the code directly related to the question. – Byte56♦ Feb 24 at 19:46