我正在使用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的新手,所以请耐心等待,谢谢
答案 0 :(得分:6)
问题是SpriteBatch投影矩阵未设置为Camera投影矩阵。这意味着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时,它还会立即将相机拍摄回精灵。
答案 1 :(得分:2)
batch.draw(splayerSprite, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
您告诉代码每次将其绘制到屏幕中心。您需要将Gdx.graphics.getWidth() / 2
和Gdx.graphics.getHeight() / 2
更改为根据您的输入更改的实际值。
编辑#2 :除了我提到的所有内容之外,还需要行batch.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() {
}
}