简体   繁体   English

场景2D与视口坐标和游戏坐标的分离

[英]Scene 2D Separation from viewport coordinates and game coordinates

To practice my Java skills, I have been developing a basic Snake Game. 为了练习Java技能,我一直在开发基本的Snake游戏。 With java, I am using LibGDX and Scene2d to handle all my objects. 使用Java,我正在使用LibGDX和Scene2d处理所有对象。

Right now, the boundaries of the snake game are set to the viewport dimensions. 现在,将蛇游戏的边界设置为视口尺寸。 Collisions are checked whenever the snake reaches the outside of the viewport. 每当蛇到达视口外部时,都会检查碰撞。 I am using a screen viewport which is incorporated into the Stage as seen below. 我正在使用一个合并到舞台中的屏幕视口,如下所示。

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();
}

Collision check code: 碰撞检查代码:

    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();
            }
        }
    }
}

The big problem with this is that the game mechanics are greatly affected by the size of the screen. 最大的问题是游戏机制受屏幕尺寸的影响很大。 What I WANT to have is a virtual area that the snake moves around in (almost like it's own coordinate system) that is separate from the viewport. 我想拥有的是蛇在其中移动的虚拟区域(几乎像它自己的坐标系一样),与视口分开。 As for the viewport, I'd rather it remain a screen viewport if possible. 至于视口,我希望它尽可能保持屏幕视口。 What would be the best way to do this? 最好的方法是什么?

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. ScreenViewport在这里不是很好,因为例如,您的游戏在smaprtphone的屏幕上会很好看,而在平板电脑屏幕的中心会是一个小多边形。 You should rather consider using FitViewport which will add a bars to your screen but will make it possible to keep the same arena size for every device. 您应该考虑使用FitViewport ,它会在屏幕上添加一个条形,但可以使每个设备保持相同的舞台大小。

To define what resolution your virtual screen should have just pass it in the viewport's constructor 要定义您的虚拟屏幕应该在视口的构造函数中通过的分辨率

    private FitViewport viewport;

    public GameScreen(AudioSnake audioSnake) {
        gameCore = audioSnake;
        viewport = new ScreenViewport(SCREEN_WIDTH_IN_PX, SCREEN_HEIGHT_IN_PX);
        gameStage = new Stage(viewport);

then you also need to overwrite the resize() method to make your viewport updatable 那么您还需要覆盖resize()方法以使视口可更新

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
    }

Also in your render() method you need to apply viewport right before rendering the stage 同样在render()方法中,您需要在渲染舞台之前立即应用视口

    viewport.apply();
    stage.act(delta);
    stage.draw();

After all of this instead of gameStage.getWidth() you can use just your custom SCREEN_WIDTH_IN_PX 完成所有这些操作之后,您可以仅使用自定义的SCREEN_WIDTH_IN_PX而不是gameStage.getWidth()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM