03OPhone平台2D游戏引擎实现图形图像系统.docx
《03OPhone平台2D游戏引擎实现图形图像系统.docx》由会员分享,可在线阅读,更多相关《03OPhone平台2D游戏引擎实现图形图像系统.docx(104页珍藏版)》请在冰豆网上搜索。
![03OPhone平台2D游戏引擎实现图形图像系统.docx](https://file1.bdocx.com/fileroot1/2022-12/16/ffb2cb04-08f0-4c7e-8c33-e4650be7b195/ffb2cb04-08f0-4c7e-8c33-e4650be7b1951.gif)
03OPhone平台2D游戏引擎实现图形图像系统
上一篇文章中我们介绍了引擎的场景、图层部分,我们已经拥有了一个用来代表一个游戏界面的容器,现在就需要向这个容器中加入各种元素,这些元素就是我们上一节给大家介绍的节点,我们前面看到在Node类中定义了一些接口,一直没有使用,本节我们将使用这一部分接口来完成图形图像的渲染,比如一个节点是一张背景图片,那么我们就需要将图片按照Opengl纹理映射的方式来进行贴图操作。
下面先给大家介绍一下本节的主要内容。
∙引擎工具包:
包括常用的逻辑操作和资源的装载等等。
∙2D纹理贴图:
封装实现一个2D的纹理贴图对象,方便引擎中的贴图操作。
∙ 图片集:
将很多图片放到一张大图片上,使用时进行分割,原因稍后解析。
∙ 贴图管理器:
负责管理引擎中所有贴图的缓冲,以及释放,重新载入等逻辑。
∙ 贴图元素:
在Node的基础上实现2D纹理对象,贴图帧,精灵等。
引擎工具包
引擎一般都包含一个工具包,通常用来处理一些简单的逻辑,比如一些数学计算,角度的换转等,这里我们还包括了资源的装载于解析,包括从res文件夹下面获取资源,以及对一个特殊资源(TGA)的解析和使用。
下面我们将分别稍稍他们的实现。
常用工具包
常用工具包就是对一些常用的操作进行了封装,所以大家一看就能明白,我们也加入了注解,这里就不在多浪费时间了。
具体实现入代码清单3-1所示。
代码清单3-1:
Utilities实现
viewplaincopytoclipboardprint?
1.public class Utilities {
2. private static final Random sRandom = new Random();
3. //产生指定的随机数
4. public static float randMinusOneToOne() {
5. return (float) Math.random() * 2.0F - 1.0F;
6. }
7. public static float randZeroToOne() {
8. return (float) Math.random();
9. }
10. public static int rand(int max) {
11. return sRandom.nextInt(max);
12. }
13. //角度与弧度之间的转换
14. public static float d2r(float angle) {
15. return angle / 180.0F * 3.141593F;
16. }
17. public static float r2d(float angle) {
18. return angle / 3.141593F * 180.0F;
19. }
20. //将byte数组转换成UTF8字符串
21. public static String getUTF8String(byte[] b) {
22. if (b == null)
23. return "";
24. return getUTF8String(b, 0, b.length);
25. }
26. public static String getUTF8String(byte[] b, int start, int length) {
27. if (b == null)
28. return "";
29. try {
30. return new String(b, start, length, "UTF-8");
31. } catch (UnsupportedEncodingException e) {
32. }
33. return "";
34. }
35. //指数
36. public static int getClosest2Exp(int num) {
37. if ((num !
= 1) && ((num & num - 1) !
= 0)) {
38. int i = 1;
39. while (i < num)
40. i *= 2;
41. num = i;
42. }
43. return num;
44. }
45. //计算文字的尺寸
46. public static YFSSize calculateTextSize(String text, String fontname,
47. float fontSize) {
48. Typeface typeface = Typeface.create(fontname, 0);
49. Paint paint = new Paint();
50. paint.setTypeface(typeface);
51. paint.setTextSize(fontSize);
52. paint.setAntiAlias(true);
53. int ascent = (int) Math.ceil(-paint.ascent());
54. int descent = (int) Math.ceil(paint.descent());
55. int measuredTextWidth = (int) Math.ceil(paint.measureText(text));
56. return YFSSize.make(measuredTextWidth, ascent + descent);
57. }
58. //创建一个文字Label转换为Bitmap
59. public static Bitmap createLabelBitmap(String text, YFSSize dimensions,
60. Label.TextAlignment alignment, String fontname, float fontSize) {
61. Typeface typeface = Typeface.create(fontname, 0);
62. Paint paint = new Paint();
63. paint.setTypeface(typeface);
64. paint.setTextSize(fontSize);
65. paint.setAntiAlias(true);
66. paint.setColor(-1);
67. int ascent = 0;
68. int descent = 0;
69. int measuredTextWidth = 0;
70. ascent = (int) Math.ceil(-paint.ascent());
71. descent = (int) Math.ceil(paint.descent());
72. measuredTextWidth = (int) Math.ceil(paint.measureText(text));
73. int textWidth = measuredTextWidth;
74. int textHeight = ascent + descent;
75. if ((dimensions.width == 0.0F) || (dimensions.height == 0.0F)) {
76. YFSSize size = calculateTextSize(text, fontname, fontSize);
77. dimensions.width = size.width;
78. dimensions.height = size.height;
79. }
80. int width = getClosest2Exp((int) dimensions.width);
81. int height = getClosest2Exp((int) dimensions.height);
82. Bitmap.Config config = Bitmap.Config.ARGB_8888;
83. Bitmap bitmap = Bitmap.createBitmap(width, height, config);
84. Canvas canvas = new Canvas(bitmap);
85. bitmap.eraseColor(0);
86. int y = ascent + ((int) dimensions.height - textHeight) / 2;
87. int x = 0;
88. switch (alignment) {
89. case RIGHT:
90. x = (int) dimensions.width - textWidth;
91. break;
92. case LEFT:
93. x = ((int) dimensions.width - textWidth) / 2;
94. }
95. canvas.drawText(text, x, y, paint);
96. return bitmap;
97. }
98. //argb转换为rgba格式
99. public static ByteBuffer argb2rgba(Bitmap bmp) {
100. ByteBuffer bb = ByteBuffer.allocateDirect(bmp.getHeight()
101. * bmp.getWidth() * 4);
102. bb.order(ByteOrder.BIG_ENDIAN);
103. IntBuffer ib = bb.asIntBuffer();
104. for (int y = bmp.getHeight() - 1; y > -1; --y) {
105. for (int x = 0; x < bmp.getWidth(); ++x) {
106. int pix = bmp.getPixel(x, bmp.getHeight() - y - 1);
107. int alpha = pix >> 24 & 0xFF;
108. int red = pix >> 16 & 0xFF;
109. int green = pix >> 8 & 0xFF;
110. int blue = pix & 0xFF;
111. ib.put(red << 24 | green << 16 | blue << 8 | alpha);
112. }
113. }
114. bb.position(0);
115. return bb;
116. }
117. //交换数据
118. public static void swap(float[] v, int index1, int index2) {
119. float tmp = v[index1];
120. v[index1] = v[index2];
121. v[index2] = tmp;
122. }
123. //从Raw中读取一个资源文件转换为byte数组
124. public static byte[] dataOfRawResource(Context context, int id) {
125. InputStream in = null;
126. byte[] bytes = (byte[]) null;
127. try {
128. in = context.getResources().openRawResource(id);
129. byte[] buf = new byte[1024];
130. ByteArrayOutputStream out = new ByteArrayOutputStream();
131. for (int i = 0; i !
= -1; i = in.read(buf)) {
132. out.write(buf, 0, i);
133. }
134. bytes = out.toByteArray();
135. out.flush();
136. out.close();
137. } catch (Throwable e) {
138. Log.e("Engine", "Can't read the raw resource:
" + id);
139. } finally {
140. try {
141. if (in !
= null)
142. in.close();
143. } catch (IOException localIOException1) {
144. }
145. }
146. return bytes;
147. }
148.}
publicclassUtilities{privatestaticfinalRandomsRandom=newRandom();//产生指定的随机数publicstaticfloatrandMinusOneToOne(){return(float)Math.random()*2.0F-1.0F;}publicstaticfloatrandZeroToOne(){return(float)Math.random();}publicstaticintrand(intmax){returnsRandom.nextInt(max);}//角度与弧度之间的转换publicstaticfloatd2r(floatangle){returnangle/180.0F*3.141593F;}publicstaticfloatr2d(floatangle){returnangle/3.141593F*180.0F;}//将byte数组转换成UTF8字符串publicstaticStringgetUTF8String(byte[]b){if(b==null)return"";returngetUTF8String(b,0,b.length);}publicstaticStringgetUTF8String(byte[]b,intstart,intlength){if(b==null)return"";try{returnnewString(b,start,length,"UTF-8");}catch(UnsupportedEncodingExceptione){}return"";}//指数publicstaticintgetClosest2Exp(intnum){if((num!
=1)&&((num&num-1)!
=0)){inti=1;while(ix=(int)dimensions.width-textWidth;break;caseLEFT:
x=((int)dimensions.width-textWidth)/2;}canvas.drawText(text,x,y,paint);returnbitmap;}//argb转换为rgba格式publicstaticByteBufferargb2rgba(Bitmapbmp){ByteBufferbb=ByteBuffer.allocateDirect(bmp.getHeight()*bmp