热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android游戏开发学习②焰火绽放效果实现方法

本文实例讲述了Android游戏开发学习②焰火绽放效果实现方法。分享给大家供大家参考。具体如下: 本节介绍在游戏开发中常用到的数学物理应用

本文实例讲述了Android游戏开发学习②焰火绽放效果实现方法。分享给大家供大家参考。具体如下:

本节介绍在游戏开发中常用到的数学物理应用——粒子系统。粒子系统与上一节的小球有类似的地方,都是通过数学方法和物理公式模拟客观世界中的物体的运动轨迹。不同的是小球更强调个体运动,而焰火粒子等粒子系统更注重整体感觉。

一、焰火粒子效果

1.粒子对象类Particle类和粒子集合类ParticleSet类

每个粒子都为一个Particle类的对象,程序中产生的所有Particle对象都由一个ParticleSet对象来管理。

Particle类:

package com.particle; 
public class Particle { 
  int color; // 粒子颜色 
  int r; // 粒子半径 
  double vertical_v; // 垂直速度 
  double horizontal_v; // 水平速度 
  int startX; // 初始X坐标 
  int startY; // 初始Y坐标 
  int x; // 实时X坐标 
  int y; // 实时Y坐标 
  double startTime; // 起始时间 
  public Particle(int color, int r, double vertical_v, double horizontal_v, int x, int y, double startTime) { 
    super(); 
    this.color = color; 
    this.r = r; 
    this.vertical_v = vertical_v; 
    this.horizontal_v = horizontal_v; 
    this.startX = x; 
    this.startY = y; 
    this.x = x; 
    this.y = y; 
    this.startTime = startTime; 
  } 
}

ParticleSet类:

