简体   繁体   English

触摸时删除精灵

[英]Removing sprite when Touched

The sprite is spawned every second and when it's touched, it should be removed. 精灵会每秒生成一次,当触摸它时,应该将其删除。

This is what I did: 这是我所做的:

//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. 当我触摸它们时,结果是错误。

You cannot reuse an iterator, so your enemyIterator is invalid and will cause exceptions. 您无法重用迭代器,因此您的enemyIterator迭代器无效,并且会导致异常。

To avoid needing to do this, change your touchInput method to simply test whether the object should be removed, not to remove it. 为了避免这样做,请更改touchInput方法以仅测试是否应删除对象,而不是删除对象。 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. 在这里,您将在从拥有的类进行draw之前调用update

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM