android粒子系统

在android游戏开发中,要想做出精美的游戏,2个类是必不可少的,一个是精灵类,一个是粒子类,粒子系统可以做出各种精美的效果,比如水流、火焰、烟雾等。

下面是一个粒子系统的实现:

MyRenderer.java

package com.lyc;
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 = 700;
    // 减速粒子
    private float slowdown = 0.5f;
    // X方向的速度
    private float xspeed = 10;
    // Y方向的速度
    private float yspeed = 10;
    // 沿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 * 5);
        vertexByteBuffer.order(ByteOrder.nativeOrder());
        vertexBuffer = vertexByteBuffer.asFloatBuffer();
        vertexBuffer.put(vertex);
        vertexBuffer.position(0);

        ByteBuffer texCoordByteBuffer = ByteBuffer
                .allocateDirect(texCoord.length * 5);
        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();
    }

    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();
    }

 
    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.lyc;

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.lyc;
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 {
    private GLSurfaceView glSurfaceView;
    private MyRenderer myRenderer;

    @Override
    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.mov004);
        bitmap = BitmapFactory.decodeResource(res, R.drawable.icon);
    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值