libgdx 2D 粒子效果

先贴几个文档链接:

https://github.com/libgdx/libgdx/wiki/2d-particle-effects

https://github.com/libgdx/libgdx/wiki/2D-Particle-Editor

http://www.java-gaming.org/topics/particle-effects-in-libgdx/29484/view.html

 

先贴个官网GitHub上的测试代码,代码和资源都可以去下。这里不能传附件??

  1 public class ParticleEmitterTest extends GdxTest {
  2     private SpriteBatch spriteBatch;
  3     ParticleEffect effect;
  4     int emitterIndex;
  5     Array<ParticleEmitter> emitters;
  6     int particleCount = 10;
  7     float fpsCounter;
  8     InputProcessor inputProcessor;
  9 
 10     @Override
 11     public void create () {
 12         spriteBatch = new SpriteBatch();
 13 
 14         effect = new ParticleEffect();
 15         effect.load(Gdx.files.internal("data/test.p"), Gdx.files.internal("data"));//第一个参数是粒子效果文件,第二个参数是图片basepath
 16         effect.setPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
 17         // Of course, a ParticleEffect is normally just used, without messing around with its emitters.
 18         emitters = new Array(effect.getEmitters());//原笔者把多个效果都放在一个文件里了,为了显示需要,这里特殊处理了,如果注释掉这三行,可以看出,几个效果一起显示了
 19         effect.getEmitters().clear();
 20         effect.getEmitters().add(emitters.get(0));
 21 
 22         inputProcessor = new InputProcessor() {
 23             public boolean touchUp (int x, int y, int pointer, int button) {
 24                 return false;
 25             }
 26 
 27             public boolean touchDragged (int x, int y, int pointer) {
 28                 effect.setPosition(x, Gdx.graphics.getHeight() - y);
 29                 return false;
 30             }
 31 
 32             public boolean touchDown (int x, int y, int pointer, int newParam) {//改变粒子的个数,重新显示
 33                 // effect.setPosition(x, Gdx.graphics.getHeight() - y);
 34                 ParticleEmitter emitter = emitters.get(emitterIndex);
 35                 particleCount += 100;
 36                 System.out.println(particleCount);
 37                 particleCount = Math.max(0, particleCount);
 38                 if (particleCount > emitter.getMaxParticleCount()) emitter.setMaxParticleCount(particleCount * 2);
 39                 emitter.getEmission().setHigh(particleCount / emitter.getLife().getHighMax() * 1000);
 40                 effect.getEmitters().clear();
 41                 effect.getEmitters().add(emitter);
 42                 return false;
 43             }
 44 
 45             public boolean keyUp (int keycode) {
 46                 return false;
 47             }
 48 
 49             public boolean keyTyped (char character) {
 50                 return false;
 51             }
 52 
 53             public boolean keyDown (int keycode) {
 54                 ParticleEmitter emitter = emitters.get(emitterIndex);
 55                 if (keycode == Input.Keys.W)//我没找到原始的键,我改成W
 56                     particleCount += 5;
 57                 else if (keycode == Input.Keys.S)我没找到原始的键,我改成S
 58                     particleCount -= 5;
 59                 else if (keycode == Input.Keys.SPACE) {
 60                     emitterIndex = (emitterIndex + 1) % emitters.size;
 61                     emitter = emitters.get(emitterIndex);
 62 
 63                     // if we've previously stopped the emitter reset it
 64                     if (emitter.isComplete()) emitter.reset();
 65                     particleCount = (int)(emitter.getEmission().getHighMax() * emitter.getLife().getHighMax() / 1000f);
 66                 } else if (keycode == Input.Keys.ENTER) {
 67                     emitter = emitters.get(emitterIndex);
 68                     if (emitter.isComplete())
 69                         emitter.reset();
 70                     else
 71                         emitter.allowCompletion();
 72                 } else
 73                     return false;
 74                 particleCount = Math.max(0, particleCount);
 75                 if (particleCount > emitter.getMaxParticleCount()) emitter.setMaxParticleCount(particleCount * 2);
 76                 emitter.getEmission().setHigh(particleCount / emitter.getLife().getHighMax() * 1000);
 77                 effect.getEmitters().clear();
 78                 effect.getEmitters().add(emitter);
 79                 return false;
 80             }
 81 
 82             @Override
 83             public boolean mouseMoved (int x, int y) {
 84                 return false;
 85             }
 86 
 87             @Override
 88             public boolean scrolled (int amount) {
 89                 return false;
 90             }
 91         };
 92 
 93         Gdx.input.setInputProcessor(inputProcessor);
 94     }
 95 
 96     @Override
 97     public void dispose () {
 98         spriteBatch.dispose();
 99         effect.dispose();//注意
100     }
101 
102     public void render () {
103         spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
104         float delta = Gdx.graphics.getDeltaTime();
105         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
106         spriteBatch.begin();
107         effect.draw(spriteBatch, delta);//这里绘制粒子效果
108         spriteBatch.end();
109         fpsCounter += delta;
110         if (fpsCounter > 3) {
111             fpsCounter = 0;
112             int activeCount = emitters.get(emitterIndex).getActiveCount();
113             Gdx.app.log("libgdx", activeCount + "/" + particleCount + " particles, FPS: " + Gdx.graphics.getFramesPerSecond());
114         }
115     }
116 
117     public boolean needsGL20 () {
118         return false;
119     }
120 }

