簡體   English   中英

如何在彼此的頂部停止加載數組的元素?

[英]How can I stop elements of an array loading on top of eachother?

我正在使用AndEngine為Android開發游戲,我有一系列汽車對象在屏幕上從左到右移動到不同的車道。 當汽車超過攝像機寬度(屏幕尺寸)時,我將其位置設置為0(屏幕左側) - spriteWidth()(僅在屏幕視口的左側)。 我的問題是,由於隨機的坐標返回,汽車一直在相互疊加。 我嘗試了很多東西,但它一直在發生。

這是用於在游戲開始時設置汽車坐標的方法,也是從屏幕向右移動的方法。

public Vector2 randomRoadCoord()
{
    int Y;
    int X;

    int arrayLength = rManager.getInstance().roadPosition.length;
    int arrayFirstValue = 1;

    Random xR = new Random();
    int Low = (int) (5 *(0 - rManager.getInstance().car_region.getWidth()));
    int High = (int) (0 - rManager.getInstance().car_region.getWidth());
    X = xR.nextInt(High-Low) + Low;

    Random yR = new Random();

    int LowY = arrayFirstValue;
    int HighY = arrayLength;
    Y = yR.nextInt(HighY-LowY) + LowY;;

    if (firstLoad)
    {
        for(int i = 0; i < rManager.getInstance().carArray.length; i++)
        {
            for(int j = 0; j < rManager.getInstance().carArray.length; j++)
            {
                while(rManager.getInstance().carArray[i].getCarSprite().collidesWith(rManager.getInstance().carArray[j].getCarSprite()))
                    X-= 150;
            }
        }
    }

    lastX = X;
    lastY = Y;
    return new Vector2(X, Y);
}

