触摸时删除精灵 [英] Removing sprite when Touched

查看:147
本文介绍了触摸时删除精灵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

精灵每秒产生一次,当它被触摸时,它应被移除。

The sprite is spawned every second and when it's touched, it should be removed.

这就是我所做的:

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

检测到触摸输入,但我不确定如何删除它们。

触摸它们时结果是错误。

The touch input is detected, but I'm not sure how to remove them.
The result is an error when I touch them.

推荐答案

您无法重复使用迭代器,因此您的 enemyIterator 无效且会导致例外。

You cannot reuse an iterator, so your enemyIterator is invalid and will cause exceptions.

为避免需要这样做,请更改 touchInput 方法以简单地测试对象是否应该被删除,而不是删除它。另请注意,您需要将屏幕坐标转换为世界坐标,因此您也必须使用相机。

To avoid needing to do this, change your touchInput method to simply test whether the object should be removed, not to remove it. Also note that you need to convert screen coordinates to world coordinates, so you must use the camera as well.

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

您只能在迭代的地方使用迭代器。因此,您必须在循环中获取本地引用,如下所示:

You can only use the iterator at the place where you're iterating. So you must acquire a local reference at the loop like this:

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






然而,上面的内容有点混乱,因为你将更新和绘图代码混合在一起,并在更新之前绘图,并在不需要的情况下反复检查触摸。我会重做它所有这些:


However, the above is kind of muddy because you're mixing update and drawing code up together, and drawing before updating, and checking for touches over and over without need. I would redo it all like this:

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

在这里你可以打电话给更新在拥有类之前绘制之前。

Here you would call update before draw from the owning class.

这篇关于触摸时删除精灵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