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()メソッドが毎秒呼び出されているため、新しいスプライトが毎秒レンダリングされています。

基本的に私がやろうとしているのは、新しい敵が生成されたときに、画面の外に出るまで下に移動する必要があるということですが、何が起こっているのかというと、敵は 1 秒間しか移動しません。

4

1 に答える 1

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メソッド (更新の場所が間違っています) では、すべての敵を移動するのではなく、作成された最新の敵のみを移動しようとしています。ループのすべての繰り返しが同じ instance:newEnemyに影響を与えていることに注意してください。これは、作成した最後の敵にすぎません。

これが私があなたのクラスを修正する方法です。

1) 移動速度は定数で、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メソッドで 2 番目の for ループを削除します。メソッドで位置の更新を処理しているためupdateです。

于 2015-05-07T00:04:45.610 に答える