[英]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.