java - libgdx 生成后的临时 Sprite 移动

标签 java libgdx spawning

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() 方法每秒都会被调用,这就是为什么每秒都会渲染一个新的 Sprite 。

基本上我想要做的是当一个新的敌人产生时,它必须向下移动直到它离开屏幕。但实际情况是敌人只会移动一秒钟。

最佳答案

我认为您通过引入成员变量 newEnemy 搞混了。你有一个方法可以创建一个新的敌人并将其添加到你的敌人列表中,之后,不应该有理由从列表中单独引用它,所以你应该只允许 newEnemy 引用被丢弃。

因此,您应该从您的类中删除 Sprite newEnemy 行,并在 newEnemy() 方法中声明它即可。

此外,不需要 Vector2 的位置列表,因为 Sprite 类已经存储了一个位置。您只需要移动单个 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,它只是您创建的最后一个敌人。

以下是我将如何修改您的类(class)。

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 方法中,删除第二个 for 循环,现在我们正在处理 update 方法中的位置更新。

关于java - libgdx 生成后的临时 Sprite 移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30082299/

相关文章:

java - Bukkit - 我怎样才能让生成器生成与 pig 不同的实体..?

java - 在spring mvc中按名称获取cookie值

android - 使用 OpenGL 着色器模拟调色板交换(在 LibGDX 中)

Javascript简单无尽游戏,setTimeout问题

java - Libgdx Sprite 深度在 Android 上与在桌面上不同

android - 如何纠正 libgdx 中平铺 map 渲染的纵横比?

python - 我的生成系统不起作用,我不知道为什么

java - mac-osx 10.9.4 Hadoop 2.7.1线程 “main” java.lang.UnsupportedClassVersionError中的异常:不支持的major.minor版本51.0

java - 404 Nicht gefunden : Invalid Request jax ws web service

java - java 中 tiff 图像的平铺?或 libTiff 的 java 包装器?