这只是测试代码,我们平时在使用的时候,几乎不这么用。

1. 大多数情况下我们都是用stage/actor结构的,不会在Screen里专门去draw粒子效果,或者说是很少情况下。

2. 效果文件在使用的时候大多数都是调好了的,不需要我们代码去调节那些参数。

3. ParticleEffectPool我还没看呢....

 

好,我们先在stage中尝试绘制一个粒子效果

其实只是自定义包装一个Actor类,在draw的时候,draw里面的effect就好了。

见代码:

 1 public class ParticleEffectActor extends Actor {
 2     ParticleEffect particleEffect;
 3     Vector2 acc = new Vector2();
 4     private static final Logger LOGGER = new Logger(ParticleEffectActor.class.getName(), Application.LOG_DEBUG);
 5     public ParticleEffectActor(ParticleEffect particleEffect) {
 6         super();
 7         this.particleEffect = particleEffect;
 8     }
 9 
10     @Override
11     public void draw(Batch batch, float parentAlpha) {
12         particleEffect.draw(batch);
13         //LOGGER.debug("draw");
14     }
15 
16     @Override
17     public void act(float delta) {
18         super.act(delta);
19         acc.set(getWidth() / 2, getHeight() / 2);
20         localToStageCoordinates(acc);
21         //LOGGER.debug(acc.toString());
22         particleEffect.setPosition(acc.x, acc.y);
23         particleEffect.update(delta);
24 
25     }
26 
27     public void start(){
28         particleEffect.start();
29     }
30 }

 

 

 1 public class ParticleTest extends ApplicationAdapter implements InputProcessor {
 2     private Stage stage;
 3     private ParticleEffect effect;
 4     private static final Logger LOGGER = new Logger(ParticleTest.class.getName(),Application.LOG_DEBUG);
 5     
 6     @Override
 7     public void create () {
 8         Gdx.app.setLogLevel(Application.LOG_DEBUG);
 9         stage = new Stage();
10         Gdx.input.setInputProcessor(this);
11         effect = new ParticleEffect();
12         effect.load(Gdx.files.internal("data/abc.p"), Gdx.files.internal("data"));//第一个参数是粒子效果文件,第二个参数是图片basepath(这里应该有一个默认的particle.png别忘了)
13 
14     }
15 
16     @Override
17     public void render () {
18         Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
19         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
20         stage.act();
21         stage.draw();
22     }
23 
24     @Override
25     public void dispose() {
26         effect.dispose();
27         stage.dispose();
28         super.dispose();
29     }
30 
31     @Override
32     public void resize(int width, int height) {
33         stage.getViewport().update(width,height);
34         super.resize(width, height);
35     }
36 
37     private void addEffect(){
38         final ParticleEffectActor actor = new ParticleEffectActor(effect);
39 
40         actor.setPosition(0,0);
41 
42         MoveToAction action = Actions.moveTo(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 4.0f);
43 
44         RunnableAction run = Actions.run(new Runnable() {
45             @Override
46             public void run() {
47                 stage.getActors().removeValue(actor, true);
48             }
49         });
50         actor.addAction(Actions.sequence(action,run));
51         actor.start();
52         stage.addActor(actor);
53     }
54 
55     @Override
56     public boolean keyDown(int keycode) {
57         if(keycode == Input.Keys.J){
58             addEffect();
59         }
60         return false;
61     }
62 
63     @Override
64     public boolean keyUp(int keycode) {
65         return false;
66     }
67 
68     @Override
69     public boolean keyTyped(char character) {
70         return false;
71     }
72 
73     @Override
74     public boolean touchDown(int screenX, int screenY, int pointer, int button) {
75         return false;
76     }
77 
78     @Override
79     public boolean touchUp(int screenX, int screenY, int pointer, int button) {
80         return false;
81     }
82 
83     @Override
84     public boolean touchDragged(int screenX, int screenY, int pointer) {
85         return false;
86     }
87 
88     @Override
89     public boolean mouseMoved(int screenX, int screenY) {
90         return false;
91     }
92 
93     @Override
94     public boolean scrolled(int amount) {
95         return false;
96     }
97 }

 

以上代码中,我们在按下J键的时候,在stage中添加一个粒子效果actor,这个actor从左下角开始向右上角移动,4秒。

注意actor的start方法,官方粒子的素材不需要就可以显示,如果是粒子编辑器默认例子没改过,则需要这个。可能跟life什么的设置有关吧。

至于快速连续按下J键看到的情况,还有待研究,可能是共用同一个effect的缘故,particleEffect的update每个都调用了。

那倒不如把particleEffect直接放到actor中去构造,释放也放在里面,待研究吧。

 

转载于:https://www.cnblogs.com/hanhongmin/p/3960948.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值