2015-05-06 97 views
2
public class Player { 
    private Sprite enemy; 

    public Rectangle bounds; 
    private SpriteBatch batch; 
    private float deltaTime; 
    private float timer; 

    private ArrayList<Sprite> enemies; 
    private Iterator<Sprite> enemyIterator; 
    private ArrayList<Vector2> posCoordinate; 
    Sprite newEnemy; 

    public void create(){ 
     batch=new SpriteBatch(); 
     timer=0; 

     enemy=new Sprite(new Texture(Gdx.files.internal("spr_player.png"))); 
     bounds=new Rectangle(200,700,82,80); 

     enemies=new ArrayList<Sprite>(); 
     posCoordinate=new ArrayList<Vector2>(); 
     newEnemy=Pools.obtain(Sprite.class); 

    } 

    public void update(){ 
     deltaTime=Gdx.graphics.getDeltaTime(); 
     enemyIterator=enemies.iterator(); 
     timer+=1*deltaTime; 

     if(timer>=1f){ 
      newEnemy(); //method called every second 
      timer-=1; 
     } 

    } 

    public void newEnemy(){ 

     Vector2 position=Pools.obtain(Vector2.class); //vector2 is created for each enemy every second. 
     position.set(200,700); 
     posCoordinate.add(position); 

     newEnemy=Pools.obtain(Sprite.class); //enemy created every second 
     newEnemy.set(enemy); 

     enemies.add(newEnemy); 
    } 

    public void draw(SpriteBatch batch){ 

     //this is where the enemy position is set and movement 
     for(Sprite enemy:enemies){ 
      enemy.draw(batch); 
     }for(Vector2 position:posCoordinate){ 
      newEnemy.setPosition(position.x,position.y); 
      position.y-=2; 

     } 
      } 

     } 

newEnemy()方法後,臨時精靈運動被稱爲每一秒,這就是爲什麼新的精靈所呈現的每一秒。libgdx正在催生

基本上我想要做的是,當一個新的敵人產生時,它必須向下移動,直到它離開屏幕。但是發生的事情是敵人只會移動一秒鐘。

回答

1

我想你已經通過引入成員變量newEnemy混淆了事情。你有一種方法可以創建一個新的敵人並將其添加到敵人列表中,之後,應該沒有理由單獨引用它,因此您應該允許丟棄參考文件newEnemy

因此,您應該從您的課程中刪除Sprite newEnemy行,並在newEnemy()方法中聲明它。

另外,由於Sprite類已經存儲了一個位置,因此不需要Vector2的位置列表。你只需要移動個別精靈。因此,請刪除與posCoordinate相關的所有內容。你newEnemy()方法應該只是看起來像這樣:

private void newEnemy(){ 
    Sprite newEnemy = Pools.obtain(Sprite.class); 
    newEnemy.set(enemy); //I recommend renaming your `enemy` variable to something like `prototypeEnemy` for clarity 
    newEnemy.setPosition(200, 700); //need to start it at correct location. 
    enemies.add(newEnemy); 
} 

最後,在draw方法(這是更新錯誤的地方),你想只移動創建的最新的敵人,而不是移動所有的人。請注意,循環的每次迭代都會影響同一個實例:newEnemy,這只是您創建的最後一個敵人。

下面是我將如何修改你的課程。

1)的移動速度應該是一個常數,以每秒世界單位測量,因此聲明像這樣在你的類的頂部:

private static final float ENEMY_SPEED = -120f; 

2)在你update()方法的底部,你可以添加這會導致你的敵人的移動:

for (Sprite sprite : enemies){ 
    sprite.translateY(deltaTime * ENEMY_SPEED); 
} 

3)在這一點,你可以添加,當他們關閉屏幕的檢查,這樣你就可以刪除它們。必須使用迭代器實例來避免ConcurrentModificationException。

Iterator<Sprite> enemyIterator = enemies.iterator(); 
while (enemyIterator.hasNext()){ 
    Sprite sprite = enemyIterator.next(); 
    if (sprite.getY() + sprite.getHeight() < screenBottom) //screenBottom is something you can calculate from your camera like camera.getPosition().y - camera.getHeight()/2 
     removeEnemy(sprite); 
} 

4),並刪除它們,因爲你使用的池,你應該把它們放回池中,當你與他們

private void removeEnemy(Sprite sprite){ 
    enemies.remove(sprite); 
    Pools.free(sprite); 
} 

5)完成在你draw方法,去除第二個循環,現在我們正在處理update方法中的位置更新。

+0

我是新手,當我移除Sprite並將它們放回池中時,如何再次使用池中的Sprite?這是幹什麼的// Sprite newEnemy = Pools.obtain(Sprite.class); –

+0

Pools.obtain(Sprite.class);將一個精靈拉出游泳池供您使用。如果該池爲空,它會自動實例化一個新的Sprite併爲您提供。你不知道你得到的精靈是新的還是回收的,所以一定要立刻設置它的紋理區域和位置。 – Tenfour04

+0

所以你不需要編寫額外的代碼,它會自動回收精靈?感謝您的回答,您的幫助非常大。 –