2012-03-04 24 views
1

编辑:我能够通过将爆炸存储到ArrayList中来解决问题,但我不确定这是否是好的做法。是否可以像这样离开它,让数组列表变得越来越大?在阵列列表超过200个左右之前,游戏将结束,但我只想练习最好的风格。应用程序运行时粒子爆炸长度(时间)减少

我目前正在制作一个非常非常简单的android游戏(有史以来的第一个项目),你有一堆圈子在屏幕上移动,当你点击它们时会“爆炸”。我实现这个的方式是,一旦它记录了你已经在圆的坐标内轻拍了一下,就会在你点击的位置产生粒子,并在随机方向上“爆炸”。

我遇到的问题是,应用程序运行时粒子的寿命会减少,尽管变量是一个常数。前几个按键是完美的,它们持续正确的时间。当你继续玩,爆炸变得越来越短,直到他们只是闪烁。我不确定这会导致什么。

任何帮助表示赞赏!

public class Explosion { 

private static final String TAG = Explosion.class.getSimpleName(); 

public static final int STATE_ALIVE = 0; //at least 1 particle is alive 
public static final int STATE_DEAD = 1; //all particles are dead 

private Particle[] particles;   //particles in the explosion 
private int x, y;      //the explosion's origin 
private int state;      //whether it's still active or not 

public Explosion(int particleNr, int x, int y) { 
    Log.d(TAG, "Explosion created at " + x + "," + y); 
    this.state = STATE_ALIVE; 
    this.particles = new Particle[particleNr]; 
    for (int i = 0; i < this.particles.length; i++) { 
     Particle p = new Particle(x, y); 
     this.particles[i] = p; 
    } 
} 

public Particle[] getParticles() { 
    return particles; 
} 

public void setParticles(Particle[] particles) { 
    this.particles = particles; 
} 

public int getX() { 
    return x; 
} 

public void setX(int x) { 
    this.x = x; 
} 

public int getY() { 
    return y; 
} 

public void setY(int y) { 
    this.y = y; 
} 

public void setState(int state) { 
    this.state = state; 
} 

public boolean isAlive() { 
    return this.state == STATE_ALIVE; 
} 

public boolean isDead() { 
    return this.state == STATE_DEAD; 
} 

public void update(Rect container) { 
    if (this.state != STATE_DEAD) { 
     boolean isDead = true; 
     for (int i = 0; i < this.particles.length; i++) { 
      if (this.particles[i].isAlive()) { 
       this.particles[i].update(container); 
       isDead = false; 
      } 
     } 
     if (isDead) 
      this.state = STATE_DEAD; 
    } 
} 

public void draw(Canvas canvas) { 
    for(int i = 0; i < this.particles.length; i++) { 
     if (this.particles[i].isAlive()) { 
      this.particles[i].draw(canvas); 
     } 
    } 
} 

}

^防爆类

public class Particle { 

public static final int STATE_ALIVE = 0; 
public static final int STATE_DEAD = 1; 

public static final int DEFAULT_LIFETIME = 500000; 
public static final int MAX_DIMENSION = 4; 
public static final int MAX_SPEED = 3; 

private int mState; 
private float mWidth; 
private float mHeight; 
private float mX,mY; 
private double mXVel, mYVel; 
private int mAge; 
private int mLifetime; 
private int mColor; 
private Paint mPaint; 

public Particle(int x, int y) { 
    mX = x; 
    mY = y; 
    mState = Particle.STATE_ALIVE; 
    mWidth = rndInt(1,MAX_DIMENSION); 
    mHeight = mWidth; 
    mLifetime = DEFAULT_LIFETIME; 
    mAge = 0; 
    mXVel = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED); 
    mYVel = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED); 

    //smoothing out the diagonal speed 
    if (mXVel * mXVel + mYVel * mYVel > MAX_SPEED * MAX_SPEED) { 
     mXVel *= .7; 
     mYVel *= .7; 
    } 
    mColor = Color.argb(255, 255, 255, 255); 
    mPaint = new Paint(mColor); 
} 

public int getState() { 
    return mState; 
} 

public void setState(int state) { 
    mState = state; 
} 

public float getWidth() { 
    return mWidth; 
} 

public void setWidth(float width) { 
    mWidth = width; 
} 

public float getHeight() { 
    return mHeight; 
} 

public void setHeight(float height) { 
    mHeight = height; 
} 

public float getX() { 
    return mX; 
} 

public void setX(float x) { 
    mX = x; 
} 

public float getY() { 
    return mY; 
} 

public void setY(float y) { 
    mY = y; 
} 

public double getXVel() { 
    return mXVel; 
} 

public void setXv(double xVel) { 
    mXVel = xVel; 
} 

public double getYVel() { 
    return mYVel; 
} 

public void setYv(double yVel) { 
    mYVel = yVel; 
} 

public int getAge() { 
    return mAge; 
} 

public void setAge(int age) { 
    mAge = age; 
} 

public int getLifetime() { 
    return mLifetime; 
} 

public void setLifetime(int lifetime) { 
    mLifetime = lifetime; 
} 

public int getColor() { 
    return mColor; 
} 

public void setColor(int color) { 
    mColor = color; 
} 

private int rndInt(int min, int max) { 
    return (int) (min + Math.random() * (max - min + 1)); 
} 

private double rndDbl(double min, double max) { 
    return min + (max - min) * Math.random(); 
} 

public boolean isAlive() { 
    return mState == STATE_ALIVE; 
} 

public boolean isDead() { 
    return mState == STATE_DEAD; 
} 