如您所見,在某些區域之間返回隨機x和y值; 具體來說,相機的頂部和底部(靜態相機,基本上是視口),以及屏幕之間的-50和-450之間(類似的東西)。 我的問題是我需要他們停止加載彼此之上,因為如果發生碰撞,用戶將失去游戲。 我嘗試檢查每輛汽車精靈,看看它是否在加載時已經與另一輛汽車碰撞(雖然這會產生減速,如果確實如此,將X坐標進一步向左移動,但似乎沒有做任何事情。

/*if (firstLoad)
        {
        for(int i = 0; i < rManager.getInstance().carArray.length; i++)
        {
            while(rManager.getInstance().carArray[i].getCarX() + 100 > X && X > rManager.getInstance().carArray[i].getCarX() - 100)
                X-= 150;
        }       
        firstLoad = true;
    }   */

我也試過檢查汽車是否在x + 150和x - 150之間的其他車型,但這也沒有做任何事情。 並非所有的汽車都是彼此重疊的,但肯定超過1,這太多了。

謝謝。 請隨時提出任何問題。

---------------------------------更新:

我嘗試過使用整形外科醫生的建議,但同樣的問題仍然存在。 雖然有被裝載在另一個上面一個不太可能的機會一輛車,它仍然發生偶然。 我這次評論了代碼,所以應該更容易理解。

for (int i = 0; i < rManager.getInstance().carArray.length; i++)
            {
                if(rManager.getInstance().carArray[i].getCarSprite().getX() < (rManager.camera.getWidth() + rManager.getInstance().carArray[i].getCarSprite().getWidth()))
                {
                    // moves car from left to right
                    rManager.getInstance().carArray[i].getCarSprite().setPosition(rManager.getInstance().carArray[i].getCarSprite().getX() + (rManager.getInstance().carArray[i].getSpeed() * 4), rManager.getInstance().carArray[i].getCarSprite().getY()); 
                } 

                else //if out of the screen
                {       
                    //set the position to the left of the screen
                    rManager.getInstance().carArray[i].getCarSprite().setPosition(randomRoadCoord().x, rManager.getInstance().roadPosition[(int) randomRoadCoord().y].y);

                    //if colliding with another car
                    while(collidesWithExisting(rManager.getInstance().carArray[i]))
                    {   //set a new random pos
                        rManager.getInstance().carArray[i].getCarSprite().setPosition(randomRoadCoord().x, rManager.getInstance().roadPosition[(int) randomRoadCoord().y].y);
                    }
                }
            }

方法:

boolean collidesWithExisting(Car pCar)
{
    for(int j = 0; j < rManager.getInstance().carArray.length; j++)
    {
        if (rManager.getInstance().carArray[j] == pCar)
            return false;

        if(rManager.getInstance().carArray[j].getCarSprite().collidesWith(pCar.getCarSprite()))
            return true;
    }
    return false;
}

再次感謝。

您的循環至少存在一個問題:您檢查的條件。更改X值時,collidesWith()不會更改。 因此可能會發生額外的誤報。

第二個問題是,如果發生collidesWith()事件,則無法知道新的x是否也會在循環中較早的另一輛汽車上引起collidesWith()事件。 想象一下,在兩輛車之間放置第三輛車,這兩輛車太靠近,無法在它們之間容納汽車。 在單循環或雙循環中無法解決這個問題。

所以這是一個不同的策略:只使一個軸完全隨機。 逐步穿過X軸(汽車行駛方向)一次一個汽車長度。 隨機確定該位置是否應該有車。 如果是,則沿Y軸隨機定位該車。 沒有太多麻煩,你可以容納每一步放置一輛或多輛汽車。

如果您不希望網格為obvoius,則可以將X循環推進1/2車長。 然后,您只需要檢查前一次迭代中放置的汽車或汽車的碰撞,您只需要在Y軸上進行偏移以防止碰撞。

這也是第二種策略:將每輛車隨機放置在一個循環中。 在循環中測試以查看當前汽車是否與任何其他汽車碰撞。 隨機重新分配其x和y,直到它不會發生碰撞。 最后,您將擁有一系列不接觸的汽車。

   Car newCar = new Car();
   newCar.setPosition(randomXPostion, randomYPosition);
   while(testCarCollidesWithExisting(newCar)){
       newCar.setPosition(randomXPostion, randomYPosition);
   }

“testCarCollidesWithExisting”方法循環遍歷已經放置的汽車數組,如果新車重疊則返回true,如果汽車不重疊則返回false。

==使用完整示例更新==

這是一個有效的例子。 使用的圖形是來自andengine示例的“坦克”。 有一個警告:如果您放置的坦克數量超過了適合的數量,則腳本會掛起,因為它會在一個while循環中停留。 我認為20左右的大小和你大小的圖像和舞台大小一樣多。

package com.example.andenginetestbed;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.bitmap.BitmapTexture;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegionFactory;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.adt.io.in.IInputStreamOpener;
import org.andengine.util.debug.Debug;

import android.os.Bundle;
import android.view.Menu;

public class TestBed extends SimpleBaseGameActivity {

    // ===========================================================
    // Constants
    // ===========================================================

    private static final int CAMERA_WIDTH = 720;
    private static final int CAMERA_HEIGHT = 480;

    // ===========================================================
    // Fields
    // ===========================================================

    private ITexture mTexture;
    private ITextureRegion mFaceTextureRegion;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_test_bed);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.test_bed, menu);
        return true;
    }

    @Override
    public EngineOptions onCreateEngineOptions() {
        final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

        return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
    }

    @Override
    public void onCreateResources() {
        try {
            this.mTexture = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
                @Override
                public InputStream open() throws IOException {
                    return getAssets().open("tank.png");
                }
            });

            this.mTexture.load();
            this.mFaceTextureRegion = TextureRegionFactory.extractFromTexture(this.mTexture);
        } catch (IOException e) {
            Debug.e(e);
        }
    }
    ArrayList<Sprite> placedSprites = new ArrayList<Sprite>();
    @Override
    protected Scene onCreateScene() {
        this.mEngine.registerUpdateHandler(new FPSLogger());

        final Scene scene = new Scene();
        scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

        /* Calculate the coordinates for the face, so its centered on the camera. */
        final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
        final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;

        /* Create the face and add it to the scene. */
        for (int i = 0; i < 20; i++) {
            final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());
            scene.attachChild(face);
            face.setPosition((float)(Math.random()*CAMERA_WIDTH), (float)(Math.random()*CAMERA_HEIGHT));
            while(faceDoesNotOverlap(face)){
                face.setPosition((float)(Math.random()*CAMERA_WIDTH), (float)(Math.random()*CAMERA_HEIGHT));                
            }
            placedSprites.add(face);

        }

        return scene;
    }

    private boolean faceDoesNotOverlap(Sprite face) {
        for (int i = 0; i < placedSprites.size(); i++) {
            if(face.collidesWith(placedSprites.get(i))){
                return true;
            }
        }
        return false;
    }



}

暫無
暫無

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

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