粒子系统代码示例

在书上看到的粒子系统的示例分享给大家参考,希望可以帮助大家学习安卓!

首先是MyRenderer.java

package com.boring.ParticleActivity;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;

public class MyRenderer implements Renderer{
	private int[] textures = new int[1];
	// 随机数
	private Random random = new Random();
	// 定义最大的粒子数
	private static final int MAX_PARTICLES = 1000;
	// 减速粒子
	private float slowdown = 0.5f;
	// X方向的速度
	private float xspeed = 80;
	// Y方向的速度
	private float yspeed = 80;
	// 沿Z轴缩放
	private float zoom = -30.0f;
	// 循环变量
	private int loop;

	// 创建一个名为Particle的数组,存储MAX_PARTICLES个元素
	private Particle particles[] = new Particle[MAX_PARTICLES];

	// 存储12种不同颜色
	private float colors[][] = { { 1.0f, 0.75f, 0.5f }, { 1.0f, 0.75f, 0.5f },
	{ 1.0f, 1.0f, 0.5f }, { 0.75f, 1.0f, 0.5f }, { 0.5f, 1.0f, 0.5f },
	{ 0.5f, 1.0f, 0.75f }, { 0.5f, 1.0f, 1.0f }, { 0.5f, 0.75f, 1.0f },
	{ 0.5f, 0.5f, 1.0f }, { 0.75f, 0.5f, 1.0f }, { 1.0f, 0.5f, 1.0f },
	{ 1.0f, 0.5f, 0.75f } };

	// vertexBuffer
	private FloatBuffer vertexBuffer;
	// texCoordBuffer
	private FloatBuffer texCoordBuffer;
	// vertex
	private float[] vertex = new float[12];
	// texCoord
	private float[] texCoord = new float[8];

	// LoadBuffer
	public void LoadBuffer(GL10 gl) {
	ByteBuffer vertexByteBuffer = ByteBuffer
	.allocateDirect(vertex.length * 4);
	vertexByteBuffer.order(ByteOrder.nativeOrder());
	vertexBuffer = vertexByteBuffer.asFloatBuffer();
	vertexBuffer.put(vertex);
	vertexBuffer.position(0);

	ByteBuffer texCoordByteBuffer = ByteBuffer
	.allocateDirect(texCoord.length * 4);
	texCoordByteBuffer.order(ByteOrder.nativeOrder());
	texCoordBuffer = texCoordByteBuffer.asFloatBuffer();
	texCoordBuffer.put(texCoord);
	texCoordBuffer.position(0);
}

	public void onDrawFrame(GL10 gl) {
		// LoadBuffer
		LoadBuffer(gl);
		// 清除屏幕和颜色缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		// 重置模型变换矩阵
		gl.glLoadIdentity();

		// 开启顶点纹理状态
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordBuffer);

