场景 2D 从视口坐标和游戏坐标分离
Scene 2D Separation from viewport coordinates and game coordinates
为了练习我的 Java 技能,我一直在开发一个基本的贪吃蛇游戏。使用 java,我使用 LibGDX 和 Scene2d 来处理我的所有对象。
现在,贪吃蛇游戏的边界设置为视口尺寸。每当蛇到达视口外部时,都会检查碰撞。我正在使用合并到舞台中的屏幕视口,如下所示。
private AudioSnake gameCore;
private Stage gameStage;
private Image background;
private Image snakeTip;
private Image food;
private ArrayList<Image> snakeTail = new ArrayList <Image>(); // all the snake tail bits
private ScreenViewport viewport;
public GameScreen(AudioSnake audioSnake) {
gameCore = audioSnake;
viewport = new ScreenViewport();
gameStage = new Stage(viewport);
Gdx.input.setInputProcessor(gameStage);
uiSkin = new Skin(Gdx.files.internal("Ui/uiskin.json"));
scoreLabel = new Label(String.format("%.0f",score),uiSkin);
generateUi();
generateFood();
}
碰撞校验码:
public void collisionCheck(){ // method that checks rather the snake head is touching outside the border, or inside it's own body
if(snakeTip.getX() >= gameStage.getWidth() || snakeTip.getY() >= gameStage.getHeight() || snakeTip.getX() <= 0 || snakeTip.getY() <= 0){
System.out.println("death activated");
activateDeath();
}
else{
for(int i = 0; i < snakeTail.size(); i++){
if(snakeTip.getX() == snakeTail.get(i).getX() && snakeTip.getY() == snakeTail.get(i).getY()){
System.out.println("death activated");
activateDeath();
}
}
}
}
最大的问题是游戏机制受屏幕尺寸的影响很大。我想要的是蛇在其中移动的虚拟区域(几乎就像它自己的坐标系),它与视口分开。至于视口,如果可能的话,我宁愿它仍然是一个屏幕视口。执行此操作的最佳方法是什么?
ScreenViewport is not good here because your game would be for example good looking on smaprtphone's screen when it would be a little polygon at the center of tablet's one. You should rather consider using FitViewport 这将在您的屏幕上添加一个栏,但可以使每个设备保持相同的竞技场大小。
要定义您的虚拟屏幕应具有的分辨率,只需将其传递到视口的构造函数中即可
private FitViewport viewport;
public GameScreen(AudioSnake audioSnake) {
gameCore = audioSnake;
viewport = new ScreenViewport(SCREEN_WIDTH_IN_PX, SCREEN_HEIGHT_IN_PX);
gameStage = new Stage(viewport);
那么你还需要重写 resize()
方法使你的视口可更新
@Override
public void resize(int width, int height) {
viewport.update(width, height);
}
同样在您的 render()
方法中,您需要在渲染舞台之前应用视口
viewport.apply();
stage.act(delta);
stage.draw();
完成所有这些之后,您可以只使用自定义 SCREEN_WIDTH_IN_PX
而不是 gameStage.getWidth()
为了练习我的 Java 技能,我一直在开发一个基本的贪吃蛇游戏。使用 java,我使用 LibGDX 和 Scene2d 来处理我的所有对象。
现在,贪吃蛇游戏的边界设置为视口尺寸。每当蛇到达视口外部时,都会检查碰撞。我正在使用合并到舞台中的屏幕视口,如下所示。
private AudioSnake gameCore;
private Stage gameStage;
private Image background;
private Image snakeTip;
private Image food;
private ArrayList<Image> snakeTail = new ArrayList <Image>(); // all the snake tail bits
private ScreenViewport viewport;
public GameScreen(AudioSnake audioSnake) {
gameCore = audioSnake;
viewport = new ScreenViewport();
gameStage = new Stage(viewport);
Gdx.input.setInputProcessor(gameStage);
uiSkin = new Skin(Gdx.files.internal("Ui/uiskin.json"));
scoreLabel = new Label(String.format("%.0f",score),uiSkin);
generateUi();
generateFood();
}
碰撞校验码:
public void collisionCheck(){ // method that checks rather the snake head is touching outside the border, or inside it's own body
if(snakeTip.getX() >= gameStage.getWidth() || snakeTip.getY() >= gameStage.getHeight() || snakeTip.getX() <= 0 || snakeTip.getY() <= 0){
System.out.println("death activated");
activateDeath();
}
else{
for(int i = 0; i < snakeTail.size(); i++){
if(snakeTip.getX() == snakeTail.get(i).getX() && snakeTip.getY() == snakeTail.get(i).getY()){
System.out.println("death activated");
activateDeath();
}
}
}
}
最大的问题是游戏机制受屏幕尺寸的影响很大。我想要的是蛇在其中移动的虚拟区域(几乎就像它自己的坐标系),它与视口分开。至于视口,如果可能的话,我宁愿它仍然是一个屏幕视口。执行此操作的最佳方法是什么?
ScreenViewport is not good here because your game would be for example good looking on smaprtphone's screen when it would be a little polygon at the center of tablet's one. You should rather consider using FitViewport 这将在您的屏幕上添加一个栏,但可以使每个设备保持相同的竞技场大小。
要定义您的虚拟屏幕应具有的分辨率,只需将其传递到视口的构造函数中即可
private FitViewport viewport;
public GameScreen(AudioSnake audioSnake) {
gameCore = audioSnake;
viewport = new ScreenViewport(SCREEN_WIDTH_IN_PX, SCREEN_HEIGHT_IN_PX);
gameStage = new Stage(viewport);
那么你还需要重写 resize()
方法使你的视口可更新
@Override
public void resize(int width, int height) {
viewport.update(width, height);
}
同样在您的 render()
方法中,您需要在渲染舞台之前应用视口
viewport.apply();
stage.act(delta);
stage.draw();
完成所有这些之后,您可以只使用自定义 SCREEN_WIDTH_IN_PX
gameStage.getWidth()