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

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

问题描述

精灵每秒生成一次,当它被触摸时,它应该被移除.

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

在这里,您将在 draw 之前从所属类调用 update.

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

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

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