您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 03_OPhone平台2D游戏引擎实现――图形图像系统
上一篇文章中我们介绍了引擎的场景、图层部分,我们已经拥有了一个用来代表一个游戏界面的容器,现在就需要向这个容器中加入各种元素,这些元素就是我们上一节给大家介绍的节点,我们前面看到在Node类中定义了一些接口,一直没有使用,本节我们将使用这一部分接口来完成图形图像的渲染,比如一个节点是一张背景图片,那么我们就需要将图片按照Opengl纹理映射的方式来进行贴图操作。下面先给大家介绍一下本节的主要内容。引擎工具包:包括常用的逻辑操作和资源的装载等等。2D纹理贴图:封装实现一个2D的纹理贴图对象,方便引擎中的贴图操作。图片集:将很多图片放到一张大图片上,使用时进行分割,原因稍后解析。贴图管理器:负责管理引擎中所有贴图的缓冲,以及释放,重新载入等逻辑。贴图元素:在Node的基础上实现2D纹理对象,贴图帧,精灵等。引擎工具包引擎一般都包含一个工具包,通常用来处理一些简单的逻辑,比如一些数学计算,角度的换转等,这里我们还包括了资源的装载于解析,包括从res文件夹下面获取资源,以及对一个特殊资源(TGA)的解析和使用。下面我们将分别稍稍他们的实现。常用工具包常用工具包就是对一些常用的操作进行了封装,所以大家一看就能明白,我们也加入了注解,这里就不在多浪费时间了。具体实现入代码清单3-1所示。代码清单3-1:Utilities实现viewplaincopytoclipboardprint?1.publicclassUtilities{2.privatestaticfinalRandomsRandom=newRandom();3.//产生指定的随机数4.publicstaticfloatrandMinusOneToOne(){5.return(float)Math.random()*2.0F-1.0F;6.}7.publicstaticfloatrandZeroToOne(){8.return(float)Math.random();9.}10.publicstaticintrand(intmax){11.returnsRandom.nextInt(max);12.}13.//角度与弧度之间的转换14.publicstaticfloatd2r(floatangle){15.returnangle/180.0F*3.141593F;16.}17.publicstaticfloatr2d(floatangle){18.returnangle/3.141593F*180.0F;19.}20.//将byte数组转换成UTF8字符串21.publicstaticStringgetUTF8String(byte[]b){22.if(b==null)23.return;24.returngetUTF8String(b,0,b.length);25.}26.publicstaticStringgetUTF8String(byte[]b,intstart,intlength){27.if(b==null)28.return;29.try{30.returnnewString(b,start,length,UTF-8);31.}catch(UnsupportedEncodingExceptione){32.}33.return;34.}35.//指数36.publicstaticintgetClosest2Exp(intnum){37.if((num!=1)&&((num&num-1)!=0)){38.inti=1;39.while(inum)40.i*=2;41.num=i;42.}43.returnnum;44.}45.//计算文字的尺寸46.publicstaticYFSSizecalculateTextSize(Stringtext,Stringfontname,47.floatfontSize){48.Typefacetypeface=Typeface.create(fontname,0);49.Paintpaint=newPaint();50.paint.setTypeface(typeface);51.paint.setTextSize(fontSize);52.paint.setAntiAlias(true);53.intascent=(int)Math.ceil(-paint.ascent());54.intdescent=(int)Math.ceil(paint.descent());55.intmeasuredTextWidth=(int)Math.ceil(paint.measureText(text));56.returnYFSSize.make(measuredTextWidth,ascent+descent);57.}58.//创建一个文字Label转换为Bitmap59.publicstaticBitmapcreateLabelBitmap(Stringtext,YFSSizedimensions,60.Label.TextAlignmentalignment,Stringfontname,floatfontSize){61.Typefacetypeface=Typeface.create(fontname,0);62.Paintpaint=newPaint();63.paint.setTypeface(typeface);64.paint.setTextSize(fontSize);65.paint.setAntiAlias(true);66.paint.setColor(-1);67.intascent=0;68.intdescent=0;69.intmeasuredTextWidth=0;70.ascent=(int)Math.ceil(-paint.ascent());71.descent=(int)Math.ceil(paint.descent());72.measuredTextWidth=(int)Math.ceil(paint.measureText(text));73.inttextWidth=measuredTextWidth;74.inttextHeight=ascent+descent;75.if((dimensions.width==0.0F)||(dimensions.height==0.0F)){76.YFSSizesize=calculateTextSize(text,fontname,fontSize);77.dimensions.width=size.width;78.dimensions.height=size.height;79.}80.intwidth=getClosest2Exp((int)dimensions.width);81.intheight=getClosest2Exp((int)dimensions.height);82.Bitmap.Configconfig=Bitmap.Config.ARGB_8888;83.Bitmapbitmap=Bitmap.createBitmap(width,height,config);84.Canvascanvas=newCanvas(bitmap);85.bitmap.eraseColor(0);86.inty=ascent+((int)dimensions.height-textHeight)/2;87.intx=0;88.switch(alignment){89.caseRIGHT:90.x=(int)dimensions.width-textWidth;91.break;92.caseLEFT:93.x=((int)dimensions.width-textWidth)/2;94.}95.canvas.drawText(text,x,y,paint);96.returnbitmap;97.}98.//argb转换为rgba格式99.publicstaticByteBufferargb2rgba(Bitmapbmp){100.ByteBufferbb=ByteBuffer.allocateDirect(bmp.getHeight()101.*bmp.getWidth()*4);102.bb.order(ByteOrder.BIG_ENDIAN);103.IntBufferib=bb.asIntBuffer();104.for(inty=bmp.getHeight()-1;y-1;--y){105.for(intx=0;xbmp.getWidth();++x){106.intpix=bmp.getPixel(x,bmp.getHeight()-y-1);107.intalpha=pix24&0xFF;108.intred=pix16&0xFF;109.intgreen=pix8&0xFF;110.intblue=pix&0xFF;111.ib.put(red24|green16|blue8|alpha);112.}113.}114.bb.position(0);115.returnbb;116.}117.//交换数据118.publicstaticvoidswap(float[]v,intindex1,intindex2){119.floattmp=v[index1];120.v[index1]=v[index2];121.v[index2]=tmp;122.}123.//从Raw中读取一个资源文件转换为byte数组124.publicstaticbyte[]dataOfRawResource(Contextcontext,intid){125.InputStreamin=null;126.byte[]bytes=(byte[])null;127.try{128.in=context.getResources().openRawResource(id);129.byte[]buf=newbyte[1024];130.ByteArrayOutputStreamout=newByteArrayOutputStream();131.for(inti=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(Throwablee){138.Log.e(Engine,Can'treadtherawresource:+id);139.}finally{140.try{141.if(in!=null)142.in.close();143.}catch(IOExceptionlocalIOException1){144.}145.}146.returnbytes;147.}148.}其中包括了指定随机数的产生,数据类型的转换,颜色格式的转换,和资源的装载,创建文字标签,这里需要说明的是Opengl中所使用的颜色格式为rgba所以我们需要对argb颜色格式进行转换,关于创建文字标签的函数,如果你不太理解,不要紧,我们后面还会进一步的分析。大家这里需要对工具包中所提供的工具有一些了解,后面我们就会经常使用到。分辨率工具OPhone平台有不同分辨率的机器,所以我们在开发游戏时也就需要考虑到机型适配的问题,比如我们将一张256*256的图片放置在drawable-mdpi文件夹下面,如果在hdpi机器上运行时,该图片就会被放大到384*384的尺寸,因此我们在使用这些图片时就不能使用固定的尺寸大小了,但是OPhone为我们提供了TypedValue.applyDimension函数用来计算尺寸的适配。该引擎我们也专门整理实现了一个类ResolutionIndependent用来计算合适的尺寸,具体实现如代码清单3-2所示。
本文标题:03_OPhone平台2D游戏引擎实现――图形图像系统
链接地址:https://www.777doc.com/doc-3603976 .html