相机没有在 LibGDX 中移动?
Camera is not moving in LibGDX?
我正在和朋友一起做一个项目,我做了我的一部分,这与视口和相机有关。当我测试它时,相机很好,移动也很好,但现在我们把我们的部分放在一起,我不得不将我的一些代码移动到 PlayState class。现在精灵在移动,但相机从一开始就没有正确设置,看起来它不能移动。这里有什么问题?
这是一些代码:
游戏class:
package com.platformer.game;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.platformer.managers.GameStateManager;
public class Game implements ApplicationListener{
private GameStateManager gsm;
SpriteBatch batch;
final float WIDTH=480;
final float HEIGHT=320;
float dx,dy;
public Viewport viewport;
public OrthographicCamera camera;
public void create () {
gsm = new GameStateManager();
batch = new SpriteBatch();
float aspectRatio=(float)Gdx.graphics.getWidth()/(float)Gdx.graphics.getHeight();
camera=new OrthographicCamera();
viewport=new FitViewport(HEIGHT*aspectRatio,HEIGHT,camera);
viewport.apply();
}
public void render () {
//clear frame
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.translate(dx,dy);
//update and draw gamestate
gsm.update(Gdx.graphics.getDeltaTime());
gsm.draw();
camera.update();
batch.begin();
batch.setProjectionMatrix(camera.combined);
batch.end();
}
public void resize(int width, int height) {
viewport.update(width,height);
camera.position.set(WIDTH,HEIGHT/2,0);
}
public void pause() {
}
public void resume() {
}
public void dispose() {
}
public void setCamera(float dx,float dy){
this.dx=dx;
this.dy=dy;
}
public float getWIDTH(){return WIDTH;}
public float getHEIGHT(){return HEIGHT;}
}
播放状态class:
package com.platformer.gamestates;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.platformer.game.Game;
import com.platformer.managers.GameStateManager;
public class PlayState extends GameState{
SpriteBatch batch;
Sprite right,left,background,character;
float dx,dy;
Game game=new Game();
float lx=game.getWIDTH()/2+5,ly=5,cx=game.getWIDTH()/2+165,cy=45;
public PlayState(GameStateManager gsm){
super(gsm);
}
public void init(){
dx=0;
dy=0;
batch = new SpriteBatch();
background=new Sprite(new Texture(Gdx.files.internal("happyplace.png")));
right=new Sprite(new Texture(Gdx.files.internal("go_right.png")));
left=new Sprite(new Texture(Gdx.files.internal("go_left.png")));
character=new Sprite(new Texture(Gdx.files.internal("char.png")));
}
public void update(float dt){
handleInput();
left.setPosition(lx,ly);
right.setPosition(lx+80,ly);
character.setPosition(cx,cy);
game.setCamera(dx,dy);
dx=0;
dy=0;
}
public void draw(){
batch.begin();
background.draw(batch);
right.draw(batch);
left.draw(batch);
character.draw(batch);
batch.end();
}
public void handleInput(){
//some movement bits
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){dx+=5f;lx+=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){dx-=5f;lx-=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.UP)){dy+=5f;ly+=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.DOWN)){dy-=5f;ly-=5f;}
if(Gdx.input.isTouched()){
if(Gdx.input.getX()<40
&&Gdx.input.getY()>game.getHEIGHT()-40){dx-=5f;lx-=5f;cx-=5f;}
if(Gdx.input.getX()<120
&&Gdx.input.getX()>80
&&Gdx.input.getY()>game.getHEIGHT()-40){dx+=5f;lx+=5f;cx+=5f;}
}
}
public void dispose(){
background.getTexture().dispose();
left.getTexture().dispose();
right.getTexture().dispose();
}
}
第二次编辑
好的,我只是注意到您有两个不同的 SpriteBatches,所以您甚至没有使用正在使用相机的精灵批次进行绘图。在您的游戏 class 中,您有一个正在应用相机的精灵批次。但是你永远不会使用那个 sprite 批次来绘制任何东西。在您的 PlayState class 中,您有另一个精灵批次用于绘图,但您从未将相机应用于它。
PlayState 甚至不需要对 SpriteBatch 的成员引用,所以只需将其删除并将游戏的批处理引用传递到您的绘制方法中:
public void draw(SpriteBatch batch){
//...
}
第一次编辑:
在您的 handleInput
方法中,您将 dx
和 cx
调整相同的量以响应触摸输入。但是,您将角色位置设置为 cx
,但对于相机,您通过调用 camera.translate
而不是 add dx
到任何当前相机位置=17=].
你会遇到的另一个问题是你在移动东西时忽略了增量时间,所以你的移动速度将与游戏的帧速率相关联,这是你无法真正控制的,并且是不一定总是不变的。任何时候你改变一个位置,你应该通过增加或减去一些常量乘以增量时间来完成。
尝试用移动的相机移动 UI 按钮也有点不寻常且容易出错。如果您的游戏有一个移动的摄像机,您应该为 UI 元素使用一个单独的静态摄像机,这样它们就可以相对于屏幕进行定义。
顺便说一句,你应该在绘制场景之前更新并应用相机,否则你想要的相机位置会延迟一帧。而且您不必在 spriteBatch.begin()
和 end()
之间调用 spriteBatch.setProjectionMatrix()
。
我还注意到您的 PlayState class 正在实例化一个无用的游戏实例 class。
我正在和朋友一起做一个项目,我做了我的一部分,这与视口和相机有关。当我测试它时,相机很好,移动也很好,但现在我们把我们的部分放在一起,我不得不将我的一些代码移动到 PlayState class。现在精灵在移动,但相机从一开始就没有正确设置,看起来它不能移动。这里有什么问题? 这是一些代码:
游戏class:
package com.platformer.game;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.platformer.managers.GameStateManager;
public class Game implements ApplicationListener{
private GameStateManager gsm;
SpriteBatch batch;
final float WIDTH=480;
final float HEIGHT=320;
float dx,dy;
public Viewport viewport;
public OrthographicCamera camera;
public void create () {
gsm = new GameStateManager();
batch = new SpriteBatch();
float aspectRatio=(float)Gdx.graphics.getWidth()/(float)Gdx.graphics.getHeight();
camera=new OrthographicCamera();
viewport=new FitViewport(HEIGHT*aspectRatio,HEIGHT,camera);
viewport.apply();
}
public void render () {
//clear frame
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.translate(dx,dy);
//update and draw gamestate
gsm.update(Gdx.graphics.getDeltaTime());
gsm.draw();
camera.update();
batch.begin();
batch.setProjectionMatrix(camera.combined);
batch.end();
}
public void resize(int width, int height) {
viewport.update(width,height);
camera.position.set(WIDTH,HEIGHT/2,0);
}
public void pause() {
}
public void resume() {
}
public void dispose() {
}
public void setCamera(float dx,float dy){
this.dx=dx;
this.dy=dy;
}
public float getWIDTH(){return WIDTH;}
public float getHEIGHT(){return HEIGHT;}
}
播放状态class:
package com.platformer.gamestates;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.platformer.game.Game;
import com.platformer.managers.GameStateManager;
public class PlayState extends GameState{
SpriteBatch batch;
Sprite right,left,background,character;
float dx,dy;
Game game=new Game();
float lx=game.getWIDTH()/2+5,ly=5,cx=game.getWIDTH()/2+165,cy=45;
public PlayState(GameStateManager gsm){
super(gsm);
}
public void init(){
dx=0;
dy=0;
batch = new SpriteBatch();
background=new Sprite(new Texture(Gdx.files.internal("happyplace.png")));
right=new Sprite(new Texture(Gdx.files.internal("go_right.png")));
left=new Sprite(new Texture(Gdx.files.internal("go_left.png")));
character=new Sprite(new Texture(Gdx.files.internal("char.png")));
}
public void update(float dt){
handleInput();
left.setPosition(lx,ly);
right.setPosition(lx+80,ly);
character.setPosition(cx,cy);
game.setCamera(dx,dy);
dx=0;
dy=0;
}
public void draw(){
batch.begin();
background.draw(batch);
right.draw(batch);
left.draw(batch);
character.draw(batch);
batch.end();
}
public void handleInput(){
//some movement bits
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){dx+=5f;lx+=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){dx-=5f;lx-=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.UP)){dy+=5f;ly+=5f;}
if(Gdx.input.isKeyPressed(Input.Keys.DOWN)){dy-=5f;ly-=5f;}
if(Gdx.input.isTouched()){
if(Gdx.input.getX()<40
&&Gdx.input.getY()>game.getHEIGHT()-40){dx-=5f;lx-=5f;cx-=5f;}
if(Gdx.input.getX()<120
&&Gdx.input.getX()>80
&&Gdx.input.getY()>game.getHEIGHT()-40){dx+=5f;lx+=5f;cx+=5f;}
}
}
public void dispose(){
background.getTexture().dispose();
left.getTexture().dispose();
right.getTexture().dispose();
}
}
第二次编辑 好的,我只是注意到您有两个不同的 SpriteBatches,所以您甚至没有使用正在使用相机的精灵批次进行绘图。在您的游戏 class 中,您有一个正在应用相机的精灵批次。但是你永远不会使用那个 sprite 批次来绘制任何东西。在您的 PlayState class 中,您有另一个精灵批次用于绘图,但您从未将相机应用于它。
PlayState 甚至不需要对 SpriteBatch 的成员引用,所以只需将其删除并将游戏的批处理引用传递到您的绘制方法中:
public void draw(SpriteBatch batch){
//...
}
第一次编辑:
在您的 handleInput
方法中,您将 dx
和 cx
调整相同的量以响应触摸输入。但是,您将角色位置设置为 cx
,但对于相机,您通过调用 camera.translate
而不是 add dx
到任何当前相机位置=17=].
你会遇到的另一个问题是你在移动东西时忽略了增量时间,所以你的移动速度将与游戏的帧速率相关联,这是你无法真正控制的,并且是不一定总是不变的。任何时候你改变一个位置,你应该通过增加或减去一些常量乘以增量时间来完成。
尝试用移动的相机移动 UI 按钮也有点不寻常且容易出错。如果您的游戏有一个移动的摄像机,您应该为 UI 元素使用一个单独的静态摄像机,这样它们就可以相对于屏幕进行定义。
顺便说一句,你应该在绘制场景之前更新并应用相机,否则你想要的相机位置会延迟一帧。而且您不必在 spriteBatch.begin()
和 end()
之间调用 spriteBatch.setProjectionMatrix()
。
我还注意到您的 PlayState class 正在实例化一个无用的游戏实例 class。