android:怎样用一天时间,写出“飞机大战”这种游戏!(无框架-SurfaceView绘制)

序言
作为一个android开发人员,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的“飞机大战”的.

体验地址:http://www.wandoujia.com/apps/edu.njupt.zhb.planegame

源码:https://github.com/nuptboyzhb/newplanegame

游戏分析

玩过“飞机大战”游戏的都知道,飞机大战中的主要“角色”有:
1.玩家飞机
2.敌方飞机
3.玩家飞机发送的子弹
4.敌方Boss飞机发送的子弹
我们须要控制的有
1.绘制屏幕内的角色
2.控制角色的逻辑。比方:敌方飞机与我方飞机的碰撞检測,我方飞机发射的子弹与敌方飞机之间的碰撞检測,敌方Boss飞机发射的子弹与我方飞机直接的碰撞检測等等。
资源:
要完毕一个游戏,还要有资源的载入。比方飞机,子弹等图片的载入等,音效的载入。
游戏背景的绘制
事实上是一张图,这张图能够首尾相接。也即是“卷轴”,原理就是卡马克卷轴算法的原理。
以下分析代码区

事实上,抛开android平台,不论什么一个平台,做这样一个游戏。都须要这些逻辑。针对android平台。我们看一下,SurfaceView的绘制框架。

直接贴代码:

package edu.njupt.zhb.game.view;

/**
 *
 * @author Zheng Haibo
 * @webset: http://www.mobctrl.net
 * @android开发联盟QQ群:272209595
 */
public class PlaneView extends SurfaceView implements Callback, Runnable {

	private SurfaceHolder surfaceHolder;
	private long sleep_time = 16;//绘制周期
	private int screenHeight;
	private int screenWidth;
	private Thread thread;
	private Canvas canvas;
	private Paint paint;
	private GameScreen currentScreen;
	private int level = 0;
	private int backgroundSpeed = 1;

	public PlaneView(Context context) {
		super(context);
		System.out.println("debug:PlaneView()");
		surfaceHolder = this.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setDither(true);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		System.out.println("debug:surfaceCreated");
		setZOrderOnTop(false);
		isGameOver = false;
		if (isPause) {
			return;
		}
		screenHeight = this.getHeight();
		screenWidth = this.getWidth();
		initPlane();
		thread = new Thread(this);
		thread.start();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		System.out.println("debug:surfaceChanged");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		System.out.println("debug:surfaceDestroyed");
		if (lift > 0) {
			planeViewCallback.onGamePause();
		}
		isPause = true;
	}

