2

我正在使用 libgdx,并且我有一个平铺的地图,我想在上面绘制精灵。然而,精灵被绘制到实际的窗口上,所以当我移动相机时,精灵停留在同一个地方。?我想让精灵在地图上移动。

这就是我目前渲染对象的方式

    @Override
    public void render(float delta) {
        translateCamera();

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        camera.update();

        renderer.setView(camera);

        renderer.render(bgLayers);
        batch.begin();

        batch.draw(splayerSprite, Gdx.graphics.getWidth() / 2,
                Gdx.graphics.getHeight() / 2);

        batch.end();
        renderer.render(fgLayers);

    }

它总是最终位于屏幕中间,但是我希望能够单独移动它们,例如带有(W,A,S,D)的相机并使用方向键移动我的播放器。然后,如果我希望相机锁定在播放器上,但其他方面是免费的。

我是 libgdx 的新手,所以请多多包涵,谢谢

4

2 回答 2

6

问题是SpriteBatch投影矩阵未设置为相机投影矩阵。这意味着Sprite没有相对于 进行渲染Camera。这就是为什么相机在移动,而精灵却没有;未使用正确的矩阵。

此外,精灵总是以屏幕宽度的一半和屏幕高度的一半呈现。修复此调用sprite.draw。这将使用 Sprite 的内部位置。

通过batch.setProjectionMatrix(camera.combined)设置SpriteBatch投影矩阵。这将导致精灵相对于相机进行渲染。

@Override
public void render(float delta) {
    translateCamera();

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    camera.update();

    renderer.setView(camera);

    renderer.render(bgLayers);

    //here's the line that was missing.
    batch.setProjectionMatrix(camera.combined);
    batch.begin();

    //be sure to call this instead of specifying position yourself!
    splayerSprite.draw(batch);
    batch.end();
    renderer.render(fgLayers);

}

每当按下 WASD 时,您仍然需要处理将相机的位置捕捉​​到精灵的位置,但这很简单。

//snap the camera to the sprite's center.
if(wasd_isDown){
    float centerX = sprite.getX()+sprite.getWidth()/2;
    float centerY = sprite.getY()+sprite.getHeight()/2;
    camera.position.set(x,y, 0);
}

如果按下方向键,只需通过Vector3.add转换相机的位置矢量,如下所示:

if(!wasd_isDown){
    float deltaX = 0;
    float deltaY = 0;
    float MOVE_DIST = 10;//or whatever you need.

    if(leftPressed) deltaX = -MOVE_DIST;
    else if(rightPressed) deltaX = MOVE_DIST;

    if(upPressed)deltaY = MOVE_DIST;
    else if(downPressed)deltaY = -MOVE_DIST;

    camera.position.add(deltaX, deltaY, 0);
}

这将允许相机仅在玩家使用方向键时独立移动,并允许精灵相对于相机的方向进行渲染。当按下 WASD 时,它还会立即将相机捕捉回精灵。

于 2013-08-04T21:24:39.920 回答
2

batch.draw(splayerSprite, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);

您是在告诉代码每次都将其绘制到屏幕的中心。您需要根据您的输入更改Gdx.graphics.getWidth() / 2和更改实际值。Gdx.graphics.getHeight() / 2

编辑#2batch.setProjectionmatrix(camera.combined);除了我提到的所有内容之外,还需要该行,我都没有注意到我的代码中已经有特定的行(它包含在默认的 libGDX 项目中),并且没有尝试使用该行运行我的演示删除。我希望这能消除我可能造成的任何困惑。

编辑:由于显然没有人真正喜欢我的答案,所以我使用干净的 libGDX 游戏中指定的控件编写了一个演示。无论相机瞄准哪里(因为它正在被平移),精灵总是被渲染在全局屏幕的中心。非常有必要使用精灵的位置来batch.draw()代替静态位置,否则它不会移动。

package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;

public class MyGdxGame implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Texture texture;
    private Sprite sprite;
    private Sprite background;

    private boolean lockToSprite;
    private Vector2 vecCamera;
    private Vector2 vecSprite;

    @Override
    public void create() {      
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera(w, h);
        batch = new SpriteBatch();

        lockToSprite = true;
        vecCamera = new Vector2();
        vecSprite = new Vector2();

        texture = new Texture(Gdx.files.internal("data/libgdx.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);

        sprite = new Sprite(region);
        sprite.setSize(0.1f * sprite.getWidth(), 0.1f * sprite.getHeight());
        sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
        sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);

        background = new Sprite(region);
        background.setOrigin(background.getWidth() / 2, background.getHeight() / 2);
        System.out.println(background.getOriginX());
        background.setPosition(-background.getWidth() / 2, -background.getHeight() / 2);
    }

    @Override
    public void dispose() {
        batch.dispose();
        texture.dispose();
    }

    @Override
    public void render() {
        camera.translate(vecCamera);

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        camera.update();

        camera.translate(vecCamera.cpy().mul(-1));

        float moveSensitivity = 0.9f;

        Vector2 vecInputSprite = new Vector2();
        if (Gdx.input.isKeyPressed(Keys.UP))
            vecInputSprite.y += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.DOWN))
            vecInputSprite.y -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.LEFT))
            vecInputSprite.x -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.RIGHT))
            vecInputSprite.x += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.N))
            vecSprite.set(new Vector2());

        Vector2 vecInputCamera = new Vector2();
        if (Gdx.input.isKeyPressed(Keys.W))
            vecInputCamera.y += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.S))
            vecInputCamera.y -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.A))
            vecInputCamera.x -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.D))
            vecInputCamera.x += moveSensitivity;

        if (Gdx.input.isKeyPressed(Keys.R)) {
            vecCamera.set(new Vector2());
            lockToSprite = false;
        }

        if (vecInputCamera.len2() != 0)
            lockToSprite = false;
        else if (Gdx.input.isKeyPressed(Keys.L))
            lockToSprite = true;

        if (lockToSprite) {
            vecCamera.set(vecSprite);
        } else {
            vecCamera.add(vecInputCamera);
        }

        vecSprite.add(vecInputSprite);

        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        background.draw(batch);
        sprite.setPosition(vecSprite.x, vecSprite.y);
        sprite.draw(batch);
        //batch.draw(sprite, vecSprite.x, vecSprite.y);
        batch.end();
    }

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

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}
于 2013-08-04T04:35:38.253 回答