AndEngine进阶之自定义Tiled精灵.docx
《AndEngine进阶之自定义Tiled精灵.docx》由会员分享,可在线阅读,更多相关《AndEngine进阶之自定义Tiled精灵.docx(23页珍藏版)》请在冰豆网上搜索。
AndEngine进阶之自定义Tiled精灵
AndEngine内置了一个TiledSprite类,可以传入TiledTextureRegion的纹理以构造一个可以连续播放的精灵,但必须要先制作好一张动画序列图片,俗称Tiled图。
但有时候在游戏项目开发中,美术人员本来的工作量已经很大,而且这种Tiled在需要修改时也带来了工作量。
在IPhone的cocos2d里的精灵类有一个runAction的方法可以播放一组序列图片以达到动画功能,但这种方式在使用的时候稍嫌麻烦,于是我封装了一个自定义Tiled精灵类。
viewplain
1.package com.weedong.sprite;
2.
3.import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X;
4.import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y;
5.
6.import java.util.Arrays;
7.
8.import javax.microedition.khronos.opengles.GL10;
9.
10.import org.anddev.andengine.collision.RectangularShapeCollisionChecker;
11.import org.anddev.andengine.collision.ShapeCollisionChecker;
12.import org.anddev.andengine.entity.primitive.BaseRectangle;
13.import org.anddev.andengine.entity.scene.Scene;
14.import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener;
15.import org.anddev.andengine.entity.shape.IShape;
16.import org.anddev.andengine.entity.shape.RectangularShape;
17.import org.anddev.andengine.input.touch.TouchEvent;
18.import org.anddev.andengine.opengl.texture.Texture;
19.import org.anddev.andengine.opengl.texture.region.TextureRegion;
20.import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
21.import org.anddev.andengine.opengl.texture.region.buffer.TextureRegionBuffer;
22.import org.anddev.andengine.opengl.texture.source.ITextureSource;
23.import org.anddev.andengine.opengl.util.GLHelper;
24.import org.anddev.andengine.util.MathUtils;
25.import org.anddev.andengine.util.constants.TimeConstants;
26.
27.import com.weedong.scene.ITextureLoadManager;
28.import com.weedong.utils.TextureUtils;
29.
30./**
31. * 自定义精灵,几乎可以实现像cocos2d一般的使用非tiled图片进行动画播放的功能
32. * 用法:
在构造函数里传入相关的图片即可
33. * @author
34. *
35. */
36.public class CustomTiledSprite extends BaseRectangle {
37.
38. private static final int LOOP_CONTINUOUS = -1;
39. private boolean mAnimationRunning;
40. private long mAnimationProgress;
41. private long mAnimationDuration;
42. private long[] mFrameEndsInNanoseconds;
43.
44. private int mFirstTileIndex;
45. private int mInitialLoopCount;
46. private int mLoopCount;
47. private IAnimationListener mAnimationListener;
48.
49. private int mFrameCount;
50. private int[] mFrames;
51.
52. private TextureRegion[] aryTextureRegion = null;
53. private TextureRegion mCurrentTextureRegion = null;
54.
55. private IOnAreaTouchListener onAreaTouchListener;
56. private Scene mScene;
57.
58. /**
59. * 构造方法
60. * @param pX
61. * @param pY
62. * @param scene
63. * @param aryTextureSource 传入TextureSource以构造
64. */
65. public CustomTiledSprite(float pX, float pY, Scene scene, ITextureSource[] aryTextureSource) {
66. this(pX, pY, scene, aryTextureSource, false);
67. }
68.
69. /**
70. * 构造方法
71. * @param pX
72. * @param pY
73. * @param scene
74. * @param aryTextureSource 传入TextureSource以构造
75. * @param bFlippedHorizontal 图片是否水平翻转
76. */
77. public CustomTiledSprite(float pX, float pY, Scene scene, ITextureSource[] aryTextureSource, boolean bFlippedHorizontal) {
78. super(pX, pY, aryTextureSource[0].getWidth(),aryTextureSource[0].getHeight());
79. this.mScene = scene;
80. loadAnimationResource(scene, aryTextureSource, bFlippedHorizontal);
81. }
82.
83. /**
84. * 构造方法
85. * @param pX
86. * @param pY
87. * @param scene
88. * @param aryTexture 传入TextureRegion以构造
89. */
90. public CustomTiledSprite(float pX, float pY, Scene scene, TextureRegion[] aryTexture) {
91. super(pX, pY, aryTexture[0].getWidth(),aryTexture[0].getHeight());
92. this.mScene = scene;
93. this.aryTextureRegion = aryTexture;
94. mCurrentTextureRegion = aryTextureRegion[0];
95. this.initBlendFunction();
96. }
97.
98. /**
99. * 注意,若使用此构造函数,请实例化精灵后,一定要使用
100. * loadAnimationResource方法加载资源
101. * @param pX
102. * @param pY
103. */
104. public CustomTiledSprite(float pX, float pY) {
105. super(pX, pY, 0, 0);
106. }
107.
108. /**
109. * 加载动画资源
110. * @author
111. * @param scene 当前的场景
112. * @param aryTextureSource 资源
113. * @param bFlippedHorizontal 是否水平翻转图片
114. */
115. public void loadAnimationResource(Scene scene, ITextureSource[] aryTextureSource, boolean bFlippedHorizontal) {
116. int textureWidth = aryTextureSource[0].getWidth();
117. int textureHeight = aryTextureSource[0].getHeight();
118. this.setWidth(textureWidth);
119. this.setHeight(textureHeight);
120. textureWidth = TextureUtils.getTextureCloseWidth(textureWidth);
121. textureHeight = TextureUtils.getTextureCloseHeight(textureHeight);
122.
123. aryTextureRegion = new TextureRegion[aryTextureSource.length];
124. for(int i = 0; i < aryTextureSource.length; ++i) {
125. Texture texture = new Texture(textureWidth, textureHeight, TextureUtils.autoRecogniseTextureOptions());
126. TextureRegion textureRegion = TextureRegionFactory.createFromSource(texture, aryTextureSource[i], 0, 0);
127. textureRegion.setFlippedHorizontal(bFlippedHorizontal);
128. aryTextureRegion[i] = textureRegion;
129. ITextureLoadManager textureLoadManager = (ITextureLoadManager)scene;
130. textureLoadManager.loadTextureAndAppendToContainer(texture);
131. }
132.
133. mCurrentTextureRegion = aryTextureRegion[0];
134. this.initBlendFunction();
135. }
136.
137. public boolean isAnimationRunning() {
138. return this.mAnimationRunning;
139. }
140.
141. @Override
142. protected void onManagedUpdate(final float pSecondsElapsed) {
143. super.onManagedUpdate(pSecondsElapsed);
144. if(this.mAnimationRunning) {
145. final long nanoSecondsElapsed = (long) (pSecondsElapsed * TimeConstants.NANOSECONDSPERSECOND);
146. this.mAnimationProgress += nanoSecondsElapsed;
147.
148. if(this.mAnimationProgress > this.mAnimationDuration) {
149. this.mAnimationProgress %= this.mAnimationDuration;
150. if(this.mInitialLoopCount !
= LOOP_CONTINUOUS) {
151. this.mLoopCount--;
152. }
153. }
154.
155. if(this.mInitialLoopCount == LOOP_CONTINUOUS || this.mLoopCount >= 0) {
156. final int currentFrameIndex = this.calculateCurrentFrameIndex();
157.
158. if(this.mFrames == null) {
159. this.setCurrentTileIndex(this.mFirstTileIndex + currentFrameIndex);
160. } else {
161. this.setCurrentTileIndex(this.mFrames[currentFrameIndex]);
162. }
163. } else {
164. this.mAnimationRunning = false;
165. if(this.mAnimationListener !
= null) {
166. this.mAnimationListener.onAnimationEnd(this);
167. }
168. }
169. }
170. }
171.
172. public void setCurrentTileIndex(int index) {
173. this.mCurrentTextureRegion = aryTextureRegion[index];
174. this.updateVertexBuffer();
175. mCurrentTextureRegion.getTextureBuffer().update();
176. }
177.
178. public void stopAnimation() {
179. this.mAnimationRunning = false;
180. }
181.
182. public void stopAnimation(final int pTileIndex) {
183. this.mAnimationRunning = false;
184. this.setCurrentTileIndex(pTileIndex);
185. }
186.
187. private int calculateCurrentFrameIndex() {
188. final long animationProgress = this.mAnimationProgress;
189. final long[] frameEnds = this.mFrameEndsInNanoseconds;
190. final int frameCount = this.mFrameCount;
191. for(int i = 0; i < frameCount; i++) {
192. if(frameEnds[i] > animationProgress) {
193. return i;
194. }
195. }
196. return frameCount - 1;
197. }
198.
199. public CustomTiledSprite animate(final long pFrameDurationEach) {
200. return this.animate(pFrameDurationEach, true);
201. }
202.
203. public CustomTiledSprite animate(final long pFrameDurationEach, final boolean pLoop) {
204. return this.animate(pFrameDurationEach, (pLoop) ?
LOOP_CONTINUOUS :
0, null);
205. }
206.
207. public CustomTiledSprite animate(final long pFrameDurationEach, final int pLoopCount) {
208. return this.animate(pFrameDurationEach, pLoopCount, null);
209. }
210.
211. public CustomTiledSprite animate(final long pFrameDurationEach, final boolean pLoop, final IAnimationListener pAnimationListener) {
212. return this.animate(pFrameDurationEach, (pLoop) ?
LOOP_CONTINUOUS :
0, pAnimationListener);
213. }
214.
215. public CustomTiledSprite animate(final long pFrameDurationEach, final int pLoopCount, final IAnimationListener pAnimationListener) {
216. final long[] frameDurations = new long[aryTextureRegion.length];
217. Arrays.fill(frameDurations, pFrameDurationEach);
218. return this