	@Override
	public void run() {
		while (!isGameOver) {//控制绘制周期
			if (isPause) {
				try {
					Thread.sleep(sleep_time);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				continue;
			}
			long starttime = System.currentTimeMillis();
			drawScreen();
			long time = System.currentTimeMillis() - starttime;
			if (time < sleep_time) {
				try {
					Thread.sleep(sleep_time - time);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 绘制场景
	 */
	private void drawScreen() {
		canvas = surfaceHolder.lockCanvas();
		if (null == canvas) {
			return;
		}
		//清除
		canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
		paint.setAlpha(255);
		gameLogic();
		gameDraw();
		if (null != canvas) {
			surfaceHolder.unlockCanvasAndPost(canvas);
		}
	}

	/**
	 * 游戏逻辑
	 */
	private void gameLogic() {
		//TO DO 控制游戏逻辑
		...
	}

	private void gameDraw() {
	    //先绘制游戏背景
		drawBackground(backgroundSpeed * frameSeq);
		if (currentScreen == GameScreen.NORMAL) {
			synchronized (planes) {
				drawPlanes();
				drawBullets();
				drawMasterPlane();
			}
		} else if (currentScreen == GameScreen.BOSS) {
			drawBullets();
			drawBossPlane();
			drawBossBullets();
			drawMasterPlane();
		}
	}

	private void drawBossPlane() {
		if (null != bossPlane) {
			if (bossPlane.isClicked()) {// draw blast img
				bossPlane.onBlastDraw(canvas, paint);
				if (bossPlane.isBlastFrameEnd()) {
					bossPlane.setClicked(false);
				}
			}
			bossPlane.onDraw(canvas, paint);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		System.out.println("debug:onDraw");
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		System.out.println("debug:onDetachedFromWindow...");
		isPause = false;
		isGameOver = true;
		//释放资源
		for (PlaneRes plane : planesRes) {
			plane.getBitmap().recycle();
		}
		for (BulletRes bulletRes : bulletsRes) {
			bulletRes.getBitmap().recycle();
		}
	}

	/**
	* 用户交互
	*/
	@Override
	public boolean onTouchEvent(MotionEvent e) {
		int x = (int) e.getX();
		int y = (int) e.getY();
		switch (e.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if (masterPlane.isContainPoint(x, y)) {
				isMove = true;
			}
			break;
		case MotionEvent.ACTION_MOVE:
			if (isMove) {
				synchronized (masterPlane) {
					masterPlane.updatePosition(x, y);//控制玩家飞机的移动
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			isMove = false;
			break;
		}
		return true;
	}
}

对于背景的绘制。事实上是循环绘制一张图:本游戏的绘制逻辑:

private void drawBackground(int yOffset) {
		yOffset %= screenHeight;
		if (yOffset == 0) {
			canvas.drawBitmap(backgroundBmp, 0, 0, paint);
		} else {
			canvas.drawBitmap(backgroundBmp, new Rect(0,
					screenHeight - yOffset, screenWidth, screenHeight),
					new Rect(0, 0, screenWidth, yOffset + 1), paint);
			canvas.drawBitmap(backgroundBmp, new Rect(0, 0, screenWidth,
					screenHeight - yOffset), new Rect(0, yOffset, screenWidth,
					screenHeight), paint);
		}
	}

然后,我们仅仅须要在一个布局上,将PlaneView加入进去就可以:

如:

planeView = new PlaneView(this);
		planeView.setPlaneViewCallback(this);
		planeView.setGameOverCallback(this);
		planeView.isMediaOpen = this.isMediaOpen;
		LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT);
		rl_plane.addView(planeView, lp);

未完待续。

。。

时间: 2024-12-24 19:59:32

android:怎样用一天时间,写出“飞机大战”这种游戏!(无框架-SurfaceView绘制)的相关文章

android:如何用一天时间,写出“飞机大战”这样的游戏!(无框架-SurfaceView绘制)

序言作为一个android开发者,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的"飞机大战"的.体验地址:http://www.wandoujia.com/apps/edu.njupt.zhb.planegame游戏分析玩过"飞机大战"游戏的都知道,飞机大战中的主要"角色"有:1.玩家飞机2.敌方飞机3.玩家飞机发送的子弹4.敌方Boss飞机发送的子弹我们需要控制的有:1.绘制屏幕内的角色2.控制角色的逻辑,比如:敌方

为什么要使用MVC模式,MVC模式的优势有哪些?请写出你熟悉的MVC轻量级框架名称。

MVC就是常说的:模型(Model),视图(View)和控制Controller) 它把业务处理和Jsp页面分开了.而以前的Jsp页面是把所有的代码都写在Jsp页面中,那样不利于维护 MVC模式的目的就是实现Web系统的职能分工. MVC模式的好处: 1.各施其职,互不干涉 在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码. 2.有利于开发中的分工 在MVC模式中,由于按层把系统分开,那么就能更好的实现开发中的分工.网页设

500行代码,教你用python写个微信飞机大战

这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手. 帮助蹲厕族.YP族.饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右手有节奏有韵律的朝着同一个方向来回移动起来! 这是史诗级的发明,是浓墨重彩的一笔,是-- 在一阵抽搐后,我结束了游戏,瞬时觉得一切都索然无味,正在我进入贤者模式时,突然想到,如果我可以让更多人已不同的方式体会到这种美轮美奂的感觉岂不美哉? 所以我打开电脑,创建了一个 plan_game.py-- 先

不要把时间浪费在写出完美的代码

一个系统可能会持续工作5年,10年,20年甚至更长的时间.但是具体到这个系统中的某一行代码,即使是关于设计的部分,这一行代码存在的时间却会很短:几个月或者几天,甚至是几分钟. 一些代码比其他代码更重要 通过研究代码是怎么随时间改变的,Michael Feathers定义了一条代码变动曲线.每个系统都有很多写完之后就不再改变的代码.与此同时,也存在少量这样的代码,这些代码是整个系统最重要也是最有用的代码,它们会随时间一次又一次地改变.重构,或者被删除,重新来过,如是反复几次. 随着你对一个系统越来

学会写出"图形界面+数据库"的程序要多长时间?

[来信] 贺老师好,我也是在自学c++看了您写的启蒙一,感触很大,太谢谢了,我现在做网络运维,会接触到部份erp的内容,,想请老师指点下.从刚开始学c++到能写出个图形化界面并与数据库简单交互的,这样一个小程序,如果不考虑数据库方面的问题,正常要用多长时间,,? [回复] 第一个时间问题,我觉得是因人而异的.这要看个人以前的积累,以及学习能力.所以我无法为你做的估计,事实上,这确实因人而异. 我昨天在手机上看到你的私信时,想到的就是这些.今天开电脑要回复了,想想这是个很有意思的问题,多说一点.

代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

告诉你一些简单的技巧来优化JavaScript编译器工作,从而让你的JavaScript代码运行的更快.尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候. 单一同态: 当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型.个数或者返回值的类型改变编译器的工作会变得艰难.通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作. function example(a, b) { // 期望a,b都为数值类型 console.log(++a * +

从零开始--系统深入学习android(实践-让我们开始写代码-Android框架学习-7.通知)

通知 一个通知是一条消息他是显示于你应用程序之外的一个界面中.当你告诉系统要发布一个通知时,它首先作为一个icon出现在通知区域.为了看见通知的细节,用户可以点击通知区域展开一个新的界面.下面让我们来看一下图7-1和图7-2: 图7-1 通知出现在通知区域 图7-2 通知展开后的效果(drawer) 注意:除非特别注明外,本章指的都是NotificationCompat.Builder,它在v4 Support Library中有,正式添加于API Level 15.但有了v4 Support

【转】Android开发笔记(序)写在前面的目录

原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入门上:其次是想拾缺补漏,写写虽然小众却又用得着的东西:另外就是想以实用为主,不求大而全,但求小而精:还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来.个人的经

如何写出优雅的CSS代码 ?(转)

对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于团队合作和后期的维护:而有的混乱,虽然表达出了最终的效果,然而却晦涩难懂,显然团队成员在读这样的代码时就显得无从下手,更不利于后期的维护了.那么如何写出优雅的代码呢?下面我将以一个很小的项目就以下几个方面简单的表达一下自己的看法,如有不妥,望批评指正. 如何整理一个项目. 如何写出清晰易懂的HTML代码. 如何写出优雅的css代