2015-06-09 2 views
0

Спрайт разворачивается каждую секунду, и когда он коснулся, его следует удалить.Удаление спрайта при касании

Это то, что я сделал:

//Render the sprites and making them move: 
public void draw(SpriteBatch batch) { 
    for(Sprite drawEnemy:enemies) { 
     drawEnemy.draw(batch); 
     drawEnemy.translateY(deltaTime * movement); 
     touchInput(drawEnemy.getX(),drawEnemy.getY(), 
      drawEnemy.getWidth(),drawEnemy.getHeight(),drawEnemy); 
    } 
} 

//Detecting the touch input: 
public void touchInput(float x,float y,float w,float h,Sprite sprite){ 
    float touchX=Gdx.input.getX(); 
    float touchY=Gdx.input.getY(); 

    if(Gdx.input.justTouched()){ 
     if(touchX > x && touchX < x+w){ 
      enemyIterator.remove(); 
      Pools.free(sprite); 
     } 
    } 
} 

Сенсорный ввод обнаружен, но я не знаю, как удалить их.
В результате возникает ошибка, когда я прикасаюсь к ним.

+0

Какая ошибка? ConcurrentModification? Если у вас есть ошибка, будет полезно включить stacktrace. – Gosu

+1

Где вы объявляете 'enemyIterator'? Это не работает, потому что любые ссылки 'enemyIterator', это не тот итератор, который используется в вашем методе' draw', потому что вы никогда не получали ссылку на него. Кроме того, вам необходимо преобразовать координаты касания в мировые координаты с помощью камеры (unproject), прежде чем вы сможете проверить, было ли это затронуто. – Tenfour04

+0

Да, ошибка одновременной модификации. Итератор доступен всеми методами. Функция обнаружения касания работает, потому что я сначала задал ее, чтобы распечатать что-либо всякий раз, когда спрайт был затронут и он работает все время. –

ответ

0

Вы не можете повторно использовать итератор, поэтому ваш enemyIterator недействителен и приведет к исключениям.

Чтобы избежать необходимости этого, измените свой метод touchInput, чтобы просто проверить, следует ли удалять объект, а не удалять его. Также обратите внимание, что вам нужно преобразовать координаты экрана в мировые координаты, поэтому вы также должны использовать камеру.

private Vector3 TMPVEC = new Vector3(); 

public boolean touched(float x,float y,float w,float h) { 
    TMPVEC.set(Gdx.input.getX(), Gdx.input.getY(), 0); 
    camera.unproject(TMPVEC); 
    return Gdx.input.justTouched() && TMPVEC.x > x && TMPVEC.x < x+w; 
} 

Вы можете использовать итератор только в том месте, где вы итерации. Таким образом, вы должны получить локальную ссылку на петле, как это:

public void draw(SpriteBatch batch) { 
    for (Iterator<Sprite> iterator = enemies.iterator(); iterator.hasNext();) { 
     Sprite drawEnemy = iterator.next(); 
     drawEnemy.draw(batch); 
     drawEnemy.translateY(deltaTime * movement); 
     if (touched((drawEnemy.getX(),drawEnemy.getY(), drawEnemy.getWidth(),drawEnemy.getHeight())){ 
      iterator.remove(); 
      Pools.free(sprite); 
     } 
    } 
} 

Однако выше вид мутная, потому что вы смешиваете обновление и составление кода вместе, и рисунок перед обновлением, и проверка для прикосновений снова и снова без необходимости. Я бы переделать все это так:

private Vector3 TMPVEC = new Vector3(); 

public void update (Camera camera, float deltaTime) { 
    boolean checkTouch = Gdx.input.justTouched(); 
    if (checkTouch) { 
     TMPVEC.set(Gdx.input.getX(), Gdx.input.getY(), 0); 
     camera.unproject(TMPVEC); 
    } //This way we only unproject the point once for all sprites 

    for (Iterator<Sprite> iterator = enemies.iterator(); iterator.hasNext();) { 
     Sprite enemy = iterator.next(); 
     enemy.translateY(deltaTime * movement); 

     if (checkTouch && touched(enemy, TMPVEC)){ 
      iterator.remove(); 
      Pools.free(sprite); 
     } 
    } 
} 

private void touched (Sprite sprite, Vector3 touchPoint){ 
    return sprite.getX() <= touchPoint.x && 
     sprite.getX() + sprite.getWidth() <= touchPoint.x; 
} 

public void draw (SpriteBatch batch){ 
    for (Sprite sprite : enemies) sprite.draw(batch); 
} 

Здесь вы назовете update перед тем draw из имущего класса.

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