一、概述
这一讲我将带着大家来实现文字和图片的绘制,然后试着让文字和图片在屏幕里动起来。虽然,离真正的游戏还有一段距离,但是,这些都是游戏的基础,所以,大家都是需要掌握的。好的,不多说了,一起进入正题吧!
完成这一讲的任务,我们需要掌握如下一些概念,然后我会分别进行讲解。
层的概念
文字层
贴图层
View对象:自定义显示控件
onDraw()方法:执行一系列绘制
Canvas对象:画布,呈现数据
Paint:画笔对象
drawText:绘制文字
drawBitmap:绘制贴图
Su易做图ceView对象
Su易做图ceHolder.Callback
Thread:线程让画面动起来
二、层的概念
学习photoshop的朋友肯定都知道层的概念,用通俗的话来说,层就是一个透明的玻璃纸。在android游戏中层的概念跟photoshop中也很相似,它可以用来呈现文字、图片等元素。游戏中一般都会有很多层组成,每个层中会有不同的元素,而且每个层中的元素是独立可控的。比如:在打飞机游戏中,背景是一层,玩家飞机是一层,敌机也是一层。大家要注意:层是有层次关系的,上面层会覆盖下面的层。那么,在打飞机游戏中,背景肯定是最里面一层,其他任何游戏元素都呈现在背景的上面。
另外有一点要跟大家特别讲一下,就是关于图片素材问题,我们都知道图片都是正规的矩形,而且有背景,所以在场景中肯定会有颜色块,看起来很不逼真。但是PNG格式的图片是可以做成透明背景,这样就解决这个问题,这也就是为什么android的图片素材基本上都是PNG格式的原因。
文字层:显示文字内容的层
贴图层:显示图片元素的层
但是,常常文字层和贴图层分的不是很清楚,文字层也可以绘制贴图,贴图层也可以绘制文字。
三、View对象
在普通的应用开发中似乎很难直接接触到View类,但实际上几乎所有的Android显示组件都是继承View类,TextView, EidtView, ImageView等等都是继承View类。开发中我们常常在XML文件中使用这些组件,但是如果要让组件具有更多独特的功能就需要自定义View类来扩展我们的需求了。
在Android游戏当中充当主要的除了控制类外就是显示类,在J2ME中我们用Display和Canvas来实现这些,而在Android中涉及到显示的为View类,Android游戏开发中比较重要和复杂的就是显示和游戏逻辑的处理。那么,我们首先研究显示的问题。
首先创建一个游戏主战场:GameView 类,并继承View类,结构如下:
[java]
package cn.zkyc.android.game;
import android.content.Context;
import android.view.View;
public class GameView extends View {
public GameView(Context context) {
super(context);
}
}
接下来我们要将上面创建的GameView类显示到手机屏幕上。需要在入口Activity中进行调用。项目创建的时候我就已经设定了一个主Activity,名称为:GameStartActivity,代码结构如下:
[java]
package cn.zkyc.android.game;
import android.app.Activity;
import android.os.Bundle;
public class GameStartActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 默认是加载XML配置文件,显示的也是XML文件中的视图组件
//setContentView(R.layout.main);
//显示自定义的View,只需要将XML文件换成自定义的View对象就即可,如下:
GameView gameView = new GameView(this);
setContentView(gameView);
}
}
运行Application,效果如下:
很遗憾,页面中除了title什么也看不到。实际上,我只是测试自定义View是否能够正确显示,只要程序没有bug,就算是成功。(请看代码中的注释)
好的,接下来我们就在View里面展现一些内容,这个时候就要用到View对象中的onDraw方法,在自定义的GameView对象中必须覆盖父类View中的onDraw方法。接下来,你想展现任何内容都可以在此方法中进行了。假如,我想在屏幕的(100,100)处绘制蓝色文字:“飞机大战”,在屏幕的(100,200)处绘制一个半径10像素的红色圆。
[java]
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画笔对象,可以控制颜色和文字大小
Paint paint = new Paint();
// 给画笔设置系统内置的颜色:蓝色
paint.setColor(Color.BLUE);
// 文字左上角的坐标为(100,100)
canvas.drawText("飞机大战",100, 100, paint);
//将画笔颜色调成红色
paint.setColor(Color.RED);
// 圆心点坐标为(100,200)
canvas.drawCircle(100, 200, 10, paint);
}
运行效果如下图:
到目前为止,你已经可以在自定义的GameView中绘制文字和各种图形了,但游戏中都是大量的图片素材,对于图片如何绘制呢?也很简单,Canvas类也提供了相应的drawBitmap方法。现在,我来绘制屏幕的(100,300)处绘制一个飞机图片。只需要在ondraw方法中添加如下代码即可:
[java]
//加载资源图片图片
Bitmap heroBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hero1);
// 在(100,300)处绘制图片
canvas.drawBitmap(heroBitmap, 100, 300, paint);
运行效果如下图:
对于代码中还有Canvas和Paint两个类没有细讲,我们可以这样打个比方吧,假如Canvas是一个画家,那么Paint就是画家手中的笔。画家能够画出各种景象(文字,形状,贴图等等),就要用到不同的画笔和不同的颜色。通过画笔类Paint就可以调整颜色,字体样式,字体大小等等。
我们发现绘制贴图canvas.drawBitmap(heroBitmap, 100, 300, paint);也会用到paint对象,但实际上paint起到的作用不大,我们完全可以忽略。
这种写法也是对的:canvas.drawBitmap(heroBitmap, 100, 300, null);
具体的用法代码里面已经有了,我就不再多说了,大家可以亲自查询下Android SDK API。
四、Thread:让画面动起来
上面我们已经实现了自定义的View中绘制了文字、形状和贴图,但是一切都是静止的,跟游戏还差的很远,意义不是很大。那么,接下来我就带着大家一起来让画面动起来。
实现这个目标,我们需要用到一个在游戏开发中非常重要的机制,就是多线程机制。具体多线程实现方式,不是我们现在讨论的问题,如果还不是很明白就需要自己补补线程方面的知识了。
在这里我们采用GameView类直接实现Runnable接口的方式:
[java]
public class GameView extends View implements Runnable { }
默认必须实现run方法:
[java]
public void run() {
while(true){
// 不断的调用View中的postInvalidate方法,让界面重新绘制
this.postInvalidate();
try {
// 暂停0.5秒继续