资源描述
石家庄科技信息职业学院
毕 业 论 文
题 目: 基 于 Android 平 台 的 游 戏设 计——太 空 保 卫 战
学 号: 0 9 0 1 2 4 0 1 6
姓 名: 宋少伟
专业班级: 游戏开发
指导教师: 刘永伟
完成日期: 2011年12月 16 日
太 空 保 卫 战
摘要:Android是Google公司为首的OHA研发的一个开源智能手机平台。随着互联网和物联网的广泛应用,得到了学术界和产业界的支持,越来越多的创意应用到Android应用程序中,席卷了整个手机产业。
近来随着手机的快速发展,各种各样的手机游戏层出不穷,使得我们能有更多的娱乐项目,而射击类游戏是节奏比较快,要求玩家通过快速的反应与游戏进行交互,从而考验玩家的灵敏度以及放松玩家大脑,是玩家身心休闲娱乐
太空保卫战便是运行在Android上的一种滚屏动作类游戏,其中融入了很多动作类游戏特有的技术,且画面流畅、声音震撼。
关键词: Android应用程序 J2ME Plane类 EnemyPlane类 Bullet类
Too empty and defend war
Abstract:Android is Google company headed by OHA research and development of an open source platform of intelligent mobile phone. With the advent of the Internet and networking applications, obtained the academic and industry support, more and more creative application to the Android application, swept the whole of mobile phone industry.
Recently with the rapid development of mobile phone, all kinds of mobile phone game emerge in an endless stream, so that we can have more entertainment projects, while shooting game is relatively fast pace, for game player through rapid response and games to interact, so as to test the sensitivity of game player and relaxed game player brain, mental and physical recreation is game player
Space war is run in the Android on a scrolling action games, which incorporates many action games unique technology, and smooth picture, sound rock.
Key words: Android application J2ME class Plane class EnemyPlane class Bullet
目 录
一、引言 ……………………………………………………………3
(一)课题背景 ……………………………………………………3
(二)本课题研究的意义 …………………………………………3
(三) 本课题的研究方法 ………………………………………3
二、课题相关基础 …………………………………………………4
(一) 游戏情节 …………………………………………………4
(二)功能介绍 ……………………………………………………4
(三) 目标平台 ……………………………………………………7
三、设计方案 ………………………………………………………8
(一)游戏的架构jagou …………………………………………………8
(二)游戏的框架简介图 …………………………………………9
(三)游戏界面基本框架及介绍 …………………………………10
(四) 游戏总流程图 ………………………………………………11si
(五)游戏实体相关类的实现 ……………………………………11
1、飞机Plane类的实现 …………………………………………11.
2、敌机EnemyPlane类的实现……………………………………19
3、子弹Bullet类的实现…………………………………………24
四i2棋盘和棋子 、结论 ……………………………………………………………27
参考文献 ……………………………………………………………28
- 29 -
正 文
一、引言
(一)课题背景
Android是Google公司为首的OHA研发的一个开源智能手机平台。随着互联网和物联网的广泛应用,得到了学术界和产业界的支持,越来越多的创意应用到Android应用程序中,席卷了整个手机产业。
随着Android游戏的普及,Android应用的需求势必会越来越大。并且Android相对于其他的手机操作系统具有开放、平等、无界限、方便以及硬件丰富性等的特性。这将是一个潜力巨大的市场会吸引无数软件开发商和开发者投身其中。
太空保卫战便是运行在Android上的一种滚屏动作类游戏,其中融入了很多动作类游戏特有的技术,且画面流畅、声音震撼。
(二)本课题研究的意义
近来随着手机的快速发展,各种各样的手机游戏层出不穷,使得我们能有更多的娱乐项目,而射击类游戏是节奏比较快,要求玩家通过快速的反应与游戏进行交互,从而考验玩家的灵敏度以及放松玩家大脑,是玩家身心休闲娱乐。
当今市面上流行的手机游戏类型繁多,不同类型的游戏自然有其独特的设计方式以及独到的吸引玩家的地方,射击类游戏(Shooting Game)是一种比较古老的游戏类型手机游戏中的射击游戏也很流行,目前市面上的射击类游戏最多的是飞行射击游戏。
太空保卫战就是属于飞行射击类游戏,是滚屏动作类游戏的一种。而滚屏动作类游戏是最传统的游戏类型之一,早期动作游戏的画面一般比较简单,没有复杂的游戏特效,主要是通过熟练操作技巧来进行游戏,一般是为了通关。而现在的动作类游戏则融入了很多新的元素,很多经典的关卡以及很多画面的特效,使其逐渐成为所有游戏类型里面款式最多,发展最快的一种。
(三) 本课题的研究方法
相对于其他相同类型的游戏进行,提取其精华技术,并且融入较多新的元素。运用平台Android2.1、Eclipse开发软件,使用Java进行语言开发,并且采用2D的呈现技术,是玩家玩得更加刺激震撼。并且游戏的添加上成绩排行功能,并将玩家的最好成绩保存下来,会大大提高游戏的可玩性。
二、课题相关基础
(一) 游戏情节:
本游戏是一款滚屏动作游戏,没有过多的情景设计。所以主要的工作是主战飞机生命的设计(血值或生命值)、道具的设计(换枪的道具及补血的道具)、关卡的设计等。此游戏还融入了很多动作类游戏特有的技术,使得画面流畅、声音震撼。游戏操作简单,易于上手,且火爆的游戏场面,快速、激烈、紧张的游戏节奏会使玩家产生浓厚兴趣。
(二)功能介绍
太空保卫战游戏主要包含欢迎界面、帮助界面以及游戏界面。下面对该游戏的部分界面及运行效果进行简单的介绍:
1、运行该游戏,通过Ctrl+F12组合键将模拟器调成横屏,进入加载界面。
图1 游戏的加载界面
2、之后将进入欢迎动画界面。
图2 游戏的欢迎动画1
图3 游戏的欢迎动画2
图3 游戏的欢迎界面3
3、欢迎动画播放完毕将进入选择界面,菜单界面包括“开始游戏”、“帮助”、“关闭声音”及“退出”按钮。
图4 选择界面
4、单击“帮助”按钮将进入“帮助”界面。
图5 帮助界面
5、单击’开始游戏“按钮将进入游戏界面,在游戏界面中,玩家可通过上下左右键控制飞机移动,然后A键发射子弹打击敌人。
图6 游戏界面
8、如果玩家飞机坚持足够的时间没有爆炸的话,将看到关底。
7、当顺利过关时,会出现恭喜过关界面;当游戏失败时,则会出现失败界面。
图7 游戏失败界面
(三)目标平台:
目标平台为Android2.1 。
开发语言:Java
开发软件:Eclipse
三、设计方案
(一)游戏的架构
该项目中的类分成了4部分进行介绍
1 共有类
Activitv的实现类PlaneActivity:该类是通过扩展基类Activity实现的,是整个游戏程序的入口。
键盘监听线程KeyThread:该类为手机键盘的监听线程,没隔一段时间读取一次键盘的状态值,并根据当前键盘状态做出相应的操作。
常量类ConstantUtil:将游戏中用到的所有常量全部封装到该类中,便于管理与维护。
2 辅助界面相关类
欢迎界面WelcomeView:该类为游戏欢迎界面的实现类,主要负责欢迎界面的绘制工作。
欢迎界面的动画实现类WelcomeViewThread:该类是为WelcomeView服务的线程类,主要负责欢迎界面中动画的生成。
帮助界面HelpView:该类非常简单,主要负责绘制帮助界面的相关图片。
加载界面ProcessView:为了使游戏更加人性化,给玩家更好的体验,在长时间加载某些资源时,需要给出加载界面以提示玩家后台加载进度。
胜利界面WinView:该类为玩家顺利谷关后的恭喜过关界面。
失败界面FailView:该类为主战飞机死亡后显示的失败界面,在该界面中玩家可以选着重新游戏或退住游戏。
3 游戏界面相关类
游戏主界面类GameView:该类为游戏菜单界面的实现类,负责界面绘制工作。
背景滚动线程类GameViewBackGroundThread:该类主要负责背景滚动、敌机以及各种道具的出现。
地图信息类Maps:该类包含着地图的相关信息,例如敌机所有的移动路线、各个关卡中补血道具、换枪道具等。
物体移动线程类MoveThread:该线程负责除了我方主站飞机外所有可移动物的移动
4 情景相关类
主战飞机Plane:该类为主战飞机的封装类,可有玩家控制其芳香以及移动状态。
敌机EnenyPlane:该类为敌机的封装类。
子弹类Bullet:子弹的封装类,游戏中所有的子弹都为该类的对象。
爆炸效果类Explode:该类为爆炸效果的渲染类,负责在指定位置绘制爆炸效果。
爆炸换帧线程ExplodeThread:该类是为爆炸效果服务的。当爆炸存在时,定时为每个爆炸效果换帧。
补血道具类life:该类是补血道具类,当主战飞机与该类的对象碰撞时,会为主站飞机增加一格血。
换枪道具类ChangeBullet:该类为换枪道具类,当主战飞机与该类的对象碰撞时,会增加主战飞机所携带武器。
(二)游戏的框架简介图
图1 太空保卫战游戏类框架图
1、启动游戏,在PlaneActivity中会先进入家在界面ProcessView,然后后台加载欢迎界面WelcomeView,当加载完成后将屏幕切换到欢迎界面,并启动WelcomeViewThread线程生成欢迎界面的动画效果。
2、当欢迎动画播放完毕后屏幕会停留在选择状态等待玩家操作。
3、当玩家点击“帮助”按钮时,将初始化帮助界面HelpView并将其显示出来。
4、当玩家单击“开始游戏”按钮时,屏幕将显示加载界面。后台将初始化游戏界面GameView,在地图信息类Maps中初始化此关卡中所有敌机、变枪的道具、补血的道具等。
5、初始化游戏界面的同时启动GameViewBackGroundThread线程,以滚动游戏界面的背景图片。
6、当玩家发射炮弹或敌机发射炮弹时会创建炮弹类Bullet的对象,并将其添加到已知的容器中。
7、当游戏过程中如果需要显示爆炸效果,会创建爆炸效果类Explode以及ExplodeThread类来渲染爆炸效果。
8、游戏中所有类中使用的常量全部封装到常量类ConstantUtil类中。
(三)游戏界面基本框架及介绍
图2 游戏界面基本框架
1、GameView在初始化时会从Maps读取当前关卡的地图信息,包括敌机、补血道具、换枪道具等。
2、在界面初始化的同时,还需要启动MoveThread线程、GameViewBackGroundThread线程、KeyThread线程及ExplodeThread线程。
3、GameView会在适当的时候从Plane类读取主战飞机的信息进行绘制。
4、当主战飞机发射子弹时,会创建Buller对象并添加到指定容器中,此时MoveThread同样需要定时改变子弹对象的位置。
5、在以上过程中,全部需要PlaneActivity的管理与ConstantUtil的参与。
(四)游戏总流程图
(五)游戏实体相关类的实现
1、飞机Plane类的实现,其代码如下:
package wyf.ytl;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Message;
public class Plane {
private int x;//飞机的坐标
private int y;
int life;//生命
private int dir;//飞机的方向,0静止,1上,2右上,3右,4右下,5下,6左下,7左,8左上
private int type;//飞机的类型
Bitmap bitmap1;//当前向下飞机的图片
Bitmap bitmap2;//当前向上飞机的图片
Bitmap bitmap3;//当前飞机的图片
GameView gameView;//GameView的引用
private int span = 10;//飞机走一步的像素
int bulletType = 1;
public Plane(int x, int y, int type, int dir,int life, GameView gameView){
this.gameView = gameView;
this.x = x;
this.y = y;
this.type = type;
this.dir = dir;
this.life = life;
initBitmap();
}
public void initBitmap(){
if(type == 1){//当类型为1时
bitmap1 = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.plane1);
bitmap2 = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.plane2);
bitmap3 = BitmapFactory.decodeResource(gameView.getResources(), R.drawable.plane3);
}
}
public void draw(Canvas canvas){
if(dir == ConstantUtil.DIR_UP){//向上
canvas.drawBitmap(bitmap2, x, y,new Paint());
}
else if(dir == ConstantUtil.DIR_DOWN){//向下
canvas.drawBitmap(bitmap1, x, y,new Paint());
}
else{//其他情况使用的图片
canvas.drawBitmap(bitmap3, x, y,new Paint());
}
}
public void fire(){//打子弹的方法
if(bulletType == 1){
Bullet b = new Bullet(this.x+75, this.y+8, 1, ConstantUtil.DIR_RIGHT,gameView);
gameView.goodBollets.add(b);
}
else if(bulletType == 2){
Bullet b = new Bullet(this.x+75, this.y+4, 3, ConstantUtil.DIR_RIGHT,gameView);
gameView.goodBollets.add(b);
}
else {
Bullet b = new Bullet(this.x+75, this.y+4, 3, ConstantUtil.DIR_RIGHT,gameView);
gameView.goodBollets.add(b);
Bullet b2 = new Bullet(this.x+55, this.y-4, 4, ConstantUtil.DIR_RIGHT_UP,gameView);
gameView.goodBollets.add(b2);
Bullet b3 = new Bullet(this.x+55, this.y+12, 5, ConstantUtil.DIR_RIGHT_DOWN,gameView);
gameView.goodBollets.add(b3);
}
if(gameView.activity.isSound){
gameView.playSound(1,0);//播放音乐
}
}
public boolean contain(Bullet b){
if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())){//检测成功
this.life--;//自己的生命减1
if(this.life<0){//当生命小于0时
gameView.status = 2;
if(gameView.mMediaPlayer.isPlaying()){
gameView.mMediaPlayer.stop();
}
if(gameView.activity.isSound){
gameView.playSound(3,0);
}
Message msg1 = gameView.activity.myHandler.obtainMessage(1);
gameView.activity.myHandler.sendMessage(msg1);//向主activity发送Handler消息
}
return true;
}
return false;
}
public boolean contain(ChangeBullet cb){
if(isContain(cb.x, cb.y, cb.bitmap.getWidth(), cb.bitmap.getHeight())){//检测成功
this.bulletType += 1;
return true;
}
return false;
}
public boolean contain(EnemyPlane ep){
if(isContain(ep.x, ep.y, ep.bitmap.getWidth(), ep.bitmap.getHeight())){//检测成功
this.life--;//自己的生命减1
if(this.life<0){//当生命小于0时
gameView.status = 2;
if(gameView.mMediaPlayer.isPlaying()){
gameView.mMediaPlayer.stop();
}
if(gameView.activity.isSound){
gameView.playSound(3,0);
}
gameView.activity.myHandler.sendEmptyMessage(1);//向主activity发送Handler消息
}
return true;
}
return false;
}
public boolean contain(Life l){//检测玩家飞机是否撞血块
if(isContain(l.x, l.y, l.bitmap.getWidth(), l.bitmap.getHeight())){//检测成功
if(this.life<ConstantUtil.life){
this.life++;//生命加一
}
return true;
}
return false;
}
private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight){//判断两个矩形是否碰撞
int xd = 0;//大的x
int yd = 0;//大大y
int xx = 0;//小的x
int yx = 0;//小的y
int width = 0;
int height = 0;
boolean xFlag = true;//玩家飞机x是否在前
boolean yFlag = true;//玩家飞机y是否在前
if(this.x >= otherX){
xd = this.x;
xx = otherX;
xFlag = false;
}else{
xd = otherX;
xx = this.x;
xFlag = true;
}
if(this.y >= otherY){
yd = this.y;
yx = otherY;
yFlag = false;
}else{
yd = otherY;
yx = this.y;
yFlag = true;
}
if(xFlag == true){
width = this.bitmap1.getWidth();
}else {
width = otherWidth;
}
if(yFlag == true){
height = this.bitmap1.getHeight();
}else{
height = otherHeight;
}
if(xd>=xx&&xd<=xx+width-1&&
yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠
double Dwidth=width-xd+xx; //重叠区域宽度
double Dheight=height-yd+yx; //重叠区域高度
if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞
return true;
}
}
return false;
}
public void setDir(int dir){
this.dir = dir;
}
public int getSpan(){
return span;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
if(this.y < 0){
this.y = 0;
}
if(this.y > ConstantUtil.screenHeight){
this.y = ConstantUtil.screenHeight;
}
}
}
2、敌机EnemyPlane类的实现,其代码如下:
package wyf.ytl;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Message;
public class EnemyPlane {
int x = ConstantUtil.screenWidth;//飞机的坐标
int y;
boolean status;//飞机的状态
long touchPoint;//触发点
int type;//飞机的类型
int life;//生命
int spanX = 10;//飞机移动的X像素
int spanY = 5;//飞机移动的X像素
Bitmap bitmap;
int start;//当前出发点
int target;//当前目标点
int step;//当前处于当前路径片段中第几步
int[][] path;
public EnemyPlane(int start,int target,int step,int[][] path, boolean status,long touchPoint, int type, int life){
this.start=start;
this.target=target;
this.step=step;
this.path=path;
this.status = status;
this.touchPoint = touchPoint;
this.type = type;
this.life = life;
this.x=path[0][start];
this.y=path[1][start];
}
public void draw(Canvas canvas){
canvas.drawBitmap(bitmap, x, y, new Paint());
}
public void move(){
if(step==path[2][start]){//一段路径走完,到下一段路径开始
step=0;
start=(start+1)%(path[0].length);
target=(target+1)%(path[0].length);
this.x=path[0][start];
this.y=path[1][start];
}else{//一段路径没有走完,继续走
int xSpan=(path[0][target]-path[0][start])/path[2][start];
int ySpan=(path[1][target]-path[1][start])/path[2][start];
this.x=this.x+xSpan;
this.y=this.y+ySpan;
step++;
}
}
public void fire(GameView gameView){//打子弹的方法
if(type == 3 && Math.random()<ConstantUtil.BooletSpan2){
Bullet b1 = new Bullet(x, y, 2, ConstantUtil.DIR_LEFT,gameView);
Bullet b2 = new Bullet(x, y, 2, ConstantUtil.DIR_LEFT_DOWN,gameView);
Bullet b3 = new Bullet(x, y, 2, ConstantUtil.DIR_LEFT_UP,gameView);
gameView.badBollets.add(b1);
gameView.badBollets.add(b2);
gameView.badBollets.add(b3);
}else if(Math.random()<ConstantUtil.BooletSpan){
if(this.type == 4){
Bullet b = new Bullet(x, y, 2, ConstantUtil.DIR_RIGHT,gameView);
gameView.badBollets.add(b);
}else{
Bullet b = new Bullet(x, y, 2, ConstantUtil.DIR_LEFT,gameView);
gameView.badBollets.add(b);
}
}
}
private boolean isContain(int otherX, int otherY, int otherWidth, int otherHeight){//判断两个矩形是否碰撞
int xd = 0;//大的x
int yd = 0;//大大y
int xx = 0;//小的x
int yx = 0;//小的y
int width = 0;
int height = 0;
boolean xFlag = true;//玩家飞机x是否在前
boolean yFlag = true;//玩家飞机y是否在前
if(this.x >= otherX){
xd = this.x;
xx = otherX;
xFlag = false;
}else{
xd = otherX;
xx = this.x;
xFlag = true;
}
if(this.y >= otherY){
yd = this.y;
yx = otherY;
yFlag = false;
}else{
yd = otherY;
yx = this.y;
yFlag = true;
}
if(xFlag == true){
width = this.bitmap.getWidth();
}else{
width = otherWidth;
}
if(yFlag == true){
height = this.bitmap.getHeight();
}else{
height = otherHeight;
}
if(xd>=xx&&xd<=xx+width-1&&
yd>=yx&&yd<=yx+height-1){//首先判断两个矩形有否重叠
double Dwidth=width-xd+xx; //重叠区域宽度
double Dheight=height-yd+yx; //重叠区域高度
if(Dwidth*Dheight/(otherWidth*otherHeight)>=0.20){//重叠面积超20%则判定为碰撞
return true;
}
}
return false;
}
public boolean contain(Bullet b,GameView gameView){//判断子弹是否打中敌机
if(isContain(b.x, b.y, b.bitmap.getWidth(), b.bitmap.getHeight())){
this.life--;//自己的生命减1
if(this.life<=0){//当生命小于0时
if(gameView.activity.isSound){
gameView.playSound(2,0);
}
this.status = false;//使自己不可见
if(this.type == 3){//是关口时
gameView.status = 3;//状态换成胜利状态
if(gameView.mMediaPlayer.isPlaying()){
gameView.mMediaPlayer.stop();//将游戏背景音乐停止
}
Message msg1 = gameView.activity.myHandler.obtainMessage(5);
展开阅读全文