应用程序运行时粒子爆炸长度(时间)减少

时间:2012-03-04 21:12:06

标签: android

编辑:我能够通过将爆炸存储到ArrayList来解决问题,但是我不确定这是不错的做法。这样就可以了,只是让arraylist变得越来越大?游戏将在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());
        }
    }
}

以下是运行类和我保持不变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);
                }
            }
        }

1 个答案:

答案 0 :(得分:0)

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

  1. 退出几个关键点的剩余时间。更新是必需的,在创建时也不是一个坏主意。
  2. 在您使用时打印a值。
  3. 可能游戏只是简单地更新它需要处理的事情。也许将帧放在某种计时器上将有助于确保时间是恒定的(反正是一个好主意)。
  4. 您的粒子创建映射似乎有些奇怪。具体来说,你怎么知道粒子死了?它可能是一个粒子还活着,但你正在覆盖它,造成一些奇怪的行为。