package com.particle; 
import java.util.ArrayList; 
import android.graphics.Color; 
public class ParticleSet { 
  ArrayList particleSet; 
  public ParticleSet() { 
    particleSet = new ArrayList(); 
  } 
  /** 
   * 向粒子集合中添加指定数量的粒子对象 
   */ 
  public void add(int count, double startTime) { 
    for (int i = 0; i 

产生的粒子竖直初速度为-30至-20,方向向上;水平初速度为-10至10,方向向左或向右。

2.物理引擎ParticleThread类

package com.particle; 
import java.util.ArrayList; 
public class ParticleThread extends Thread { 
  boolean flag; 
  ParticleView father; 
  int sleepSpan = 80; 
  double time = 0; // 物理引擎的时间轴 
  double span = 0.15; // 每次计算粒子位移时采用的时间间隔 
  public ParticleThread(ParticleView father) { 
    this.father = father; 
    this.flag = true; 
  } 
  @Override 
  public void run() { 
    while (flag) { 
      father.ps.add(5, time); // 每次添加5个粒子 
      ArrayList tempSet = father.ps.particleSet; // 获取粒子集合 
      for (int i = tempSet.size() - 1; i >= 0; i--) { 
        Particle particle = tempSet.get(i); 
        double timeSpan = time - particle.startTime; // 计算从程序开始到现在经过的时间 
        int tempX = (int) (particle.startX + particle.horizontal_v * timeSpan); 
        int tempY = (int) (particle.startY + 4.9 * timeSpan * timeSpan + particle.vertical_v * timeSpan); 
        if (tempY > ParticleView.DIE_OUT_LINE) { // 如果粒子超过屏幕下边沿 
          tempSet.remove(particle); 
        } 
        particle.x = tempX; 
        particle.y = tempY; 
      } 
      time += span; 
      try { 
        Thread.sleep(sleepSpan); 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
}

本例中的物理引擎没有采用获取系统时间的方式,而是自己定义了一个时间轴(成员变量time)。这样可以自己确定时间轴行进的快慢程度(通过改变成员变量span的值),而不必依赖于系统的时间。

3.视图类ParticleView类

package com.particle; 
import java.util.ArrayList; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.RectF; 
import android.view.SurfaceHolder; 
import android.view.SurfaceHolder.Callback; 
import android.view.SurfaceView; 
public class ParticleView extends SurfaceView implements Callback { 
  public static final int DIE_OUT_LINE = 300; 
  DrawThread dt; 
  ParticleSet ps; 
  ParticleThread pt; 
  String fps = "FPS:N/A"; 
  public ParticleView(Context context) { 
    super(context); 
    this.getHolder().addCallback(this); 
    dt = new DrawThread(this, getHolder()); 
    ps = new ParticleSet(); 
    pt = new ParticleThread(this); 
  } 
  public void doDraw(Canvas canvas) { 
    canvas.drawColor(Color.BLACK); // 清屏 
    ArrayList particleSet = ps.particleSet; 
    Paint paint = new Paint(); 
    for (int i = 0; i 

4.绘图类DrawThread及Activity类

基本与上节相同

DrawThread类:

package com.particle; 
import android.graphics.Canvas; 
import android.view.SurfaceHolder; 
public class DrawThread extends Thread { 
  ParticleView pv; 
  SurfaceHolder surfaceHolder; 
  boolean flag=false; 
  int sleepSpan=30; 
  long start =System.nanoTime(); //记录起始时间,该变量用于计算帧速率
  int count=0 ; //记录帧数 
  public DrawThread(ParticleView pv,SurfaceHolder surfaceHolder) { 
    this.pv=pv; 
    this.surfaceHolder=surfaceHolder; 
    this.flag=true; 
  } 
  public void run() { 
    Canvas canvas=null; 
    while(flag) { 
      try { 
        canvas=surfaceHolder.lockCanvas(null); //获取BallView的画布 
        synchronized (surfaceHolder) { 
          pv.doDraw(canvas); 
        } 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } finally { 
        if(canvas!=null) { 
          surfaceHolder.unlockCanvasAndPost(canvas); // surfaceHolder解锁,并将画布传回 
        } 
      } 
      this.count++; 
      if(count==20) { //计满20帧时计算一次帧速率 
        count=0; 
        long tempStamp=System.nanoTime(); 
        long span=tempStamp-start; 
        start=tempStamp; 
        double fps=Math.round(100000000000.0/span*20)/100.0; 
        pv.fps="FPS:"+fps; 
      } 
      try { 
        Thread.sleep(sleepSpan); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
}

MainActivity类:

package com.particle; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Window; 
import android.view.WindowManager; 
public class MainActivity extends Activity { 
  ParticleView pv; 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); //设置不显示标题 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //设置全屏 
    pv=new ParticleView(this); 
    setContentView(pv); 
  } 
}

效果图:

二、瀑布粒子效果

瀑布粒子和焰火粒子十分类似,二者的运动都是带有初速度的下落运动。所不同的是焰火粒子水平方向和竖直方向的速度均不为零,而瀑布粒子只有水平方向初速度,竖直方向初速度为零。只需在焰火粒子的生成部分ParticleSet类中修改即可。

ParticleSet类add方法修改如下:

/** 
* 向粒子集合中添加指定数量的粒子对象(瀑布粒子效果) 
*/ 
public void add2(int count, double startTime) { 
    for (int i = 0; i 

效果图:

希望本文所述对大家的Android程序设计有所帮助。


推荐阅读
  • xmake-ftmpxxx.luaxmake--filexxx.lua最简单:--添加名为demo的目标到工程target(demo)--设置目标程序类型为二进制,一般为 ... [详细]
  • DeaDBeeF(音频播放器)v1.8.0官方PC版
      DeaDBeeF音频播放器是一款来自国外的强大音乐播放软件,使用这款完全中文的DeaDBeeF音频播放器可以让你随时编辑本地的音乐文件标签和属性,根据不同的音乐文件配置不同的音色输出 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • [oracle@oracle~]$impxxxx/userfile=/usr/local/src/666.dmpfull=ybuffer=40960000Import: ... [详细]
  • Matlab:数学之美–绘制分形图形学习最好的动力是兴趣,所以我们先看看效果:这一篇与Java学习日记:数学之美-分形图形绘制有共同之处,只是所用的工具不同。clear;%不同的参 ... [详细]
  • A题这题贼水,直接暴力就可以了。用个bool数组记录一下,如果某一天,当前剩下的最大的出现了的话,就输出一段。1#include<stdio.h>2intn;3boolvi ... [详细]
  • #-*-coding:utf-8-*-print(upython与开源QGis课题研究组)#print(汉字)##创建矢量数据文件#try:fromosgeoimporto ... [详细]
  • 主函数:CStringGetCPUIDString()Copyright(C)shangweixiao2011 ... [详细]
  • 1引言在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着JavaSE1.6对Synchronized进行 ... [详细]
  • 本文目录一览:1、\mysybase.dump对数据库正常使用有影响吗 ... [详细]
  • html显示屏幕中心1,HTML中常见的长度单位
    8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?THML中常见的8种长度1、常见的单位px:像素 ... [详细]
  • 我是这么写的, ... [详细]
  • 我有一个vim默认安装在Linux上,在一个系统上有vt52终端仿真器和unicode功能。Vim不会接受换行一切都工作正常,直到今天,当 ... [详细]
  • 并发系列之CAS与原子操作1、CAS的概念2、Java实现CAS的原理-Unsafe类3、原子操作-AtomicInteger类源码简析4、CAS实现原子操作的三大问题4.1、AB ... [详细]
  • 本文主要介绍关于人工智能,shell的知识点,对【winyyy.sys,hcpidesk.sys,mtlrd.sys,uldfhjfh.sys,servets.exe等1】和【】有兴趣的朋友可以看下由 ... [详细]
author-avatar
晴活的比较迷-茫m
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有