实现的思路:缓存池+(Image或者CHActor) + Actions
例:实现星星右中心点向圆形周围扩散,且星星不断的旋转,缩小,到达圆上时消失。
这个需求里面对于单个星星包含的Action有:
moveTo 移动
roatateBy 旋转
scaleTo 缩小
我们使用Actions.parallel(...)来同时执行上面三个Action。当然我们再执行上面所有Action还需要加上最后的RunnableAction.用来处理粒子结束后的其他工作(释放星星对象到缓存池)。
单个星星的运动过程了解后,剩下的就简单了,我们约定使用30个星星来实现这个效果,在360度的范围随机30次,得到各个星星的运动目标位置,随机整个运动时长。OK。加入舞台,就可以了。
同样,如果我需要一个烟花效果呢?
- 确定一个矩形范围
- 在矩形范围随机位置,播放上面的星星效果,这就是个烟花释放的效果。
理解了这种思路,其他的粒子的效果都不在话下了,自由扩展吧!!!
下面为本人封装两种粒子效果:
package com.oahcfly.chgame.core.helper; import java.util.Random; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.scenes.scene2d.Action; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Pool; import com.badlogic.gdx.utils.Pool.Poolable; import com.badlogic.gdx.utils.Pools; import com.oahcfly.chgame.core.Chao; import com.oahcfly.chgame.core.actions.CHScheduleAction; import com.oahcfly.chgame.core.mvc.CHActor; /** * * <pre> * * 可自由扩展的粒子播放器 * <设置粒子图片路径即可> * date: 2015年3月26日 * </pre> * * @author caohao */ public class CHAutoParticle implements Poolable { private Random random = new Random(); private Pool<CHActor> starPool = null; // 半径 private int cradius = 100; public void setRadius(int radius) { cradius = radius; } private String imgString; // 设置图片路径assets目录下 public void setImagePath(final String imgPath) { this.imgString = imgPath; starPool = (Pool<CHActor>) Pools.get(CHActor.class); } private CHActor getActor() { CHActor chActor = starPool.obtain(); Texture texture = Chao.game.getTexture(imgString); chActor.setBgTexture(texture); chActor.setSize(50, 50); chActor.setOrigin(com.badlogic.gdx.utils.Align.center); float r = (float) ((Math.random() * 0.4f) + 0.7f); float g = (float) ((Math.random() * 0.4f) + 0.7f); float b = (float) ((Math.random() * 0.4f) + 0.7f); chActor.setColor(r, g, b, 1); return chActor; } /** * * @param imgPath * 图片路径 */ public CHAutoParticle(final String imgPath) { setImagePath(imgPath); } public CHAutoParticle() { } /** * * <pre> * <由中心向周围扩散并且旋转缩小> * 播放粒子效果 * date: 2015年3月26日 * </pre> * * @author caohao * @param stage * @param centerX * 中心点位置X * @param centerY * 中心点位置Y */ public void playCircleParticle(Stage stage, float centerX, float centerY) { // 半径范围 float initRadius = cradius; // 星星数量 float starNum = 30; float initStarDuration = 0.3f; for (int i = 0; i < starNum; i++) { // 随机角度 int degree = random.nextInt(360) + 1; // 随机运行时间 float starDuration = (float) (initStarDuration + random.nextInt(5) / 10f); // 随机半径 float radius = initRadius + random.nextInt(10); final CHActor starImg = getActor(); starImg.setPosition(centerX, centerY, Align.center); starImg.setScale(1); // 目标点 float targetX = centerX + (float) (radius * Math.cos(Math.toRadians(degree))); float targetY = centerY + (float) (radius * Math.sin(Math.toRadians(degree))); final boolean islast = i == starNum - 1; // 运动同时进行旋转,缩小 Action parallelAction = Actions.parallel(Actions.moveTo(targetX, targetY, starDuration), Actions.rotateBy(360, starDuration), Actions.scaleTo(0.1f, 0.1f, starDuration)); starImg.addAction(Actions.sequence(parallelAction, Actions.run(new Runnable() { @Override public void run() { // 释放加移除 starPool.free(starImg); starImg.remove(); if (islast) { Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class); pool.free(CHAutoParticle.this); } } }))); stage.addActor(starImg); } } /** * * <pre> * <烟花效果> * * date: 2015年3月26日 * </pre> * * @author caohao * @param stage * @param rangeRectangle * 烟花范围 */ public void playFireWorks(final Stage stage, final Rectangle rangeRectangle, final int playCount, final Runnable callbackRunnable) { Action runnableAction = Actions.run(new Runnable() { int count; @Override public void run() { count++; if (count > playCount) { for (Action action : stage.getRoot().getActions()) { if (action instanceof CHScheduleAction) { ((CHScheduleAction) action).finish(); } } return; } for (int i = 0; i < 10; i++) { int x = (int) (random.nextInt((int) rangeRectangle.width) + rangeRectangle.x); int y = (int) (random.nextInt((int) rangeRectangle.height) + rangeRectangle.y); playCircleParticle(stage, x, y); } } }); Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub if (callbackRunnable != null) { callbackRunnable.run(); } Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class); pool.free(CHAutoParticle.this); } }; CHScheduleAction scheduleAction = new CHScheduleAction(0.5f, playCount, runnableAction); scheduleAction.setCallbackRunnable(runnable); stage.addAction(scheduleAction); } @Override public void reset() { // TODO Auto-generated method stub cradius = 100; if (starPool != null) { starPool.clear(); } } public static CHAutoParticle obtain(String imgPath) { Pool<CHAutoParticle> pool = Pools.get(CHAutoParticle.class); CHAutoParticle chAutoParticle = pool.obtain(); chAutoParticle.setImagePath(imgPath); return chAutoParticle; } }
基于libGdx二次封装的CHGame框架 :
https://git.oschina.net/oahcfly/CHGame
时间: 2024-11-18 23:26:48