2013-04-17 72 views
0

我正在使用AndEngine爲Android開發一款遊戲,並且我在不同車道的屏幕上有一組從左到右移動的汽車物體。當汽車超出攝像機寬度(屏幕尺寸)時,我將其位置設置爲0(屏幕左側) - spriteWidth()(僅在屏幕視口的左側)。我的問題是,由於隨機coordiantes返回,汽車保持負載。我嘗試了很多東西,但它一直在發生。我該如何停止在彼此之上加載數組的元素?

這是用來在遊戲開始時設置汽車座標的方法,也是在屏幕右側。

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

感謝。

+0

啊我以爲我做到了。全部完成:D –

+0

好吧,這還沒解決。那個評論是刪除了他的評論的人D: –

+0

好吧,我正確地理解了這一點:你在相機外面(隨機地在x = -car.width和-infinity之間)加載汽車,他們應該在隨機車道上(y),對嗎?他們什麼時候開始移動,並且是否繼續裝載新車,當他們已經移動時(以及移動車後面的位置回到屏幕的左側)?順便說一句:對不起,刪除評論:D – GameDroids

回答

2

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

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

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

如果你不想讓網格變成obvius,你可以將你的X循環提前1/2車長。然後,您只需檢查與上一次迭代中放置的汽車或汽車的碰撞情況,您只需要在Y軸上偏移即可防止碰撞。

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

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

的「testCarCollidesWithExisting」方法遍歷已經放在汽車的數組,如果新車重疊,假如果汽車不重疊返回true。

全例子==

這裏==更新是一個工作的例子。使用的圖形是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; 
    } 



} 
+0

您好整形外科醫生。我試着用你的方法,但無濟於事。我已經更新了我的原始帖子,顯示了我的代碼(具體來說,您的第一個方法,我嘗試了第二個,但也得到了類似的結果)。感謝您的回覆:) –

+0

我看到一個問題,我想。在放置它們之前,您正在創建您的汽車陣列。這是可以的,但你需要有兩個陣列:一個汽車陣列和一個放置汽車陣列。在您的collidesWithExisting()中,您只應檢查已放置的車輛 - 已知不會碰撞的車輛。)如果碰撞,則在while循環中設置新的x AND y位置。 –

+0

我給你一個完整的例子來展示如何去做。 –