		// 循环所有的粒子
		for (loop = 0; loop < MAX_PARTICLES; loop++) {
		// 如果粒子为激活的
		if (particles[loop].active) {
		// 返回X轴的位置
		float x = particles[loop].x;
		// 返回Y轴的位置
		float y = particles[loop].y;
		// 返回Z轴的位置
		float z = particles[loop].z + zoom;
		// 设置粒子颜色
		gl.glColor4f(particles[loop].r, particles[loop].g,
		particles[loop].b, particles[loop].life);
		// 开始准备绘制"三角地带"
		texCoordBuffer.clear();
		vertexBuffer.clear();
		texCoordBuffer.put(1.0f);
		texCoordBuffer.put(1.0f);
		vertexBuffer.put(x + 0.5f);
		vertexBuffer.put(y + 0.5f);
		vertexBuffer.put(z);
		texCoordBuffer.put(1.0f);
		texCoordBuffer.put(0.0f);
		vertexBuffer.put(x + 0.5f);
		vertexBuffer.put(y);
		vertexBuffer.put(z);
		texCoordBuffer.put(0.0f);
		texCoordBuffer.put(1.0f);
		vertexBuffer.put(x);
		vertexBuffer.put(y + 0.5f);
		vertexBuffer.put(z);
		texCoordBuffer.put(0.0f);
		texCoordBuffer.put(0.0f);
		vertexBuffer.put(x);
		vertexBuffer.put(y);
		vertexBuffer.put(z);
		// 绘制
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		// 更新X坐标的位置
		particles[loop].x += particles[loop].xi / (slowdown * 1000);
		// 更新Y坐标的位置
		particles[loop].y += particles[loop].yi / (slowdown * 1000);
		// 更新Z坐标的位置
		particles[loop].z += particles[loop].zi / (slowdown * 1000);

		// 更新X轴方向速度大小
		particles[loop].xi += particles[loop].xg;
		// 更新Y轴方向速度大小
		particles[loop].yi += particles[loop].yg;
		// 更新Z轴方向速度大小
		particles[loop].zi += particles[loop].zg;

		// 减少粒子的生命值
		particles[loop].life -= particles[loop].fade;

		// 如果粒子生命小于0
		if (particles[loop].life < 0.0f) {
		float xi, yi, zi;
		xi = xspeed + (float) ((rand() % 60) - 32.0f);
		yi = yspeed + (float) ((rand() % 60) - 30.0f);
		zi = (float) ((rand() % 60) - 30.0f);
		initParticle(loop, random.nextInt(12), xi, yi, zi);
		}

		}
		}
		// 关闭顶点纹理状态
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glFinish();
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
		// ratio
		float ratio;
		if (height == 0) {
		height = 1;
		}
		ratio = (float) width / (float) height;
		gl.glViewport(0, 0, (int) width, (int) height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glFrustumf(-ratio, ratio, -1, 1, 1.0f, 200.0f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		// 重置模型矩阵
		gl.glLoadIdentity();
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
		// 黑色背景
		gl.glClearColor(0, 0, 0, 0);
		// 关闭深度测试
		gl.glDisable(GL10.GL_DEPTH_TEST);
		// 阴影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		// 启用混合
		gl.glEnable(GL10.GL_BLEND);
		// 精细修正
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

		// 启用纹理
		gl.glEnable(GL10.GL_TEXTURE_2D);
		// 创建纹理
		gl.glGenTextures(1, textures, 0);
		// 绑定纹理
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
		// 生成纹理
//		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, LoadImage.bitmap, 0);
		// 线性滤波
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
		GL10.GL_LINEAR);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
		GL10.GL_LINEAR);

		for (loop = 0; loop < MAX_PARTICLES; loop++) {
		float xi, yi, zi;
		xi = (float) ((rand() % 50) - 26.0f) * 10.0f;
		yi = zi = (float) ((rand() % 50) - 25.0f) * 10.0f;
		// 初始化粒子
		initParticle(loop, random.nextInt(12), xi, yi, zi);
		}
		}

		public int rand() {
		return Math.abs(random.nextInt(1000));
		}

		// initParticle初始化粒子
		public void initParticle(int num, int color, float xDir, float yDir,
		float zDir) {
		Particle par = new Particle();
		// 使所有粒子为激活状态
		par.active = true;
		// 所有粒子生命值为最大
		par.life = 1.0f;
		// 随机生成衰率(0~99)/1000+0.003f
		par.fade = rand() % 100 / 1000.0f + 0.003f;

		// 赋予粒子颜色分量r,g,b
		// r
		par.r = colors[color][0];
		// g
		par.g = colors[color][1];
		// b
		par.b = colors[color][2];

		// 设定粒子方向xi,yi,zi
		// xi
		par.xi = xDir;
		// yi
		par.yi = yDir;
		// zi
		par.zi = zDir;

		// x,y,z方向加速度
		// xg
		par.xg = 0.0f;
		// yg
		par.yg = -0.5f;
		// zg
		par.zg = 0.0f;

		particles[loop] = par;
		}
}

接下来是Particle.java

package com.boring.ParticleActivity;

public class Particle {

	boolean active; // 是否激活
	float life; // 粒子生命
	float fade; // 衰减速度

	float r; // 红色值
	float g; // 绿色值
	float b; // 蓝色值

	float x; // X位置
	float y; // Y位置
	float z; // Z位置

	float xi; // X方向
	float yi; // Y方向
	float zi; // Z方向

	float xg; // X 方向重力加速度
	float yg; // Y 方向重力加速度
	float zg; // Z 方向重力加速度
}

接下来是ParticleActivity.java

package com.boring.ParticleActivity;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class ParticleActivity extends Activity {
    /** Called when the activity is first created. */
	private GLSurfaceView glSurfaceView;
	private MyRenderer myRenderer;
	
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	LoadImage.load(getResources());
    	myRenderer = new MyRenderer();
    	glSurfaceView = new GLSurfaceView(this);
    	glSurfaceView.setRenderer(myRenderer);
    	setContentView(glSurfaceView);
    }
}

class LoadImage {
	public static Bitmap bitmap;

	public static void load(Resources res) {
	bitmap = BitmapFactory.decodeResource(res, R.drawable.mm);
	}
}

AndroidManifest.xml配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.boring.ParticleActivity"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".ParticleActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>
 

猜你喜欢

转载自boring.iteye.com/blog/1217631
今日推荐