简体   繁体   English

libgdx如何每秒绘制或生成一个新的精灵/对象?

[英]libgdx How do you draw or spawn a new sprite/object every second?

I'm trying to spawn a sprite or object every second, but what happens is that the sprite is only rendered for less than a second every second 我试图每秒生成一个Sprite或对象,但是发生的是该Sprite每秒仅渲染不到一秒钟

public class Player {
private Sprite playerSpr,enemy,enemy1;
public Vector2 position,size;
public Rectangle bounds;
private SpriteBatch batch;
private float deltaTime;
private float timer,elapsedTime;

private ArrayList<Sprite> enemies;
private Iterator<Sprite> enemyIterator;

public void create(){
    position=new Vector2(200,910);
    size=new Vector2(82,80);
    batch=new SpriteBatch();
    timer=0;

    playerSpr=new Sprite(new Texture(Gdx.files.internal("spr_player.png"))); 
    enemy=new Sprite(new Texture(Gdx.files.internal("spr_player.png"))); 
    enemy1=new Sprite(new Texture(Gdx.files.internal("spr_player.png"))); 
    bounds=new Rectangle(position.x,position.y,size.x,size.y);

    enemies=new ArrayList<Sprite>();
    enemies.add(playerSpr);
    enemies.add(enemy);

}

public void update(){
    deltaTime=Gdx.graphics.getDeltaTime();
    enemyIterator=enemies.iterator();

    timer+=1*deltaTime;
    elapsedTime+=1*deltaTime;   

    playerSpr.setPosition(position.x,position.y);
    playerSpr.setSize(size.x,size.y);

    bounds.set(position.x,position.y,size.x,size.y);
}

public void movement(){
    if(position.y<=910){
        position.y-=600*deltaTime;

        }

    }

/* wan't to draw the next sprite every second, for now I only have to stored in the iterator */
public void draw(){
    if(timer>=1){
        Sprite cur=enemyIterator.next();
        batch.begin();
        cur.draw(batch);
        batch.end();timer=0;
    }  

only the playerspr is being rendered for less that as second every second,I know be cause the timer is being reset every second but how do you spawn or draw the next one? 我只知道每秒仅重置一次playerspr,而每秒渲染的时间少于第二秒,但是您如何生成或绘制下一个定时器呢?

You are conflating your game logic with your drawing. 您正在将游戏逻辑与绘图混淆。 All you should be doing in your draw method is drawing all your stuff, so you should just go through your list of enemies and draw each one: draw方法中您应该做的就是绘制所有东西,因此您应该遍历敌人列表并绘制每个敌人:

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

Note that this class should not own or even reference a sprite batch, and should not call begin or end . 注意,此类不应该拥有甚至引用一个sprite批处理,并且不应调用beginend The Game or Screen class that owns this class should call begin and end so they are only called once for the whole game. 拥有此类的Game或Screen类应调用begin和end,因此在整个游戏中它们仅被调用一次。

And you want to spawn an enemy each second, which is something that should be done in your update method. 您想每秒产生一个敌人,这应该在您的update方法中完成。 Right after you increment your timer (the timer+=1*deltaTime; line), you can spawn an enemy by creating one and adding it to your list: 在增加计时器( timer+=1*deltaTime;行)之后,可以通过创建一个敌人并将其添加到列表中来生成敌人:

while (timer >= 1f) {
    createNewEnemy();
    timer -= 1f;  //don't simply reset to 0, or you will be rounding off every time a new one is spawned, so the rate won't be consistent over time.
}

(The reason for using while instead of if is because theoretically, you might want to spawn enemies more often than your max frame time. This prevents your game logic from falling behind if there is a slow frame somewhere.) (之所以使用while不是if的原因是,从理论上讲,您可能希望生成敌人的时间超过您的最大帧时间。这可以防止游戏逻辑在某处帧缓慢的情况下落后。)

The createNewEnemy method should get a sprite, set it up, and add it to the enemies list. createNewEnemy方法应获取一个精灵,对其进行设置,然后将其添加到敌人列表中。 It could simply instantiate a new sprite new Sprite(enemy); 它可以简单地实例化一个新的sprite new Sprite(enemy); , which creates a new Sprite and seeds it with the existing enemy prototype sprite you have. ,这会创建一个新的Sprite并将其与您现有的enemy原型Sprite一起播种。 But if you use pooling, you can avoid triggering the GC, which will cause stuttering in your game: 但是,如果使用池化,则可以避免触发GC,这会导致游戏结结:

private void newEnemy(){
    Sprite newEnemy = Pools.obtain(Sprite.class);
    newEnemy.set(enemy); //reference same Texture from your prototype enemy sprite
    //set up enemy position and other parameters here
    enemies.add(newEnemy);
}

If you use pooling, then later when you want to remove an enemy, you should do it like this: 如果使用池化,则稍后要移除敌人时,应按以下步骤进行:

private void removeEnemy(Enemy removedEnemy){
    Pools.free(removedEnemy);
    enemies.remove(removedEnemy);
}

Hopefully this gets you on the right track, although your game structure seems a bit confused (like why is this class called Player if it contains both the player and all the enemies?). 希望这能使您走上正确的路,尽管您的游戏结构似乎有些混乱(例如,如果该类包含玩家和所有敌人,为什么将其称为Player?)。

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

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