簡體   English   中英

在libGDX游戲中實現視差效果

[英]Achieve parallax effect in libGDX game

我和一些朋友在一個游戲中工作,我們有一個大的水平世界和一個僅顯示1/3的OrthographicCamera 當攝像機的水平位置發生變化時,此攝像機會移動,因此攝像機僅向左和向右移動。

游戲中顯示的一些物體靠近玩家的觀點,但其他物體距離較遠(例如島嶼)。 考慮到這一點,我們不能為元素設置固定位置並僅移動相機。 考慮到元素的距離,我們需要實現視差效果。

這是一個簡單的圖像,可以更好地解釋它: 在此輸入圖像描述 左側的視口顯示了游戲的3個對象。 綠色的是靠近玩家,紅色橢圓是遠的,黃色的是在中間。 在右側的視口中,攝像機已向右移動,因此所有對象都消失在左側。 問題是綠色矩形的相對運動大於黃色的運動。 同樣,黃色物體的運動大於紅色物體的運動。

我創建了所有我的資產,考慮到它們的范圍,但現在,我如何使用libGDX模擬這個視角? 有沒有課可以做? 如果我必須在每次迭代中設置元素位置,我該如何計算正確的位置?

請注意,下面的示例未經過測試,因為我只是回憶起我是如何做到的。 這個想法很簡單 - 創建具有額外層的圖層,每個圖層具有初始位置和速度並移動它們。 如果一個圖層離開邊緣,則在另一邊添加另一個圖層(這就是我們創建一個額外圖層的原因)。

假設您有一個視差對象,它具有初始位置,大小和速度 -

public class Parallax extends DynamicGameObject {

    public float width, height; // Use setter/getter if you prefer

    public Parallax(float x, float y, float width, float height, float velocityX, float velocityY) {

        super(x, y, width, height);
        velocity.set(velocityX, velocityY);
        this.width = width;
        this.height = height;

    }

    public void update(float deltaTime) {
        position.add(velocity.x * deltaTime, velocity.y * deltaTime);
    }

    public void setPosition(float x, float y) {
        position.set(x, y);
    }
}

DynamicGameObject取自SuperJumper演示 -

public class DynamicGameObject extends GameObject {

    public final Vector2 velocity;
    public final Vector2 accel;

    public DynamicGameObject(float x, float y, float width, float height) {
        super(x, y, width, height);
        velocity = new Vector2();
        accel = new Vector2();
    }
}

游戲對象以及 -

public class GameObject {

    public final Vector2 position;
    public final Rectangle bounds;

    public GameObject(float x, float y, float width, float height) {
        this.position = new Vector2(x,y);
        this.bounds = new Rectangle(x - width/2f, y - height/2f, width, height);
    }
}

假設我們有兩層 - 一層在前面,另一層在后面。 我們每個都有一個紋理。 每個紋理都填滿整個屏幕。 我們為每個圖層創建兩個實例,以便當一個紋理開始離開屏幕時,另一個紋理顯示在邊緣以填補空白。 如果你有較小的紋理,你需要首先確定填充屏幕所需的紋理數量,然后創建一個額外的圖層以填補其間的間隙。

我們可以在世界創造期間創建一個視差層陣列 -

Array<Parallax> parallaxList = new Array<Parallax>(4);

我們可以創建像這樣的層 -

// Back
/* First parallax for back layer is at 0 x-axis. If you want to move the texture from right to left, the value of BACK_VELOCITY_X should be negative. You can experiment with velocity value for desire pace of movement. We do not want our layer to move on y-axis. Hence, it is set to 0. */

parallaxList.add(new Parallax(0, BACK_TEXTURE_HEIGHT, BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, BACK_VELOCITY_X, 0));

/* This one is also for back layer but it is positioned at the right edge of the layer above*/
parallaxList.add(new Parallax(BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, SOME_VELOCITY_X, 0));

// Front
parallaxList.add(new Parallax(0, 0, FRONT_TEXTURE_WIDTH, FRONT_TEXTURE_HEIGHT, FRONT_VELOCITY_X, 0));
parallaxList.add(new Parallax(FRONT_TEXTURE_WIDTH, 0, FRONT_TEXTURE_WIDTH, FRONT_TEXTURE_HEIGHT, FRONT_VELOCITY_X, 0));

我們在每個框架的更新呼叫中更新圖層 -

// In our example, TOTAL_LAYERS is 4
for (int i = 0; i < TOTAL_LAYERS; i++) {

    int tmpInt;
    Parallax parallax = parallaxList.get(i);

    parallax.update(deltaTime);

    // If one layer is off the edge, put it at the right of the next one
    // In this example, layers are moving from right to left
    if (parallax.position.x <= -parallax.width) {

        // We know that parallaxList's indexes 0 and 1 hold the back layers
        // and indexes 2 and 3 have the front layers. You can add additional
        // parameters in Parallax class to indicate a group so that you do not
        // have to determine the group in dirty way like this
        if(i == 0){
            tmpInt = 1;
        } else if(i == 1) {
            tmpInt = 0;
        } else if(i == 2) {
            tmpInt = 3;
        } else {
            tmpInt = 2;
        }

        parallax.setPosition(parallaxList.get(tmpInt).position.x + parallax.width, parallax.position.y);            
    }        
}

您可以使用OrthographicCamera和SpriteBatch繪制視差圖層。 你可以實際使用你擁有的游戲相機,但我認為使用單獨的相機更清潔。 無論如何,視差紋理通常足夠大,可以在單獨的調用中進行批處理,因此使用游戲相機很可能無法為您節省一個繪制調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM