2012-03-04 23 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