7-Particle Explosion with Android

來源:互聯網
上載者:User

想知道爆炸式怎麼製作的嗎?讓我們抄個近道,試著來實現一個基本的例子爆炸

爆炸就是一堆粒子在螢幕上面分散開來,簡單起見,我們認為所有的例子都是來自於一個點

想想煙火,小小的火箭上升,然後爆炸為成百的小星星,最終落下時候消失。

為了簡單一點,我們會造一些粒子,我們會把他們放到一個位置,給他們隨機的力量,這個值是向量值,也就是說它既有方向,也有大小。大小決定速度,方向決定粒子的方向。

粒子

類檔案

public class Particle {public static final int STATE_ALIVE = 0;// particle is alivepublic static final int STATE_DEAD = 1;// particle is deadpublic static final int DEFAULT_LIFETIME = 200;// play with thispublic static final int MAX_DIMENSION= 5;// the maximum width or heightpublic static final int MAX_SPEED= 10;// maximum speed (per update)private int state;// particle is alive or deadprivate float width;// width of the particleprivate float height;// height of the particleprivate float x, y;// horizontal and vertical positionprivate double xv, yv;// vertical and horizontal velocityprivate int age;// current age of the particleprivate int lifetime;// particle dies when it reaches this valueprivate int color;// the color of the particleprivate Paint paint;// internal use to avoid instantiation}

粒子不過是個有些屬性小矩形,當然也可以是圖片,圓形,或者其他的形狀。

它有一個狀態,表示這個粒子或者還是死了,一個粒子是活著的 當它的顏色不是黑的,它的歲數還沒有到時候,一會在詳細看這個。

它有一個位置,是一個2D座標位置,在系統中用x和y表示

也有一個速度和方向,速度是一個向量,所以它有兩個元素在2D環境下。在3D時候還會有一個z的元素,現在我們還在2D的時候,為了簡單,還是先有兩個屬性吧

粒子年紀開始時候是0,每一次功能更新都會增加

lifetime是粒子掛了之前最大的年紀

其他的是顏色和畫筆,都是為了畫圖用的

回想以前的記錄,遊戲更新只不過是調用每個實體的更新函數,並顯示他們。粒子的更新方法相當簡單

首先我們來建立粒子

public Particle(int x, int y) {this.x = x;this.y = y;this.state = Particle.STATE_ALIVE;this.widht = rndInt(1, MAX_DIMENSION);this.height = this.widht;this.lifetime = DEFAULT_LIFETIME;this.age = 0;this.xv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);this.yv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);// smoothing out the diagonal speedif (xv * xv + yv * yv > MAX_SPEED * MAX_SPEED) {xv *= 0.7;yv *= 0.7;}this.color = Color.argb(255, rndInt(0, 255), rndInt(0, 255), rndInt(0, 255));this.paint = new Paint(this.color);}

檢查一下粒子的建立過程,是很直觀的。

粒子是在位置x,y建立的

狀態設定為活著的

我們需要把矩形的大小隨機化,因為爆炸建立粒子以不同的大小和形狀,我們只是把大小和顏色隨機了。

我寫了一些協助方法來產生隨機數,請參考完整的代碼

下一步是設定生命時間,每個粒子都會有相同的生命時間

出生的時候粒子的年紀是0

Next is the interesting bit. It’s very amateurish. To set the speed I have used 2 random numbers for the 2 components of the speed vector (vx andvy). The smoothing is needed because if both components are near the maximum value then the
resulting magnitude will be over the max speed. You could use simple trigonometric functions with a random degree instead of this.

下一步是有意思的,非常的業餘,為了設定速度,我用了兩個隨機數來表述速度向量的兩個元素 vx和vy。

最後是設定顏色,同樣是隨機的

There you have it.

粒子的update函數

