本篇博客适合给初学安卓,熟悉基本的JAVA语法,并希望用安卓写个小游戏的初学者参考,因为博主也因大学课程需要,是在2个星期内自学的JAVA和安卓开发,可能会有一些错误和需要优化的地方,望指出
我在这2个星期内看的书为《JAVA核心技术卷I》和李华明写的《Android游戏编程之从零开始》,有些内容是借鉴书上而来。
《Android游戏编程之从零开始》的电子版
链接:http://pan.baidu.com/s/1c1TIB9e 密码:7vfo,仅供参考
游戏的试玩视频
http://www.tudou.com/programs/view/UKRBOUnQtAM/
首先简单介绍一下游戏实现的原理,具体可以看电子书的第四章,介绍比较详细:对玩家来说,游戏是动态的;对于游戏开发人员来说,游戏是静态的,只是在不停的播放不同的画面,让玩家看到了动画的效果。 所有游戏元素都是通过画笔“画”在画布上,并且有自己的逻辑。然后通过线程不断刷新这个画布,处理逻辑,最后形成游戏画面。
刷屏方式:对于SurfaceView类,每次绘图前,需用lockCanvas()函数获取Canvas,同时对获取的Canvas画布进行加锁,防止在SurfaceView在绘制过程中被修改、摧毁等发生的改变;与此同时,还有一个unlockCancasAndPose(Canvas canvas)函数用于解锁画布和提交。
线程:在游戏中,基本上不会等用户每次触发了按键事件、触屏时间才会去重绘画布,而是会固定一个时间去刷新画布;所以在游戏开发中,都会有一个线程不停的去重绘画布,实时的更新游戏元素的状态。除了画布直接展示给玩家的之外,怪物的AI,一些其他元素的逻辑也需要用线程刷新。
接下来进入游戏开发,首先设置横屏游戏跟全屏显示,新建类MySurfaceView。
在AndroidMainifest.xml文件的activity框架下添加android:screenOrientation="landscape">(landscape表示横屏,portrait为竖屏)
MainActivity中代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏标题栏,实现全屏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//显示MySurfaceView
setContentView(new MySurfaceView(this));
}
}
对于SurfaceView类框架,首先新建一个类,本例为MySurfaceView,此类继承SurefaceView,实现SurfaceHolder.Callback接口和Runnable接口,需要重写surfaceCreated(),surfaceChanged()和surfaceDestroyed()三个视图响应函数,同时需要在框架里需要添加绘图函数,逻辑函数和线程。最后考虑到游戏有4种游戏状态,分别为GAMING,GAME_MENU,GAME_WIN,GAME_LOSE,需要对状态进行检测,来处理游戏逻辑。具体代码如下:
public class MySurfaceView extends SurfaceView implements Callback,Runnable, SurfaceHolder.Callback {
private SurfaceHolder sfh;//声明类
private Paint pt;
private Thread th;//声明一条线程
private boolean flag;//线程消失标志位
private Canvas cvs;
private Resources res = this.getResources();
public static int screenW, screenH;
public static final int GAME_MENU = 0; //游戏菜单
public static final int GAMEING = 1; //游戏中
public static final int GAME_WIN = 2; //胜利
public static final int GAME_LOST = 3; //失败
public static int gameState //游戏状态
public MySurfaceView(MainActivity mainActivity) {
super(mainActivity);
sfh = this.getHolder();//实例化SurfaceHolder
sfh.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);//获得焦点
pt = new Paint();//实例化画笔
}
//视图创建
@Override
public void surfaceCreated(SurfaceHolder holder) {
screenW = this.getWidth();//读取屏幕的宽
screenH = this.getHeight();//读取屏幕的高
flag = true; //线程允许标志位
gameState = GAME_MENU; //开始游戏状态为菜单
th = new Thread(this); //实例化线程
th.start();//启动线程
initGae(); //游戏初始化
}
//初始化函数,用于游戏开始时加载各种游戏资源
private void initGame() {…}
//绘图函数,当SurfaceView不可创建时,调用lockCanvas()返回null;Canvas进行绘图的时候会产生不可预知的错误,所以要对绘图函数进行try…catch处理。绘图的时候可能会出现BUG,虽然使用try语句包起来了,但是一旦在提交画布函数之前出错,下次lockCanvas会出错,所以解锁提交应放在finally里
public void myDraw() {
try {
cvs = sfh.lockCanvas();
if (cvs != null) {
//黑色背景色
cvs.drawRGB(0, 0, 0);
switch (gameState) {
case GAME_MENU:
break;
case GAMEING:
break;
case GAME_WIN:
break;
case GAME_LOST:
break;
}catch (Exception e) {
} finally {
if (cvs != null)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//触屏事件监听
public boolean onTouchEvent(MotionEvent event) {
switch (gameState) {
case GAME_MENU:
break;
case GAMEING:
break;
case GAME_WIN:
break;
case GAME_LOST:
break;
}
//逻辑函数
private void logic() {
switch (gameState) {
case GAME_MENU:
break;
case GAMEING:
break;
case GAME_WIN:
break;
case GAME_LOST:
break;
}
//线程
public void run() {
while (flag) {
long start = System.currentTimeMillis();
myDraw();
logic();
long end = System.currentTimeMillis();
try {
if (end - start < 50) {
Thread.sleep(50 - (end - start)); //此ceHoldrholde目, 的为设定游戏刷新时间为50ms
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {…}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false;// 销毁线程,防现异常
以上就是我创建的参考书里的SurfaceView类的框架,接下去就需要我们往框架里添加相应对象来实现游戏具体功能了。我会在接下去几篇文章里讲解和实现我自己创建的本游戏的对象。