libgdx学习笔记02

来源:互联网 发布:随州seo服务 编辑:程序博客网 时间:2024/04/28 00:12
 一个游戏引擎要做出精美的游戏出来,有两个类是必不可少的,一个是精灵类,一个是粒子系统。粒子系统可以做出各种精妙的效果,如水流,火焰,烟雾等等,制作精美的粒子系统甚至可以以假乱,制作出令人惊叹的效果。

         Libgdx也提供了粒子系统的支持,而且令人兴奋的是,libgdx提供了一个可视化的粒子系统编辑器,我们可以采取边编辑边预览的方式,“所见即所得”,很快就能做出不错的粒子系统效果。


          Libgdx粒子系统编辑器—Particle Editor
Particle Editor下载地址:
http://libgdx.googlecode.com/svn/jws/particle-editor.jnlp

       这里请大家注意一点,把该工具下载下来以后,需要保证你的计算机已经安装了jre即Java环境这样工具才能运行。jre的安装方法就问一下度娘吧。 


这是我今天将最新版下载下来以后打开的截图:

        嘿嘿,这里大家可以先做一个工作,就是先save一下,将得到的一个文件,我们将它保存为particle.p,这个可以留下来等会用,嘿嘿。这里还需要一个用来形成单个粒子的图片,一般用一个很小的白色小圆即可,在我的源码里有,也可以用任意图片代替,当然出来的效果就不一样啦。我还会在附件里面添加一个我随意做的.p文件,也就是粒子效果文件,显示的效果应该是彩虹色,大家可以用该工具打开后就可以根据下面各个参数的解释一一摸索,调整对应参数观察变化,然后自己做出一些更好的效果出来。


官方网站上对软件中的各个参数的解释如下:
Delay:   当粒子系统开始后,发射器等待多少时间开始发射
Duration发射器生存跨度,也就是粒子效果持续的的时间,注意这个时间和粒子生存时间不同 
Count:   顾名思义,同一时间可出现的粒子个数,有一个上限一下下限。
Emission: 每秒钟发射多少个粒子,这个参数带了一张图表,图表中间写着duration,代表图表X 轴表示发射器生存时间,意思是说发射器的生存时间内,该图表控制各个时间点粒子每秒钟发射多少个,左边的上下两个文本框用于控制生成初始值时的范围,左边的'>'字符用于输入另外一个数值,比如说下面那个”>“, 发射器会在这两个值中间选择一下随机值作为上限值,Relative,如果选中,表示图表中的值是相对值,相对于初始值。否则是个绝对值.
Life: 一个粒子的生存时间,
Life Offset: 决定粒子在显示之前已经用掉它生命多少值 ,这样可以实现让一个粒子在它生命50%时再显现
X Offset and Y Offset: 粒子出现在位置相对中心位置的像素偏移
Spawn: 用于产生粒子的发射器的形状
Spawn Width and Spawn Height: 发射器的形状的宽,高
Size: 粒子的大小 
Velocity: 
Angle:
Rotation:
这个几值用于控制粒子的运动轨迹:
Wind and Gravity: 烟为生存时间内在X轴和Y轴上每秒种的像素偏移值
Tint: 粒子的颜色,可以在粒子生存期内变化任意多个颜色
Transparency:粒子的透明度


      下面我们做一些代码上的准备,今天要实现的是实现粒子模拟出触摸轨迹的一个功能,代码在上一讲的代码的基础上做进一步的修改。


