Sprite not moving properly. libgdx

2019-06-10 12:04发布

问题:

I'm new to libgdx, I'm trying to make a sprite move while the camera follows. I can make the sprite move perfectly until I attach the camera to it. When I click, the sprite will move wherever it feels like (it seems) and the camera will follow properly. I've tried a few different things but at this point its just guessing and checking.

public class MyGdxGame implements ApplicationListener {
OrthographicCamera mCamera;
SpriteBatch mBatch;
Texture mTexture, mMap;
Sprite sprite;
float touchX, touchY;
float spriteX, spriteY, speed = 5;

@Override
public void create() {
    float CAMERA_WIDTH = 480, CAMERA_HEIGHT = 320;

    mBatch = new SpriteBatch();
    mTexture = new Texture(Gdx.files.internal("data/logo.png"));
    mMap = new Texture(Gdx.files.internal("data/sc_map.png"));
    mCamera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
    mCamera.setToOrtho(false, CAMERA_WIDTH, CAMERA_HEIGHT);
}

@Override
public void dispose() {

}

@Override
public void render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    mBatch.setProjectionMatrix(mCamera.combined);
    mCamera.update();
    mBatch.begin();
    updateInput();
    drawD();
    mBatch.end();

}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

public void drawD() {
    mCamera.position.set(spriteX, spriteY, 0);
    mBatch.draw(mMap, 0, 0);
    mBatch.draw(mTexture, spriteX, spriteY);

}

public void updateInput() {

    if (Gdx.input.justTouched()) {

        touchX = Gdx.input.getX();
        touchY = Gdx.input.getY();

    }
    if (touchX != spriteX) {

        if (spriteX < touchX) {
            spriteX += speed;
        }
        if (spriteX > touchX) {
            spriteX -= speed;
        }
    }
    if (touchY != spriteY) {
        if (spriteY > Gdx.graphics.getHeight() - touchY) {
            spriteY -= 10;
        }
        if (spriteY < Gdx.graphics.getHeight() - touchY) {
            spriteY += 10;
        }
    }

}

}

回答1:

Since you have spent a decent amount of time and are trying to get it working, I will give you a little push forward closer to what you are looking for. Look over the changes I made and below I will outline what I did to help you understand the code better.

  • Orthographic Camera, when you setup the camera 0,0 is the center of the screen. The width and the height are what you specified into the constructor. So the top edge would be x, 160 and the bottom edge would be x, -160. The left edge would be -240, y and the right edge would be 240, y.
  • drawD() Notice that I'm drawing the sprite in the middle of the image and it isn't moving. I instead move the map around in the opposite direction (y is inverted).
  • updateInput() Notice I pass in a delta value (this is the time in seconds between frames) this allows you to smoothly move things. The speed is 120, so this will smoothly move your character at a rate of 120/second.
  • The if condition is basically a simply way to compare the float values so it stops when it gets close enough. This prevents it from over shooting the target position and then bouncing back and forth because it might not be able to get to the exact value.
  • I added dispose calls for the textures you loaded, these are important as you don't want to fill up your memory.

I hope this helps get you started and pointed in the right direction. Working on games is a lot of work and takes time, so be patient and be ready to learn lots along the way!

Based on your comment I believe what you are looking for is something closer to this:

public class MyGdxGame implements ApplicationListener {
    OrthographicCamera mCamera;
    SpriteBatch mBatch;
    Texture mTexture, mMap;
    float touchX, touchY;
    float spriteX, spriteY, speed = 120;

    final float CAMERA_WIDTH = 480, CAMERA_HEIGHT = 320;

    @Override public void create() {
        mCamera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);

        mBatch = new SpriteBatch();
        mTexture = new Texture(Gdx.files.internal("data/logo.png"));
        mMap = new Texture(Gdx.files.internal("data/sc_map.png"));
    }

    @Override public void dispose() {
        mTexture.dispose();
        mMap.dispose();
    }

    @Override public void render() {
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        updateInput(Gdx.graphics.getDeltaTime());
        mCamera.update();
        mBatch.setProjectionMatrix(mCamera.combined);
        mBatch.begin();
        drawD();
        mBatch.end();
    }

    @Override public void resize(final int width, final int height) {}

    @Override public void pause() {}

    @Override public void resume() {}

    public void drawD() {
        mBatch.draw(mMap, -spriteX - (mMap.getWidth() / 2), spriteY - (mMap.getHeight() / 2));
        mBatch.draw(mTexture, -32, -32, 64, 64);
    }

    public void updateInput(final float delta) {
        if (Gdx.input.justTouched()) {
            touchX = Gdx.input.getX() - (Gdx.graphics.getWidth() / 2);
            touchY = Gdx.input.getY() - (Gdx.graphics.getHeight() / 2);
        }
        final float dv = delta * speed;
        if (Math.abs(touchX - spriteX) > 1) {
            if (spriteX < touchX) {
                spriteX += dv;
            }
            if (spriteX > touchX) {
                spriteX -= dv;
            }
        }
        if (Math.abs(touchY - spriteY) > 1) {
            if (spriteY > touchY) {
                spriteY -= dv;
            }
            if (spriteY < touchY) {
                spriteY += dv;
            }
        }
    }
}