public void update() {if (this.state != STATE_DEAD) {this.x += this.xv;this.y += this.yv;// extract alphaint a = this.color >>> 24;a -= 2; // fade by 2if (a <= 0) { // if reached transparency kill the particlethis.state = STATE_DEAD;} else {this.color = (this.color & 0x00ffffff) + (a << 24);// set the new alphathis.paint.setAlpha(a);this.age++; // increase the age of the particle}if (this.age >= this.lifetime) {// reached the end if its lifethis.state = STATE_DEAD;    }}}

相當的簡單,每次更新,位置根據速度來設定,粒子顏色的alpha值逐步減小,換句話說,粒子是逐漸層淡的

如果年紀超過了生命值或者不透明度為0,那就意味著粒子完全透明了,也就意味著生命的終結

If you wonder about the magic with colours, it is quite simple once you get the bitwise operators. Don’t worry, I’m rubbish as well, just make sure you know where to look. Here is a good explanation of colour components and how to use bitwise operators to
manipulate them:
http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math. It’s faster than using the objects but you can safely use the android methods too.

如果你想知道關於顏色的奧秘,如果你瞭解了位值運算 那麼就太簡單了,別擔心,我也不懂,這裡有個關於顏色的非常好的解釋,怎麼樣運用位元運算來控制他們,http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math.直接操作對象要快的多,當然你也可以安全的運用android的方法

 

關於顏色的邊注

在android裡面顏色是整型的,如果你瞭解rgb和argb,那就太好了,rgb是24位的,而argb是32位的,有一個alpha值,代表透明或者不透明

Opacity values: 0 = transparent, 255 = completely opaque.

不透明度,0 是透明的,255是完全透明的

為了表示16進位,可以加一個首碼0x,用16進位表示顏色是很簡單的,比如0x00FF00代表綠色,模式是0xRRGGBB(紅,綠,藍)。加上alpha值就是0xAARRGGBB

因為是16進位,值是在00和FF之間的,0就是0,FF是10進位的255

下面是如何提取顏色中的各種值

int color = 0xff336699;int alpha = color >>> 24;int red   = color >>> 16 & 0xFF;int green = color >>>  8 & 0xFF;int blue  = color & 0xFF;

畫的方法也很簡單

public void draw(Canvas canvas) {paint.setColor(this.color);canvas.drawRect(this.x, this.y, this.x + this.widht, this.y + this.height, paint);}

這一步就是在畫板上建立很多的粒子,觀察一下現象

The Explosion

爆炸就是數百計的例子從原點爆炸

Explosion

In the image above you see the first 4 updates of a simple explosion. All the particles have the same speed but they spread out in different directions. Each circle is one update.

The main properties of an explosion are:

public class Explosion {public static final int STATE_ALIVE = 0;// at least 1 particle is alivepublic static final int STATE_DEAD = 1;// all particles are deadprivate Particle[] particles;// particles in the explosionprivate int x, y;// the explosion's originprivate int size;// number of particlesprivate int state;// whether it's still active or not}

It contains an array of particles. The size is the number of particles. An explosion is alive if it has at least one particle alive.

The update is extremely simple. It iterates through all the particles and calls theupdate() method on each particle. The
draw() ditto.

In our application we will create explosions on the screen where we touch it.
The constructor is very simple:

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;} this.size = particleNr;}

The array of particles is being filled at the touch down position.

In our application we will allow up to 10 explosions. So in the MainGamePanel we declare an array of explosions.

private Explosion[] explosions;

In the surfaceCreated method we instantiate the array and fill it withnull.

explosions = new Explosion[10];for (int i = 0; i < explosions.length; i++) {explosions[i] = null;}

The onTouchEvent is where we create explosions.

public boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {// check if explosion is null or if it is still activeint currentExplosion = 0;Explosion explosion = explosions[currentExplosion];while (explosion != null && explosion.isAlive() && currentExplosion < explosions.length) {currentExplosion++;explosion = explosions[currentExplosion];}if (explosion == null || explosion.isDead()) {explosion = new Explosion(EXPLOSION_SIZE, (int)event.getX(), (int)event.getY());explosions[currentExplosion] = explosion;}}return true;}

What we do is iterate through the explosions and when we find the first
null
(this means we never used it for an instance) or the first dead explosion we create a new one at the touch position.

The update and render methods are straight forward. Iterate through the explosions and if they are not null and are alive then call their update and draw methods respectively.

In the final code I added a border for the screen as the wall and added a basic collision detection for the particles so they bounce off the walls. The wall is being transmitted as a reference and the update method checks for collision with it. Use it as
an exercise and remove the collision and try attaching an image to the particle instead of being a rectangle. To create explosions just click on the screen.

It should look like this:

Explosion Screenshot

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.