在MyGame.java里添加四个变量
ParticleEffect particle;
ParticleEffect tem;
ParticleEffectPool particlepool;
ArrayList<ParticleEffect>particlelist;


    第一个即为粒子实例,第二个是一个临时变量,这里重点要说一下的是第三个量,这是一个ParticleEffectPool的实例,这是一个粒子系统的统一管理的类,负责管理粒子系统的产生回收,可以用它的obtain()方法得到一个ParticleEffect实例,我们当然可以不用这个类而直接新建ParticleEffect实例,但是如果要产生大量的粒子(为了产生更真实的效果往往我们必须这么做),粒子的管理就是一个很大的问题,因此使用ParticleEffectPool是个很不错的选择。添加以后的代码如下所示:


  1. public class MyGame implements ApplicationListener {
  2.     SpriteBatch batch;
  3.     BitmapFont bf;
  4.     ParticleEffect particle;
  5.     ParticleEffect tem;
  6.     ParticleEffectPool particlepool;
  7.     ArrayList<ParticleEffect> particlelist;
  8.         public void create () {
  9.                 // STUB
  10.         batch=new SpriteBatch();
  11.         bf=new BitmapFont();
  12.         //初始化粒子变量
  13.         particle = new ParticleEffect();
  14.         particle.load(Gdx.files.internal("particle.p"), Gdx.files.internal("particle.png"));
  15.         particlepool=new ParticleEffectPool(particle, 5, 10);
  16.         }

  17.         public void render () {
  18.                 // STUB
  19.         Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  20.         Gdx.gl.glClearColor(0f,0f,0f,0f);
  21.         batch.begin();
  22.         bf.draw(batch, "Testin  Mkey libgdx(2)",Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
  23.         batch.end();
  24.         }

  25.         public void resize (int width, int height) {
  26.                 // STUB
  27.         }

  28.         public void pause () {
  29.                 // STUB
  30.         }

  31.         public void resume () {
  32.                 // STUB
  33.         }

  34.         public void dispose () {
  35.                 // STUB
  36.          batch.dispose();
  37.         bf.dispose();
  38.         //千万别忘了释放内存
  39.         particle.dispose();
  40.         if(tem!=null)
  41.             tem.dispose();
  42.         particlepool.clear();
  43.         }
  44. }
复制代码
    这里说明一点Gdx.files.internal()的位置是在项目的asset根目录下,同理在asset下的data文件夹的话,格式应该为Gdx.files.internal(“data/particle.p”).
另外,我们在上一讲中已经提到,libgdx中很多资源需要手动回收,
ParticleEffect,ParticleEffectPool 两个类都实现了Disposeable接口(新版的ParticleEffectPool没有了dispose()方法而用clear()方法替代),千万记得手动回收一下资源。
另外ParticleEffect,ParticleEffectPool使用前都要初始化:

  1. particle.load(Gdx.files.internal("particle.p"),
  2. Gdx.files.internal(""));
复制代码


   第一个参数Particle Editor生成的编辑文件(注意后缀名也是自己取的,读取的时候记得对应),第二个参数是形成单个粒子的图片文件。

这里有一点非常重要!请万分注意:第一个参数是ParticleEditor生成的编辑文件,图片文件的文件名必须为particle.png,也就是说无论粒子编辑文件的名字是什么,系统读取的图片文件都应该是particle.png,而有关两者的路径问题,举个例子大家就应该能明白。如果在asset下的data文件夹的话,格式应该写为Gdx.files.internal(“data/particle.p”)和Gdx.files.internal(“data/”)也就是说,png图片实际上是不需要在代码中写出来的,不过文件名要保持一致才能正确读取。
  1. particlepool=new ParticleEffectPool(particle, 5, 10);
复制代码
    第一个参数是刚刚初始化完成的粒子,第二个参数是制定该粒子池里以第一个参数为模板生成多少个粒子可以供系统随时调用,第三个参数是粒子池中最大的粒子数目。


    下面我们实现粒子模拟触摸轨迹的功能,首先我们需要捕捉到触摸事件。而且我们面临一个很现实的问题:我们在哪里捕捉触摸事件?要知道libgdx和API可不一样,我们没有办法使用API在libgdx中获取触摸事件。对此Gdx包中的input部分提供了Gdx.input.isTouched()方法,判断当前屏幕是否被触摸,是则返回true。我们将这一语句放在render()方法中,就达到了随时检测的目的。修改后的MyGame.java的代码如下:


  1. public class MyGame implements ApplicationListener {
  2.     SpriteBatch batch;
  3.     BitmapFont bf;
  4.     ParticleEffect particle;
  5.     ParticleEffect tem;
  6.     ParticleEffectPool particlepool;
  7.     ArrayList<ParticleEffect> particlelist;
  8.         public void create () {
  9.                 // STUB
  10.         batch=new SpriteBatch();
  11.         bf=new BitmapFont();
  12.         //初始化粒子变量
  13.         particle = new ParticleEffect();
  14.         particle.load(Gdx.files.internal("particle.p"), Gdx.files.internal(""));
  15.         particlepool=new ParticleEffectPool(particle, 5, 10);
  16.         particlelist=new ArrayList<ParticleEffect>();
  17.         }

  18.         public void render () {
  19.                 // STUB
  20.         Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  21.         Gdx.gl.glClearColor(0f,0f,0f,0f);
  22.         batch.begin();
  23.         bf.draw(batch, "Testin  Mkey libgdx(3)",Gdx.graphics.getWidth()*0.4f, Gdx.graphics.getHeight()/2);
  24.         batch.end();
  25.         if(true){
  26.              if(Gdx.input.isTouched()){
  27.                 //当此触摸点与上一触摸点距离大于一定值的时候触发新的粒子系统,由此减小系统负担
  28.                 tem=particlepool.obtain();
  29.                 tem.setPosition(Gdx.input.getX(),Gdx.graphics.getHeight()-Gdx.input.getY());
  30.                 particlelist.add(tem);
  31.              }
  32.              batch.begin();
  33.                 for(int i=0;i<particlelist.size();i++){
  34.              particlelist.get(i).draw(batch, Gdx.graphics.getDeltaTime());
  35.                 }
  36.                 batch.end();
  37.        
  38.                 //清除已经播放完成的粒子系统
  39.                 ParticleEffect temparticle;
  40.                 for(int i=0;i<particlelist.size();i++){
  41.                   temparticle=particlelist.get(i);
  42.                  if(temparticle.isComplete()){
  43.                      particlelist.remove(i);
  44.                  }
  45.                 }
  46.              }
  47.         }

  48.         public void resize (int width, int height) {
  49.                 // STUB
  50.         }

  51.         public void pause () {
  52.                 // STUB
  53.         }

  54.         public void resume () {
  55.                 // STUB
  56.         }

  57.         public void dispose () {
  58.                 // STUB
  59.         batch.dispose();
  60.         bf.dispose();
  61.         //千万别忘了释放内存
  62.         particle.dispose();
  63.         if(tem!=null)
  64.             tem.dispose();
  65.         particlepool.clear();
  66.         }
  67. }
复制代码


    其中添加了一些很简单的去除已完成的粒子系统的代码,想来对大家也没有什么难度,因此不做过多的解释了.

    为了演示方便,我对前面保存的particle.p做了适当的修改,并在编辑器最下方中勾选了 continuous,即连续播放,也是为了让大家看的更清楚一些,