360 likes | 475 Views
智能终端软件开发. 孙兴华. 第 10 章 Android 游戏开发. 本章知识结构图. 10.1 Android 游戏开发框架. View 类是 Android 的一个超类,这个类几乎包含了所有的屏幕类型。每一个 View 都有一个用于绘画的画布,这个画布可以进行任意扩展。
E N D
智能终端软件开发 孙兴华 第10章 Android游戏开发
10.1 Android游戏开发框架 View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘画的画布,这个画布可以进行任意扩展。 游戏中最重要的就是需要与玩家交互,比如键盘输入、触笔点击等事件,我们如何来处理这些事件呢?Android中提供了onKeyUp、onKeyDrown、onKeyMuliple、onKeyPreIme、onTouchEvent、onTrackballEvent等方法,可以轻松地处理游戏中的事件消息。 游戏的核心是不断地绘图和刷新界面,图我们可以通过onDraw方法绘制 3
10.1 Android游戏开发框架 下面通过实现一个在屏幕上不停变换颜色的矩形来分析Android中界面的更新。先来看看运行效果,如图1所示;通过线程改变颜色之后,如图2所示;当我们在键盘上按上下键,矩形就会上下移动,如图3所示。 图1 此时为绿色矩形 图2 invalidate方法更新 图10-3 按键处理 4
10.1.2 SurfaceView 类开发框架 游戏中的背景、任务、动画等都需要绘制在一个画布(Canvas)上,而SurfaceView可以直接访问一个画布,SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的。 View及其子类(如TextView和Button)要画在Surface上。每个Surface创建一个Canvas对象(但属性时常改变),用来管理View在Surface上的绘图操作。 5
10.1.2 SurfaceView 类开发框架 在使用SurfaceView开发需要注意的是,使用它绘图时,一般都是出现在最顶层。 使用时还需要对其进行创建、销毁,情况改变时进行监视,这就要实现SurfaceHolder.Callback接口 如果要对被绘制的画布进行裁剪,控制其大小时都需要使用SurfaceHolder来完成处理。 在程序中,SurfaceHolder对象需要通过getHolder方法来获得,同时还需要addCallback方法来添加“回调函数”。 6
10.1.2 SurfaceView 类开发框架 surfaceChanged:在Surface的大小发生改变时激发 surfaceCreated:在创建Surface时激发。 surfaceDestroyed:在销毁Surface时激发。 addCallback:给SurfaceView添加一个回调函数。 lockCanvas:锁定画布,绘图之前必须锁定画布才能得到当前画布对象。 unlockCanvasAndPost:开始绘制时锁定了画布,绘制完成之后解锁画布。 removeCallback:从SurfaceView中移除回调函数。 7
10.1.2 SurfaceView 类开发框架 下面通过一个示例来分析使用SurfaceView开发的视图类,该程序实现了绘制一个不断变换颜色的圆,并且实现了SurfaceView的事件处理,其运行效果如图4所示。当我们按上下键时,图形移动之后效果如图5所示。 图4 SurfaceView 示例图5 SurfaceView 事件处理 8
10.2 Graphics类开发——Paint和Color类 Paint中包含了很多方法对其属性进行设置 setAntiAlias:设置画笔的锯齿效果。 setColor:设置画笔的颜色。 setARGB:设置画笔的a,r,p,g值。 setAlpha:设置Alpha值。 setTextSize:设置字体尺寸。 setStyle: 设置画笔的风格,空心或者实心。 setStrokeWidth:设置空心的边框宽度。 getColor:得到画笔的颜色。 getAlpha得到画笔的Alpha值。 9
10.2 Graphics类开发——Paint和Color类 Color类则更加简单,主要定义了一些颜色常量,以及对颜色的转换等。主要的12种颜色如下表所示。 10
10.2 Graphics类开发——Paint和Color类 Color类同时还提供了Color.rgb方法将整形的颜色转换成Color类型,如Color.red方法可以提供出红色值。下面我们来看一个示例,分别说明这些方法的使用,运行效果如下图所示。 在绘制出图形之后还需要通过Activity类的setContentView方法来设置要显示的具体View类。 11
10.2 Graphics类开发——Canvas类 画笔调整好之后,现在需要绘制到画布上,这就得用到Canvas类了。 除了在画布上绘制之外,还需要设置一些关于画布的属性,比如,画布的颜色、尺寸等。下面来分析Android中Canvas有哪些功能。 12
10.2 Graphics类开发——Canvas类 Canvas提供了如下一些方法。 Canvas():创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布。 Canvas(Bitmap bitmap):以bitmap对象创建一个画布,则将内容都绘制在bitmap上,因此bitmap不得为NULL。 Canvas(GL gl):在绘制3D效果时使用,与OpenGL相关。 drawColor:设置Canvas的背景颜色。 setBitmap:设置具体画布。 clipRect:设置显示区域,即设置裁剪区。 isOpaque:检测是否支持透明。 rotate:旋转画布。 setViewport:设置画布中显示窗口。 skew:设置偏移量。 13
10.2 Graphics类开发——Canvas类 旋转画布时会旋转画布上的所有对象,而我们只是需要旋转其中的一个,这时就需要用到save方法来锁定需要操作的对象, 在操作之后通过restore犯法来解除锁定,运行效果如x下图所示。 我们对左边的矩形旋转操作,而没有旋转右边的矩形,由于我们设置了裁剪区域,因此左边的矩形只能看到一部分。 14
10.2.3 几何图形的绘制 其实前面我们已经看到了在屏幕上显示的矩形、圆形、三角形等几何图形 下面我们来看看在Android中可以绘制出哪些几何图形。 15
10.2.3 几何图形的绘制 下面我们通过一个示例来看看如何绘制这些几何图形,运行效果如下图所示。示例中分别绘制了空心和实心的几何图形。 16
10.2.4 图像绘制 在Android中,项目目录下的“res\drawable”文件夹(包括drawable—hdpi、drawable—mdpi、drawable—ldpi文件夹)用来放置该项目的图片资源, Android中提供了Bitmap来存放这些资源,如下代码可以通过一个资源索引获得其图像对象Bitmap :((BitmapDrawable)getResources().getDrawable(资源索引)).getBitmap(); 然后使用drawBitmap方法将图片显示到屏幕上。如下代码将一个名为bitmap的Bitmap对象显示在(x,y)坐标上:Canvas.drawBitmap(bitmap,x,y,null); Bitmap还提供了一些方法,比如getHeight方法和getWith方法可以获得这个图片的高度和宽度 17
10.2.4 图像绘制 我们将在下面的示例中分析如何使用这些方法,并将图片显示在手机屏幕上,运行效果如下图所示。 该示例显示了两张图片,用户可以通过左右键来控制图片左右移动。 18
10.2.5 图像旋转 在Android中进行图像旋转需要使用Matrix,它包含一个3×3的矩阵,专门用于进行图像变换匹配,Matrix没有结构体,它必须被初始化,通过reset方法或set方法来实现。 通过setRotate设置旋转角度,用createBitmap创建一个经过旋转等处理的Bitmap对象,然后将Bitmap绘制到屏幕上,于是就实现了旋转操作。 19
10.2.5 图像旋转 下面我们通过一个示例来说明Matrix的使用以及旋转方式,运行效果如下图所示,本示例可以通过左右键旋转图像。 20
10.2.6 图像缩放 如何来缩放图像呢?其实和旋转一样,不同的是需要使用Matrix的postScale方法来设置图像缩放的倍数。下面的示例可以通过上下键来缩小和放大图像。下图所示是经过缩小的图像和放大的图像。 21
10.3 动画实现 Tween动画,即通过对场景里的对象不断进行图像变换(平移、缩放、旋转)来产生动画效果 Frame动画,即顺序播放事先做好的图像,和电影类似。 GIF动画的实现原理。 22
10.3.1 Tween动画 首先来分析Tween动画,Tween动画通过对View的内容完成一系列的图形变换(包括平移、缩放、旋转、改变透明度)来实现动画效果。它主要包括以下四种动画效果: Alpha:渐变透明度动画效果。 Scale:渐变尺寸伸缩动画效果。 Translate:画面转换位置移动动画效果。 Rotate:画面转移旋转动画效果。 23
10.3.1 Tween动画(通过Java代码实现) 具体来讲,Tween动画是通过预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。程序沿着时间线执行这些指令就可以实现动画效果。 因此我们首先需要定义Animation动画对象,然后设置该动画的一些属性,最后通过startAnimation方法来开始动画。各个动画的属性设置如下: AlphaAnimation(float fromAlpha, float toAlpha) 功能:构建一个渐变透明度动画 参数:fromAlpha为动画起始时透明度;toAlpha为动画结束时透明度(0.0表示完全透明,1.0表示完全不透明)。 24
10.3.1 Tween动画(通过Java代码实现) ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 功能:构建一个渐变尺寸伸缩动画。 参数:fromX、toX分别是起始和结束时x坐标上的伸缩尺寸。FromY、toY分别是起始和结束是y坐标上的伸缩尺寸。pivotXType、pivotYType分别是x、y的伸缩模式。pivoXValue、pivotYValue分别为伸缩动画相对于x、y的坐标开始位置。 TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) 功能:构建一个画面转换位置移动动画。 参数:fromXDelta、fromYDelta分别为起始坐标;toXDelta、toYDelta分别为结束坐标。 25
10.3.1 Tween动画(通过Java代码实现) RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 功能:构建一个旋转画面的动画。 参数fromDegrees未开始的角度;toDegrees未结束的角度。pivotXType、pivotYType分别为x、y的伸缩模式。pivotXValue、pivotYValue分别为伸缩动画相对于x、y的坐标开始位置。 setDuration(long durationMillis) 功能:设置动画显示的时间。 参数:durationMillis为动画显示时间的长短,以毫秒为单位。 startAnimation`(Animation animation) 功能:开始播放动画。 参数:animation为要播放的动画。 26
10.3.1 Tween动画(通过Java代码实现) 下面我们通过具体代码来看这些动画是如何实现的,AlphaAnimation动画、ScaleAnimation动画、TranslateAnimation动画、RotateAnimation动画如下图所示,分别通过操作上、下、左、右四个方向键来显示动画效果。 27
10.3.1 Tween动画(通过XML代码实现) 在Andriod中使用XML布局文件实现动画更加简单,下面我们分别将这4种动画改用XML布局文件来实现。 <alpha>动画中,fromAlpha表示透明度,toAlpha表示结束透明度,duration表示动画的时间长短。 在<scale>动画布局中,fromXScale为动画起始时x坐标上的伸缩尺寸,toXScale为动画结束时x坐标上的伸缩尺寸,fromYScale为动画起始时y坐标上的伸缩尺寸,toYScale为动画结束时y坐标上的伸缩尺寸;pivotX为动画相对于物件的x坐标时的开始位置,pivotY为动画相对于物件的y坐标的开始位置;duration表示动画的时间长短。 在<translate>动画布局中,fromXDelta为动画起始时x坐标上的位置,toXDelta为动画结束时x坐标上的位置,fromYDelta为动画起始时y坐标上的位置,toYDelta为动画结束时y坐标上的位置;duration表示动画的时间长短。 28
10.3.1 Tween动画(通过XML代码实现) 在Andriod中使用XML布局文件实现动画更加简单,下面我们分别将这4种动画改用XML布局文件来实现。 在<rotate>动画布局中,interpolator指定了一个动画插入器,fromDegrees为动画起始时物件的角度,toDegrees为动画结束时物件旋转的角度(可以大于360度),pivotX为动画相对于物件的x坐标的开始位置,pivotY为动画相对于物件的y坐标的开始位置,duration表示动画的时间长短。 现在我们完成了几种动画的XML布局,下面只需要在程序中装载这些布局,然后开始播放动画即可。 29
10.3.2 Frame 动画 只需要创建一个AnimationDrawable对象来表示Frame动画 然后通过addFrame方法把每一帧要显示的内容添加进去 最后通过start方法就可以播放这个动画了,同时还可以通过setOneShot方法来设置该动画是否重复播放。 30
10.3.2 Frame 动画(通过Java代码实现) 下面我们就通过Frame动画来模拟日全食效果。 按上方向键开始欣赏日全食效果。 31
10.3.2 Frame 动画(通过xml代码实现) 如果使用XML布局文件来实现Frame动画,基本上就不用写多少代码了,只需要在XML文件中通过oneshot设置动画是否重复播放,然后将所有帧都列出来即可 最后在程序中通过setBackgroundResource方法加载这个XML动画布局文件 通过用getBackground方法得到动画 通过用setBackgroundDrawable方法设置要显示的动画 通过用start开始播放动画即可欣赏和上面一样的日全食效果了, 32
10.3.2 Frame 动画(通过xml代码实现) 如果使用XML布局文件来实现Frame动画,基本上就不用写多少代码了,只需要在XML文件中通过oneshot设置动画是否重复播放,然后将所有帧都列出来即可 最后在程序中通过setBackgroundResource方法加载这个XML动画布局文件 通过用getBackground方法得到动画 通过用setBackgroundDrawable方法设置要显示的动画 通过用start开始播放动画即可欣赏和上面一样的日全食效果了, 33
10.3.3 GIF动画播放 本示例播放的一张GIF动画,想要播放GIF动画,首先需要对GIF图像进行解码,然后将GIF中的每一帧分别提取出来保存到一个容器中,然后根据需要连续绘制每一帧,这样就可以轻松地实现GIF动画的播放。 这个逻辑过程十分简单,首先需要创建一个GIF图像解码类,然后需要一个GIF帧管理器来管理GIF的每一帧的图片。最后,使用这两个类播放一张GIF动画。 34
10.4小结 Android中的游戏开发框架, 图像图像的绘制和处理方法, Android中的两种动画的实现原理, Android平台中如何播放GIF动画。 对于复杂的游戏来说,还需要更高级的处理以及优化,后面的章节会专门讨论这方面的话题,希望大家保持高度的热情继续后面的学习! 35
Q & A Any questions??