2015-05-06 4 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().

Кроме того, вам не нужен ваш список Vector2 для позиций, потому что класс Sprite уже сохраняет позицию. Вам просто нужно переместить отдельные спрайты. Поэтому удалите все, что связано с 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 newEnemy = Pools.obtain (Sprite.class); –

+0

Pools.obtain (Sprite.class); вытаскивает спрайт из бассейна для вас. Если пул пуст, он автоматически создает новый Sprite и дает вам это. Вы не знаете, является ли спрайт, который вы получаете, новым или переработанным, поэтому обязательно обязательно установите его область и положение текстуры. – Tenfour04

+0

Так что вам не нужно писать дополнительный код, он автоматически перерабатывает спрайты?Спасибо за ваши ответы, очень полезно. –

Смежные вопросы