public void update(Rect container) { 
    // update with collision 
    if (this.isAlive()) { 
     if (mX <= container.left || mX >= container.right - mWidth) { 
      mXVel *= -1; 
     } 
     // Bottom is 480 and top is 0 !!! 
     if (mY <= container.top || mY >= container.bottom - mHeight) { 
      mYVel *= -1; 
     } 
    } 
    update(); 
} 

public void update() { 
    if (mState != STATE_DEAD) { 
     mX += mXVel; 
     mY += mYVel; 

     //extract alpha 
     int a = mColor >>> 24; 
     //fade by 2 
     a -= 2; 
     //if transparency is reached then particle dies 
     if (a <= 0) { 
      mState = STATE_DEAD; 
     } else { 
      //set new alpha 
      mColor = (mColor & 0x00ffffff) + (a << 24); 
      mPaint.setAlpha(a); 
      mAge++; 
     } 
     //particle reached end of its lifetime 
     if (mAge >= mLifetime) { 
      mState = STATE_DEAD; 
     } 
    } 
} 

public void draw(Canvas canvas) { 
    mPaint.setColor(mColor); 
    canvas.drawRect(mX, mY, mX + mWidth, mY + mHeight, mPaint); 
} 

}

下面是updatePhysics()方法在我的视图类

public void updatePhysics() { 
int pWidth = BitmapFactory.decodeResource(getResources(),R.drawable.bullet).getWidth(); 
    for (int i = 0; i < pummels.size(); i++) { 
     //checks collision with left side wall 
     //changes direction if it collides 
     pummels.get(i).update(); 
if (pummels.get(i).getSpeed().getxDirection() == Speed.DIRECTION_LEFT && pummels.get(i).getX() - pWidth/2 <= 0) { 
      totalHp--; 
      setHP("HP: " + String.valueOf(totalHp)); 
      pummels.remove(i); 
     } 
     if (pummels.size() == 0) { 
      for (int j = 0; j < 10; j++) { 
       pummels.add(j, new Pummel(BitmapFactory.decodeResource(getResources(), R.drawable.bullet), 850, (int) (Math.random() * 200) + 80)); 
      } 
     } 
     if (explosion != null && explosion.isAlive()) { 
      explosion.update(getHolder().getSurfaceFrame()); 
     } 
    } 
} 

下面是运行类和我试图维护in constant FPS

@Override 
    public void run() { 
     Log.d(TAG, "Starting game loop"); 

     long beginTime; 
     long timeDiff; 
     int sleepTime = 0; 
     int framesSkipped; 

     while(mRunning) { 
      Canvas c = null; 
      try { 
       c = mSurfaceHolder.lockCanvas(); 
       synchronized (mSurfaceHolder) { 
        beginTime = System.currentTimeMillis(); 
        framesSkipped = 0; 
        mGamePanel.updatePhysics(); 
        mGamePanel.render(c); 
        timeDiff = System.currentTimeMillis() - beginTime; 
        sleepTime = (int)(FRAME_PERIOD - timeDiff); 

        /if (sleepTime > 0) { 
         try { 
          Thread.sleep(sleepTime); 
         } catch (InterruptedException e) { 
         } 
        } 
        while (sleepTime <= 0 && framesSkipped < MAX_FRAME_SKIPS) { 
         mGamePanel.updatePhysics(); 
         sleepTime += FRAME_PERIOD; 
         framesSkipped++; 
        } 

        if (framesSkipped > 0) { 
         Log.d(TAG, "Skipped:" + framesSkipped); 
        } 
       } 
      } finally { 
       if (c != null) { 
        mSurfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
     } 
+0

请加上相关代码 – TheLastBert 2012-03-04 21:20:46

+0

我道歉,我以为我在那里。 – Kinru 2012-03-04 21:22:02

+1

你在管理帧率吗? – Maz 2012-03-04 22:09:26

回答

0

要开始诊断,我会做以下事情。基本上,我会验证第1点和第2点没有什么奇怪的事情发生,然后移动到第3点,如果这没有帮助,那么第4点可能会有用处。

  1. 注销剩余在几个关键点的时间。更新是必需的,并且在创建时也不是一个坏主意。
  2. 打印出a值。
  3. 这可能是因为游戏只是更新更少的东西,它必须处理。也许把帧放在某种计时器上会有助于确保时间不变(无论如何,这是一个好主意)。
  4. 您的粒子创建映射似乎有些奇怪。具体来说,你怎么知道一个粒子已经死了?它可能是一个粒子还活着,但你覆盖它,造成一些奇怪的行为。
+0

对于第4点。一旦“年龄”达到其“寿命”并且寿命是恒定的,则该粒子被宣布死亡。每次alpha降低时,年龄都会增加。 你也可以详细说明你的第二点吗?我不太明白你的意思。 – Kinru 2012-03-04 21:55:59

+0

@Kinru:#4有点远射。我只是想知道这个年龄是不是混淆了......实际上,经过进一步的思考,我怀疑它甚至超过了我在写它时所做的...尽管如此,我敢打赌,第3点是你真正的罪魁祸首。 – PearsonArtPhoto 2012-03-04 21:58:35

+0

对不起,我在之前的评论中写了错误的号码。我的意思是要求你详细说明你的第三点>。<在我的运行循环中,为了创建一致的FPS,我有一个计数器来计算跳过的帧并更新游戏,以免它出现波涛汹涌。如果在更新和绘制之后留下一段时间,那么它会睡觉。 难道问题是我每次都有一个新的覆盖每个爆炸?我没有把它们放入一个数组列表中,因为我找不到解决爆炸的好办法。 – Kinru 2012-03-04 22:04:02