2024年1月24日发(作者:安璇子)
.
学姓成
.
交通运输学院
面向对象程序设计
课程设计
院 交通运输学院 班 级 信管09
名 许 文 学 号 200900820
绩 指导老师 应东
2012 年 7 月 8 日
.
交通大学交通运输学院课程设计任务书
所在系:信息管理与信息系统 课程名称:面向对象程序设计 指导教师(签名):
专业班级: 信管09 学生: 许文 学号:200900820
一、课程设计题目
基于安卓的俄罗斯方块游戏开发
二、课程设计的目的
(1)提高学生思考与分析项目的能力。
(2)提高并加强学生面向对象的编程思想。
(3)强化学生灵活的编写程序并解决问题的能力。
三、课程设计的主要容和要求(包括原始数据、技术参数、设计要求、工作量要求等)
1. 写出详细设计说明
2. 编写程序代码,调试程序使其能正确运行
3. 设计完成的软件要便于操作和使用
四、工作进度安排
本课程设计一共安排3周时间,具体如下:
第1周:完成分析与设计工作,对整个设计的功能及流程有清晰的认识;
第2周:完成开发工作;
第3周:对设计中存在的问题进行完善,完成设计报告。
.
.
五、主要参考文献
[1] 志宏.Java程序设计教程.:航空工业,2010年7月
[2] 单兴华.Java基础与案例开发详解.:清华大学,2009年9月
审核批准意见
系主任(签字) 年 月 日
指导教师评语及成绩
指
导
教
师
评
语
.
.
成
绩
导师签字:
年 月 日
目录
俄罗斯方块游戏在Android中的实现 .................................................... 1
引言 ............................................................................... 1
1游戏背景及功能概述 ................................................................ 1
1.1背景概述 .................................................................... 1
1.2游戏简介 .................................................................... 2
.
.
1.3功能概述 .................................................................... 2
1.4游戏操作方法 ................................................................ 4
2.游戏策划及准备工作................................................................ 5
2.1游戏策划 .................................................................... 5
2.2游戏开发平台 ................................................................ 6
2.3Android平台下游戏的准备工作 ................................................. 7
3.游戏构架 ......................................................................... 7
4游戏中各个类中实现的功能 .......................................................... 8
5游戏的优化与改进 .................................................................. 8
结论 ............................................................................... 9
参考文献 ........................................................................... 9
附录 ............................................................................... 9
附录文件代码 ........................................................ 9
附录文件代码 .................................................. 64
附录文件代码 ................................................ 66
附录文件代码 .......................................................... 66
附录文件代码 ............................................. 68
附录文件代码 ........................................................ 69
附录文件代码 ...................................................... 70
.
.
俄罗斯方块游戏在Android中的实现
引言
引言:简要说明设计题目的目的、意义、容、主要任务等。
俄罗斯方块原本是前联科学家阿列克•帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。
从诞生发展至今俄罗斯方块已经可以在各个平台上运行了。本次游戏的开发就是基于Android 4.0系统和传统俄罗斯方块的游戏方法进行的。
1游戏背景及功能概述
俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。
1.1背景概述
俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰.
.
动与造成的经济价值可以说是游戏史上的一件大事。这款游戏最初是由联的游戏制作人Alex Pajitnov 制作的,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。
究其历史,俄罗斯方块最早还是出现在PC机上,而我国的用户都是通过红白机了解、喜欢上它的。现在Android手机游戏的兴起又将重新掀起这股让人沉迷的俄罗斯方块风潮。对一般用户来说,它的规则简单,容易上手,且游戏过程变化无穷,而在"Android俄罗斯方块"中,更有一些Android游戏所独有的魅力――更加方便简单的操作模式,用户可在任意的地方任意时间进行游戏。
1.2游戏简介
原本是前联科学家阿列克·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。
Game Boy版的俄罗斯方块在日本卖出424万套,是Game Boy史上卖最好的游戏。海湾战争时,也是前线美军最常拿消磨时间的游戏之一。
由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。
俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。
俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。
1.3功能概述
1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为24,列高为25,以每个小正方形为单位。
2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。
I:一次最多消除四层
.
.
J(左右):最多消除三层,或消除二层
L:最多消除三层,或消除二层
O:消除一至二层
S(左右):最多二层,容易造成孔洞
Z (左右):最多二层,容易造成孔洞
T:最多二层
(1)部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。
方块会从区域上方开始缓慢继续落下。
(2)玩家可以做的操作有:以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。
(3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。
(4)当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。
(5)当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。
(6)一般来说,游戏还会提示下一个要落下的方块,熟练的玩家会计算到下一个方块,评估现在要如何进行。由于游戏能不断进行下去对商业用游戏不太理想,所以一般还会随着游戏的进行而加速提高难度。
3、通过设计者预先设置的随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。
4、如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束。
具体到每一款不同的游戏,其中的细节规则都可能有千差万别,但是以上的基本规则是相同的。
.
.
1.4游戏操作方法
1、安装apk游戏安装包,在Android手机的资源管理其中找到并点击文件选择安装。
2、点击游戏图标进入游戏界面后按键盘的"MENU"按钮,在弹出的菜单中选择“开始”来开始游戏(如图1所示)。
图1游戏开始前的界面截图
3、游戏玩家可以再游戏中采用点击“MENU”按钮来选择“暂停”、“退出”、“开始”以实现暂停、退出、重新开始功能(如图2所示)。
.
.
图2游戏中的界面截图
4、触摸屏操作:系统缺省设置使用触摸屏,用手指点击方块的左边一次左移一格(长按则快速移动到最左边);点击方块的右边一次右移一格(长按则快速移动到最右边);点击方块本身旋转方块;点击方块的下边一次向下移一格(长按则快速移动到最下边)。
5、计分牌显示的容:
“分数””为本局游戏所得的分数,一次消一行100分、2行200分、3行400分、4行800分。
“关卡”为本局游戏所在的关卡,所在的关卡越高,难度越大。
“时间”为本局游戏从开始到当前所用的时间。
2.游戏策划及准备工作
2.1游戏策划
游戏的策划是指对游戏中主要功能的实现方案进行确定的过程,大型游戏需要缜密的策划才可以开发。例如,呈现技术、目标平台等容。
游戏设计
.
.
本游戏为经典俄罗斯方块游戏,每一次消除一层加100分、2层200分、3层400分、4层800分。游戏中的方块形状都是随机生成的(共7种)。随着难度的增加方块下落的默认速度会增加,游戏分数没有上限。
呈现技术
本游戏采用的游戏背景和其他图片都是用美图秀秀软件编辑的。
目标平台
本游戏的目标平台为Android 4.0。
操作方式
游戏的操作方式为触控操作,游戏菜单的弹出是通过键盘来操作的。
2.2游戏开发平台
本次开发采用jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep_2008开发包、eclipse-SDK-3.6.2-win32开发工具、android-sdk-windows开发包。
JDK(Java Development Kit)是Sun Microsystems针对Java开发员的产品。自从Java推出以来,JDK已经成为使用最广泛的Java SDK。JDK 是整个Java的核心,包括了Java运行环境,Java工具和Java基础的类库。JDK是学好Java的第一步。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。从SUN的JDK5.0开始,提供了泛型等非常实用的功能,其版本也不断更新,运行效率得到了非常大的提高。
Eclipse(软件开发者包)是Eclipse Platform、JDT和PDE所生产的组件合并,它们可以一次下载。这些部分在一起提供了一个具有丰富特性的开发环境,允许开发者有效地建造可以无缝集成到Eclipse Platform中的工具。Eclipse SDK由Eclipse项目生产的工具和来自其它开放源代码的第三方软件组合而成。Eclipse项目生产的软件以 GPL发布,第三方组件有各自自身的许可协议。
Android SDK(Google Android专属的软件开发工具包),它是编写Android应用程序的基石。
.
.
2.3Android平台下游戏的准备工作
本游戏中用到的图片资源见表1所示。
表1游戏中所用到的图片资源及说明
图片名称
大小(kB)
0.647
0.647
0.647
0.647
0.647
0.647
0.647
0.647
0.647
7.96
7.31
像素(w*h)
24*25
24*25
24*25
24*25
24*25
24*25
24*25
24*25
24*25
140*115
522*780
用途
小方快图案
小方快图案
小方快图案
小方快图案
小方快图案
小方快图案
小方快图案
小方快图案
小方快图案
游戏图标
游戏背景
3.游戏构架
本游戏中各个模块的结构如图3所示。
.
图3游戏的总构架
.
前台表示模块主要用于游戏画面的渲染。其中包括游戏界面和管理面版两个模块,游戏界面主要为游戏中出现的界面,比如:开始界面和游戏中界面。管理面板包括开始、退出、暂停三部分,主要为玩家提供控制游戏行进和退出。
游戏实体模块主要用于后台游戏逻辑。本游戏中仅有方块实体模块一部分。方块实体模块主要负责对已落下、正在落下和即将落下的方块图案的颜色和形状进行控制,核对正在落下的方块图案的行进路线、形状变换进行控制。
数据存储模块包括游戏中关卡数据的存储和的分数据的存储。游戏每一次启动都将全部删除上次启动时所产生的数据,重新进行新的数据存储。后台运行时重新进入游戏不算做重启游戏,故数据不会重置。
工具类模块将自身的静态成员或者方法提供给游戏中的其他类使用。
4游戏中各个类中实现的功能
由于在本次游戏的开发中本人对代码的注释比较详尽,故对各个类所实现的功能在代码中都有较详细的注释。
具体功能见附件代码。
5游戏的优化与改进
到目前为止本游戏已经能实现俄罗斯方块游戏本身的基本功能,但是有一些地方还值得优化与改进。下面提出几点需要改进的地方以便在下次开发时进行必要的完善。
加入本地游戏用户列表和相关的一些面板(如积分排行榜);
加入游戏声音(本次游戏的开发由于主要用于交通大学交通运输学院信息管理与信息系统09级2012年暑期课程设计,时间有限没有加入游戏声音);
取消重启游戏后得分重置(由于本次开发没有加入游戏用户,数据的保存只能保存所有玩家的最高纪录等信息,而无法保存某个玩家的个人最优成绩等);
对界面中图像进行优化(此次开发由于时间和精力有限对图像的处理力求简单,下次开发可以对图像进行比较深的加工);
对游戏中的一些BUG进行改进(到目前为止此游戏在中兴U880[Android2.3.7]上使用没有发现比如卡死等较大的BUG);
.
.
结论
面向对象设计方法以对象为基础,利用特定的软件工具直接完成从对象客体的描述到软件结构之间的转换。这是面向对象设计方法最主要的特点和成就。面向对象设计方法的应用解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题,缩短了开发周期,解决了从分析和设计到软件模块结构之间多次转换映射的繁杂过程,是一种很有发展前途的系统开发方法。
通过此次Android游戏的开发,使得我们更加深刻地理解了面向对象的编程思想。
参考文献
[1] 志宏.Java程序设计教程.:航空工业,2010年7月
[2] 单兴华.Java基础与案例开发详解.:清华大学,2009年9月
附录
附录文件代码
package .weirui;
import ty;
import t;
import ces;
import ;
import ;
.
.
import ;
import ;
import le;
import ;
import y;
import nt;
import ;
import em;
import Event;
import ;
import Manager;
import Layout;
import ;
public class Elos extends Activity {
private final int SQUARELEMENT_NUMBERS = 7;
private ElosLogic player = null;//定义一个自定义的类的量
private ElosView evElos = null;
private ElosStateView esvElos = null;
private ElosLogic[][] elosGuard = null;//定义界面数组
private Drawable[] drArr = new Drawable[SQUARELEMENT_NUMBERS];//保存方块的图片
.
.
private Drawable drArrCartoonBG = null;//保存背景图片
private int nElosHeight = 0;//定义一个保存组成方块图片的高的量
private int nElosWidth = 0;//定义一个保存组成方块图片的宽的量
private boolean bReset = true;//为true时表示开始
private boolean bPause =true;//false表示用来暂停使用的
int DRAWABLE_CHOICES = SQUARELEMENT_NUMBERS;//定义一个一个变量用来随机抽取图片来组成图形
.
int ELOS_CHOICES = 15;
int time=0;//时间
int ntime=0;//累计时间
int nTimeInterval = 500;//初始值为500表示第一关的总分为500*10
int nCents = 0;//游戏得分
int nStage = 1;//游戏关卡
int nOldStage = 0;//定义上一个关卡数
private int nTotalLines = 0;
private int nTotalColumns = 0;//定义了左边界面的数组行与列
int nElosYOffset = 0;
int nElosXOffset = 0;//定义了屏幕的起始点
private int nElosAreaWidth = 0;
private int nElosAreaHeight = 0;//定义了左面界面的宽与高的量
Thread thdTimer = null;//定义一个线程
boolean bReportResult = false;//只有当游戏失败后值变为true,会在屏幕上显
.
示结果
boolean bPlaying = true;//当变量为默认的true表示线程里开始工作
boolean start=false;
int nPlayerChoice = 0;//当获得随机抽取数表示要显示那个方块图形时赋给这个变量
int nDrawableChoice = 0;//当获得随机抽取数表示选用那图片做为构造方块图形赋值给这个变量
.
//获取资源图片
private void RetriveDrawable(Context c){
}
//-----由于没有拟定每个小图片的大小,所以调用函数获得设定的宽和高--------
Resources res = ources();
drArr[0] = wable(le.a);
drArr[1] = wable(le.b);
drArr[2] = wable(le.c);
drArr[3] = wable(le.d);
drArr[4] = wable(le.e);
drArr[5] = wable(le.f);
drArr[6] = wable(le.g);
drArrCartoonBG = wable(le.p4);
.
private int GetElosHeight(Drawable dr){
}
private int GetElosWidth(Drawable dr){
}
//-------------------------------------------------------------------
return imumWidth();
return imumHeight();
private void AnnounceNewStage(){//显示关卡数并每关过后将下降速度加快
if (nOldStage != nStage){
xt(this, "第" + nStage + "关",
_SHORT).show();
少
.
nTimeInterval = nTimeInterval - (nStage - 1)*50;//每关后睡眠时间减
}
}
nOldStage = nStage;
private void ClearStageAndCentsAfterFail(){//开始的时候要清空关卡和分数
nCents = 0;
nStage = 1;
time=0;
.
}
ntime=0;
//---------------------------------游戏失败-------------------------------------------
private boolean IsElosGameFail(){
thdTimer=null;
ElosLogic visit = elosGuard[0][0];
while (visit != null){
if (() && !) return true;
visit = sLogicRight();//一直在左边方框数组的第一行寻找存在有了图片并被画出的则返回true表示失败
}
//------------------------------判断要消去的行数}
return false;
----------------------------------
.
private boolean IsWholeLineDrawed(ElosLogic logic){
if (logic == null) return false;
ElosLogic keep1, keep2;//定义两个ElosLogic的变量
keep1 = keep2 = logic;
.
int nCount = 0;
//通过两个分别左右循环的来查看这一行是否需要消除
while (keep1 != null){
}
keep2 = sLogicRight();
while(keep2 != null){
}
if (nCount == Columns) return true;//如果与列数相同,则需if (())
nCount++;
if (())
nCount++;
keep1 = sLogicLeft();
keep2 = sLogicRight();
要消除返回true
}
private void ClearWholeLine(ElosLogic logic){//如果要消除,则将这一行全设return false;
定为不显示
.
if (logic == null) return;
ElosLogic keep1, keep2;
.
}
keep1 = keep2 = logic;
while (keep1 != null){
}
keep2 = sLogicRight();
while(keep2 != null){
}
w(false);
keep2 = sLogicRight();
w(false);
keep1 = sLogicLeft();
private void ElosLogicCopyAfterLineFull(ElosLogic src, ElosLogic des){
}
private void ElosLogicLineCopyAfterLineFull(ElosLogic logic){//没消除掉行 = ;
= false;//把上一行设置成不绘制
wable(wable());//将下一行保存了上一行的图片
数都得自动下降
.
Rect rtElos = t();
Rect rtGuardZero = elosGuard[0][0].GetRect();
.
int nLineNumber = ( - )/();
while (nLineNumber >= 1){
for (int i = 0; i < Columns; i++){
//依次对下一行的每列都换成上一行的图片
ElosLogicCopyAfterLineFull(elosGuard[nLineNumber - 1][i],
elosGuard[nLineNumber][i]);
}
int CheckGuard(ElosLogic elosPlayer){//每次不再下降的时候都要核对一遍进行
}
}
nLineNumber--;
操作
.
int nErasableLines = 0;
if (elosPlayer == null) return nErasableLines;
if (IsWholeLineDrawed(elosPlayer)){
ClearWholeLine(elosPlayer);
ElosLogicLineCopyAfterLineFull(elosPlayer);
nErasableLines++;
}
if (sLogicDown() != null){//向上查两行
if (IsWholeLineDrawed(sLogicDown())){
.
ClearWholeLine(sLogicDown());
ElosLogicLineCopyAfterLineFull(sLogicDown());
nErasableLines++;
}
if (sLogicDown().GetElosLogicDown() != null){
if
(IsWholeLineDrawed(sLogicDown().GetElosLogicDown())){
ClearWholeLine(sLogicDown().GetElosLogicDown());
ElosLogicLineCopyAfterLineFull(sLogicDown().GetElosLogicDown());
.
}
}
nErasableLines++;
}
if (sLogicUp() != null){//向上查一行
if (IsWholeLineDrawed(sLogicUp())){
ClearWholeLine(sLogicUp());
ElosLogicLineCopyAfterLineFull(sLogicUp());
nErasableLines++;
.
}
}
}
return nErasableLines;//返回所要消除的行数
//-------以下三个函数是分别相应当按下左,右和下的时候组合方块进行的移动-------------
private ElosLogic PlayerMoveDown(ElosLogic elosPlayer, int
nPlayerChoice){//如果向下可以移动的就得进行操作
了
elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer);//重新生成一
if (elosPlayer == null) return elosPlayer;
if (!IsPlayerMoveableDown(elosPlayer)) {return elosPlayer; }
Drawable dr = wable();
ClearPlayer(elosPlayer);
elosPlayer = sLogicDown();//这个数组已经换成下一行的个跟下落前一样的方块
.
}
return elosPlayer;
.
private ElosLogic PlayerMoveLeft(ElosLogic elosPlayer, int nPlayerChoice){
if (elosPlayer == null) return elosPlayer;
if (!IsPlayerMoveableLeft(elosPlayer)) {return elosPlayer; }
Drawable dr = wable();
ClearPlayer(elosPlayer);
elosPlayer = sLogicLeft();
elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer);
return elosPlayer;
}
private ElosLogic PlayerMoveRight(ElosLogic elosPlayer,
nPlayerChoice){
if (elosPlayer == null) return elosPlayer;
if (!IsPlayerMoveableRight(elosPlayer)) {return elosPlayer; }
Drawable dr = wable();
ClearPlayer(elosPlayer);
elosPlayer = sLogicRight();
elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer);
return elosPlayer;
}
.
int
.
//---------------------------------------------------------------------------
//--------------------------及时清空上一个图--------------------------------
private void ClearElosLogicUnitUnitTag(ElosLogic elosPlayer){
if (elosPlayer == null) return;
= false;
if (sLogicLeft() != null
sLogicLeft().bUnit)
ClearElosLogicUnitUnitTag(sLogicLeft());
if (sLogicRight() != null
sLogicRight().bUnit)
ClearElosLogicUnitUnitTag(sLogicRight());
if (sLogicUp() != null
sLogicUp().bUnit)
ClearElosLogicUnitUnitTag(sLogicUp());
if (sLogicDown() != null
sLogicDown().bUnit)
ClearElosLogicUnitUnitTag(sLogicDown());
}
.
形&&
&&
&&
&&
.
//--------------------判断下左右的值返回到函数IsRecursiveElosLogic中---------------------------------
private boolean IsElosLogicDownable(ElosLogic logic){//判断它的下面情况
if (logic == null){ return false;}
if (sLogicDown() == null) { return false;}//表示图形已经到底了返回false
if (sLogicDown().bUnit) return true;//表示下面已经有图形了返回true
if (sLogicDown().IsDraw()) { return false;}//下面的没有绘制图片则返回false
.
}
return true;
private boolean IsElosLogicLeftable(ElosLogic logic){
}
private boolean IsElosLogicRightable(ElosLogic logic){
if (logic == null) return false;
if (sLogicLeft() == null) return false;
if (sLogicLeft().bUnit) return true;
if (sLogicLeft().bDraw) return false;
return true;
.
}
if (logic == null) return false;
if (sLogicRight() == null) return false;
if (sLogicRight().bUnit) return true;
if (sLogicRight().bDraw) return false;
return true;
//---------------------------------------------------------------------------------
//------------------------------------通过上面三个函数返回值判断下左右能否移动-----------------------
boolean IsRecursiveElosLogicDownable(ElosLogic elosLogic){//利用上面函数返还值判断方块是否可以移动
if (!IsElosLogicDownable(elosLogic)) return false;
= false;//每次对方块中的一个数组量判断不出是否可以下降是先将量赋为false表示没有
if (sLogicDown() != null &&
sLogicDown().bUnit)
if(!IsRecursiveElosLogicDownable(sLogicDown()))
{//只要在一个方向不能动的时候就得将bUnit变为true表示有量
.
return false;}
= true;//知道通过上下左右检查出的确不能移动在将他设定
.
为true
}
private boolean IsRecursiveElosLogicLeftable(ElosLogic elosLogic){
if (!IsElosLogicLeftable(elosLogic)) return false;
= false;
if (sLogicLeft() != null &&
return true;
sLogicLeft().bUnit)
}
private boolean IsRecursiveElosLogicRightable(ElosLogic elosLogic){
if (!IsElosLogicRightable(elosLogic)) return false;
= false;
if (sLogicRight() != null &&
if(!IsRecursiveElosLogicLeftable(sLogicLeft()))
{ = true;return false;}
= true;
return true;
sLogicRight().bUnit)
.
if(!IsRecursiveElosLogicRightable(sLogicRight()))
{ = true;return false;}
.
}
= true;
return true;
//---------------------------------------------------------------------------------------------
//----------------------------获得能否移动的结果后返回true和false的值给线程里---------------------------
.
private boolean IsPlayerMoveableDown(ElosLogic elosPlayer){
}
private boolean IsPlayerMoveableLeft(ElosLogic elosPlayer){
}
private boolean IsPlayerMoveableRight(ElosLogic elosPlayer){
}
if (elosPlayer == null) return false;
return (IsRecursiveElosLogicRightable(elosPlayer));
if (elosPlayer == null) return false;
return (IsRecursiveElosLogicLeftable(elosPlayer));
if (elosPlayer == null) return false;//调用的左边的数组中的量不为null
return (IsRecursiveElosLogicDownable(elosPlayer));
.
//-------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
.
private class TimerThread extends Thread{
Override
public void run() {
// TODO Auto-generated method stub
();
while (bPlaying){
while(bPause){
validate();
try {
sleep(nTimeInterval);
} catch (InterruptedException e) {
}
//用来累计时间的
ntime=ntime+nTimeInterval;
if(ntime%1000==0)
// TODO Auto-generated catch block
tackTrace();
.
数
time++;
if (IsElosGameFail()){
}
//创建的player在这个地方是指数组坐标(1,nTotalColumns/2)
if (!erMoveableDown(player)){
ClearElosLogicUnitUnitTag(player);
int nErasableLine = CheckGuard(player);//获得要消除的行bPlaying = false;
bReportResult = true;
validate();
nCents += 100*nErasableLine + (int)((nErasableLine == 0?
1: nErasableLine) - 1)*50;//若连续消除了两成以上额外加上消去的层数减一再乘50
nStage = nCents/(10*nTimeInterval) + 1;//对于每个关卡的计算
player = CreatePlayer(drArr[GetRandomDrawableChoice()],
GetRandomPlayerChoice());//没核对完一次下落都要重新下一次的下落
.
}else{
.
.
}
player = MoveDown(player, nPlayerChoice);
}
}
}
validate();//执行完上面的都要重新绘制一下界面
}
//--------------这两个函数是用来设置菜单的----------------------
Override
public boolean onCreateOptionsMenu(Menu menu) {
}
// TODO Auto-generated method stub
(0, 0, 0, "开始");
(0, 1, 1, "退出");
(0, 2, 2, "暂停");
return teOptionsMenu(menu);
Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
.
if (mId() == 0){
bPlaying = true;
bPause = true;
start=true;
MakeElosLogicNet();//对左边界面的每个数组重新保存
validate();
ClearStageAndCentsAfterFail();//清空游戏的分数和关卡
//-------------------下面的函数是通过两个随机函数获得图片和使用图片组成的图形-------------
player = CreatePlayer(drArr[GetRandomDrawableChoice()],
GetRandomPlayerChoice());
.
}
//当创建了一个方块图形后就要进入一个线程
if (thdTimer == null){
}
thdTimer = new TimerThread();
();
if (mId()==1){
}
if (mId()==2){
();
.
.
}
}
if (le().equals("暂停")){
bPause = false;
le("继续");
bled(false);
}else {
}
bPause = true;
le("暂停");
bled(true);
return onsItemSelected(item);
//---------------------------------------------------------
//-------------------------入口的主函数---------------------------------
Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
te(savedInstanceState);
setContentView();
LinearLayout elos = (LinearLayout)ewById();
.
Params params =
new
Params(_CONTENT,
_PARENT);
rgin = 1;
argin = 1;
//布局时对显示框的布局
= 1;
w(evElos = new ElosView(this), params);
params = new Params(params);
= 5;
w(esvElos = new ElosStateView(this), params);
RetriveDrawable(this);//对图片进行提取
nElosHeight = GetElosHeight(drArr[0]);
nElosWidth = GetElosWidth(drArr[0]);
}
//-----------------------------触发事件(触屏和--------------------------
Override
.
键盘)
.
public boolean onTouchEvent(MotionEvent event){
//获得屏幕的宽和高
WindowManager windowManager = getWindowManager();
Display display = aultDisplay();
float screenWidth = th()*4/5;
float screenHeight = ght();
float x = ();
float y = ();
if(ion()==_DOWN&&start==true){
if (y>screenHeight*2/3&&x player = PlayerMoveLeft(player, nPlayerChoice); }else (y>screenHeight*2/3&&x>screenWidth*2/3&&x player = PlayerMoveRight(player, nPlayerChoice); }else if (y ElosTransform(player); }else (x>screenWidth/3&&x if (erMoveableDown(player)) . if if . . } } } Override player = PlayerMoveDown(player, nPlayerChoice); date(); AnnounceNewStage(); return hEvent(event); public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if (keyCode == 21){//left player = PlayerMoveLeft(player, nPlayerChoice); }else if (keyCode == 22){//right player = PlayerMoveRight(player, nPlayerChoice); }else if (keyCode == 19){//up ElosTransform(player); }else if (keyCode == 20){//down if (erMoveableDown(player)) player = PlayerMoveDown(player, nPlayerChoice); . } } date(); AnnounceNewStage(); return own(keyCode, event); //-------------------------------------------------------------------------- //下面是组合方块的变形 private void ElosTransform1(ElosLogic elosPlayer){ if (r == 1){ Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 5); }else if (r == 6){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . . } } Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 0); private void ElosTransform2(ElosLogic elosPlayer){ if (r == 2){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; if (sLogicUp().GetElosLogicUp() == null) return; if (sLogicUp().GetElosLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 6); }else if (r == 7){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicRight().GetElosLogicRight() == null) return; if (sLogicRight().GetElosLogicRight().IsDraw()) return; . Drawable dr = wable(); . layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 7); }else if(r == 8){ if (sLogicDown() == null) return; if (sLogicDown().IsDraw()) return; if (sLogicDown().GetElosLogicDown() == null) return; if (sLogicDown().GetElosLogicDown().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 8); }else if (r == 9){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 1); . . } } //NNN // N private void ElosTransform3(ElosLogic elosPlayer){ if (r == 3){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 9); }else if (r == 10){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 10); }else if (r == 11){ if (sLogicDown() == null) return; if (sLogicDown().IsDraw()) return; Drawable dr = wable(); . } layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 11); }else if (r == 12){ } if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 2); //NNN //N private void ElosTransform4(ElosLogic elosPlayer){ if (r == 4){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicDown().GetElosLogicDown() == null) return; if (sLogicDown().GetElosLogicDown().IsDraw()) return; . Drawable dr = wable(); . layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 12); }else if (r == 13){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 13); }else if(r == 14){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicUp().GetElosLogicUp() == null) return; if (sLogicUp().GetElosLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 14); }else if (r == 15){ if (sLogicDown() == null) return; . if (sLogicDown().IsDraw()) return; if (sLogicRight().GetElosLogicRight() == null) return; if (sLogicRight().GetElosLogicRight().IsDraw()) return; . } } Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 3); private void ElosTransform(ElosLogic elosPlayer){ // Drawable dr = wable(); ElosTransform1(elosPlayer); ElosTransform2(elosPlayer); ElosTransform3(elosPlayer); ElosTransform4(elosPlayer); // wable(dr); } //----------------将界面分成的数组每个量new一个自定义的类ElosLogic对象rChoice = r - 1; . ----------------- private void InitElosLogicGuard(){ } //----------------------------------------------------------------------elosGuard = new ElosLogic[nTotalLines][nTotalColumns]; int i = 0; while (i < nTotalLines){ } for (int j = 0; j elosGuard[i][j] = new ElosLogic(); i++; ------------- //---------------将我们数组中每个量可能会使用的数据保存到自定义类中--------------- . private void MakeElosLogicNet(){ Rect rt = new Rect(); for (int i=0;i int j = 0; for (; j < Columns; j++){ //------------left------------------ if (j == 0){ . . elosGuard[i][j].SetElosLogicLeft(null); }else{ elosGuard[i][j].SetElosLogicLeft(elosGuard[i][j - 1]); } //------------right-------------------- if (j == Columns - 1){ elosGuard[i][j].SetElosLogicRight(null); }else{ elosGuard[i][j].SetElosLogicRight(elosGuard[i][j + 1]); } //-----------up-------------------------------- if (i == 0){ elosGuard[i][j].SetElosLogicUp(null); }else{ elosGuard[i][j].SetElosLogicUp(elosGuard[i - 1][j]); } //------------down------------------------- if (i == Lines - 1){ elosGuard[i][j].SetElosLogicDown(null); }else{ elosGuard[i][j].SetElosLogicDown(elosGuard[i + 1][j]); } . //----------------保存好数组中每个量的框架------------------ = j*idth + nElosXOffset; = i*eight + Offset; = + idth; = + eight; elosGuard[i][j].SetRect(rt);//将数组中的每个量的边框保存到自定义类中 } //---------------------------------------------------------------------- } elosGuard[i][j].SetDrawable(drArr[0]); elosGuard[i][j].SetDraw(false); elosGuard[i][j].bUnit = false; } ---------- //----------------------------这两个类主要是用来绘制界面的------------------------- . Rect rtDraw = new Rect(); //画图 . private void DrawElosLogicNet(Canvas canvas, ElosLogic[][] elosLogicGuard,Rect rtDraw){ 制 . for (int i = 0; i < ; i++) for (int j = 0; j < elosLogicGuard[i].length; j++) if (elosLogicGuard[i][j].IsDraw()) DrawElos(elosLogicGuard[i][j], canvas);//对数组的每个量进行绘} private void DrawElos(ElosLogic elosLogic, Canvas canvas){ } //----------------------------------------------------------------------if (!()) return; Drawable dr = wable(); if (dr == null) return; //-----------绘制左边数组中的每个量的边框和图片----------------- (t()); = - 1/2; = - 1/2; nds(rtDraw); (canvas);//将图片画在相应的矩形框架里 //------------------------------------------------------------ 2024年1月24日发(作者:安璇子) . 学姓成 . 交通运输学院 面向对象程序设计 课程设计 院 交通运输学院 班 级 信管09 名 许 文 学 号 200900820 绩 指导老师 应东 2012 年 7 月 8 日 . 交通大学交通运输学院课程设计任务书 所在系:信息管理与信息系统 课程名称:面向对象程序设计 指导教师(签名): 专业班级: 信管09 学生: 许文 学号:200900820 一、课程设计题目 基于安卓的俄罗斯方块游戏开发 二、课程设计的目的 (1)提高学生思考与分析项目的能力。 (2)提高并加强学生面向对象的编程思想。 (3)强化学生灵活的编写程序并解决问题的能力。 三、课程设计的主要容和要求(包括原始数据、技术参数、设计要求、工作量要求等) 1. 写出详细设计说明 2. 编写程序代码,调试程序使其能正确运行 3. 设计完成的软件要便于操作和使用 四、工作进度安排 本课程设计一共安排3周时间,具体如下: 第1周:完成分析与设计工作,对整个设计的功能及流程有清晰的认识; 第2周:完成开发工作; 第3周:对设计中存在的问题进行完善,完成设计报告。 . . 五、主要参考文献 [1] 志宏.Java程序设计教程.:航空工业,2010年7月 [2] 单兴华.Java基础与案例开发详解.:清华大学,2009年9月 审核批准意见 系主任(签字) 年 月 日 指导教师评语及成绩 指 导 教 师 评 语 . . 成 绩 导师签字: 年 月 日 目录 俄罗斯方块游戏在Android中的实现 .................................................... 1 引言 ............................................................................... 1 1游戏背景及功能概述 ................................................................ 1 1.1背景概述 .................................................................... 1 1.2游戏简介 .................................................................... 2 . . 1.3功能概述 .................................................................... 2 1.4游戏操作方法 ................................................................ 4 2.游戏策划及准备工作................................................................ 5 2.1游戏策划 .................................................................... 5 2.2游戏开发平台 ................................................................ 6 2.3Android平台下游戏的准备工作 ................................................. 7 3.游戏构架 ......................................................................... 7 4游戏中各个类中实现的功能 .......................................................... 8 5游戏的优化与改进 .................................................................. 8 结论 ............................................................................... 9 参考文献 ........................................................................... 9 附录 ............................................................................... 9 附录文件代码 ........................................................ 9 附录文件代码 .................................................. 64 附录文件代码 ................................................ 66 附录文件代码 .......................................................... 66 附录文件代码 ............................................. 68 附录文件代码 ........................................................ 69 附录文件代码 ...................................................... 70 . . 俄罗斯方块游戏在Android中的实现 引言 引言:简要说明设计题目的目的、意义、容、主要任务等。 俄罗斯方块原本是前联科学家阿列克•帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。 从诞生发展至今俄罗斯方块已经可以在各个平台上运行了。本次游戏的开发就是基于Android 4.0系统和传统俄罗斯方块的游戏方法进行的。 1游戏背景及功能概述 俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。 1.1背景概述 俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰. . 动与造成的经济价值可以说是游戏史上的一件大事。这款游戏最初是由联的游戏制作人Alex Pajitnov 制作的,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。 究其历史,俄罗斯方块最早还是出现在PC机上,而我国的用户都是通过红白机了解、喜欢上它的。现在Android手机游戏的兴起又将重新掀起这股让人沉迷的俄罗斯方块风潮。对一般用户来说,它的规则简单,容易上手,且游戏过程变化无穷,而在"Android俄罗斯方块"中,更有一些Android游戏所独有的魅力――更加方便简单的操作模式,用户可在任意的地方任意时间进行游戏。 1.2游戏简介 原本是前联科学家阿列克·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。 Game Boy版的俄罗斯方块在日本卖出424万套,是Game Boy史上卖最好的游戏。海湾战争时,也是前线美军最常拿消磨时间的游戏之一。 由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。 俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。 俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。 1.3功能概述 1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为24,列高为25,以每个小正方形为单位。 2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。 I:一次最多消除四层 . . J(左右):最多消除三层,或消除二层 L:最多消除三层,或消除二层 O:消除一至二层 S(左右):最多二层,容易造成孔洞 Z (左右):最多二层,容易造成孔洞 T:最多二层 (1)部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。 方块会从区域上方开始缓慢继续落下。 (2)玩家可以做的操作有:以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。 (3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。 (4)当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。 (5)当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。 (6)一般来说,游戏还会提示下一个要落下的方块,熟练的玩家会计算到下一个方块,评估现在要如何进行。由于游戏能不断进行下去对商业用游戏不太理想,所以一般还会随着游戏的进行而加速提高难度。 3、通过设计者预先设置的随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。 4、如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束。 具体到每一款不同的游戏,其中的细节规则都可能有千差万别,但是以上的基本规则是相同的。 . . 1.4游戏操作方法 1、安装apk游戏安装包,在Android手机的资源管理其中找到并点击文件选择安装。 2、点击游戏图标进入游戏界面后按键盘的"MENU"按钮,在弹出的菜单中选择“开始”来开始游戏(如图1所示)。 图1游戏开始前的界面截图 3、游戏玩家可以再游戏中采用点击“MENU”按钮来选择“暂停”、“退出”、“开始”以实现暂停、退出、重新开始功能(如图2所示)。 . . 图2游戏中的界面截图 4、触摸屏操作:系统缺省设置使用触摸屏,用手指点击方块的左边一次左移一格(长按则快速移动到最左边);点击方块的右边一次右移一格(长按则快速移动到最右边);点击方块本身旋转方块;点击方块的下边一次向下移一格(长按则快速移动到最下边)。 5、计分牌显示的容: “分数””为本局游戏所得的分数,一次消一行100分、2行200分、3行400分、4行800分。 “关卡”为本局游戏所在的关卡,所在的关卡越高,难度越大。 “时间”为本局游戏从开始到当前所用的时间。 2.游戏策划及准备工作 2.1游戏策划 游戏的策划是指对游戏中主要功能的实现方案进行确定的过程,大型游戏需要缜密的策划才可以开发。例如,呈现技术、目标平台等容。 游戏设计 . . 本游戏为经典俄罗斯方块游戏,每一次消除一层加100分、2层200分、3层400分、4层800分。游戏中的方块形状都是随机生成的(共7种)。随着难度的增加方块下落的默认速度会增加,游戏分数没有上限。 呈现技术 本游戏采用的游戏背景和其他图片都是用美图秀秀软件编辑的。 目标平台 本游戏的目标平台为Android 4.0。 操作方式 游戏的操作方式为触控操作,游戏菜单的弹出是通过键盘来操作的。 2.2游戏开发平台 本次开发采用jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep_2008开发包、eclipse-SDK-3.6.2-win32开发工具、android-sdk-windows开发包。 JDK(Java Development Kit)是Sun Microsystems针对Java开发员的产品。自从Java推出以来,JDK已经成为使用最广泛的Java SDK。JDK 是整个Java的核心,包括了Java运行环境,Java工具和Java基础的类库。JDK是学好Java的第一步。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。从SUN的JDK5.0开始,提供了泛型等非常实用的功能,其版本也不断更新,运行效率得到了非常大的提高。 Eclipse(软件开发者包)是Eclipse Platform、JDT和PDE所生产的组件合并,它们可以一次下载。这些部分在一起提供了一个具有丰富特性的开发环境,允许开发者有效地建造可以无缝集成到Eclipse Platform中的工具。Eclipse SDK由Eclipse项目生产的工具和来自其它开放源代码的第三方软件组合而成。Eclipse项目生产的软件以 GPL发布,第三方组件有各自自身的许可协议。 Android SDK(Google Android专属的软件开发工具包),它是编写Android应用程序的基石。 . . 2.3Android平台下游戏的准备工作 本游戏中用到的图片资源见表1所示。 表1游戏中所用到的图片资源及说明 图片名称 大小(kB) 0.647 0.647 0.647 0.647 0.647 0.647 0.647 0.647 0.647 7.96 7.31 像素(w*h) 24*25 24*25 24*25 24*25 24*25 24*25 24*25 24*25 24*25 140*115 522*780 用途 小方快图案 小方快图案 小方快图案 小方快图案 小方快图案 小方快图案 小方快图案 小方快图案 小方快图案 游戏图标 游戏背景 3.游戏构架 本游戏中各个模块的结构如图3所示。 . 图3游戏的总构架 . 前台表示模块主要用于游戏画面的渲染。其中包括游戏界面和管理面版两个模块,游戏界面主要为游戏中出现的界面,比如:开始界面和游戏中界面。管理面板包括开始、退出、暂停三部分,主要为玩家提供控制游戏行进和退出。 游戏实体模块主要用于后台游戏逻辑。本游戏中仅有方块实体模块一部分。方块实体模块主要负责对已落下、正在落下和即将落下的方块图案的颜色和形状进行控制,核对正在落下的方块图案的行进路线、形状变换进行控制。 数据存储模块包括游戏中关卡数据的存储和的分数据的存储。游戏每一次启动都将全部删除上次启动时所产生的数据,重新进行新的数据存储。后台运行时重新进入游戏不算做重启游戏,故数据不会重置。 工具类模块将自身的静态成员或者方法提供给游戏中的其他类使用。 4游戏中各个类中实现的功能 由于在本次游戏的开发中本人对代码的注释比较详尽,故对各个类所实现的功能在代码中都有较详细的注释。 具体功能见附件代码。 5游戏的优化与改进 到目前为止本游戏已经能实现俄罗斯方块游戏本身的基本功能,但是有一些地方还值得优化与改进。下面提出几点需要改进的地方以便在下次开发时进行必要的完善。 加入本地游戏用户列表和相关的一些面板(如积分排行榜); 加入游戏声音(本次游戏的开发由于主要用于交通大学交通运输学院信息管理与信息系统09级2012年暑期课程设计,时间有限没有加入游戏声音); 取消重启游戏后得分重置(由于本次开发没有加入游戏用户,数据的保存只能保存所有玩家的最高纪录等信息,而无法保存某个玩家的个人最优成绩等); 对界面中图像进行优化(此次开发由于时间和精力有限对图像的处理力求简单,下次开发可以对图像进行比较深的加工); 对游戏中的一些BUG进行改进(到目前为止此游戏在中兴U880[Android2.3.7]上使用没有发现比如卡死等较大的BUG); . . 结论 面向对象设计方法以对象为基础,利用特定的软件工具直接完成从对象客体的描述到软件结构之间的转换。这是面向对象设计方法最主要的特点和成就。面向对象设计方法的应用解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题,缩短了开发周期,解决了从分析和设计到软件模块结构之间多次转换映射的繁杂过程,是一种很有发展前途的系统开发方法。 通过此次Android游戏的开发,使得我们更加深刻地理解了面向对象的编程思想。 参考文献 [1] 志宏.Java程序设计教程.:航空工业,2010年7月 [2] 单兴华.Java基础与案例开发详解.:清华大学,2009年9月 附录 附录文件代码 package .weirui; import ty; import t; import ces; import ; import ; . . import ; import ; import le; import ; import y; import nt; import ; import em; import Event; import ; import Manager; import Layout; import ; public class Elos extends Activity { private final int SQUARELEMENT_NUMBERS = 7; private ElosLogic player = null;//定义一个自定义的类的量 private ElosView evElos = null; private ElosStateView esvElos = null; private ElosLogic[][] elosGuard = null;//定义界面数组 private Drawable[] drArr = new Drawable[SQUARELEMENT_NUMBERS];//保存方块的图片 . . private Drawable drArrCartoonBG = null;//保存背景图片 private int nElosHeight = 0;//定义一个保存组成方块图片的高的量 private int nElosWidth = 0;//定义一个保存组成方块图片的宽的量 private boolean bReset = true;//为true时表示开始 private boolean bPause =true;//false表示用来暂停使用的 int DRAWABLE_CHOICES = SQUARELEMENT_NUMBERS;//定义一个一个变量用来随机抽取图片来组成图形 . int ELOS_CHOICES = 15; int time=0;//时间 int ntime=0;//累计时间 int nTimeInterval = 500;//初始值为500表示第一关的总分为500*10 int nCents = 0;//游戏得分 int nStage = 1;//游戏关卡 int nOldStage = 0;//定义上一个关卡数 private int nTotalLines = 0; private int nTotalColumns = 0;//定义了左边界面的数组行与列 int nElosYOffset = 0; int nElosXOffset = 0;//定义了屏幕的起始点 private int nElosAreaWidth = 0; private int nElosAreaHeight = 0;//定义了左面界面的宽与高的量 Thread thdTimer = null;//定义一个线程 boolean bReportResult = false;//只有当游戏失败后值变为true,会在屏幕上显 . 示结果 boolean bPlaying = true;//当变量为默认的true表示线程里开始工作 boolean start=false; int nPlayerChoice = 0;//当获得随机抽取数表示要显示那个方块图形时赋给这个变量 int nDrawableChoice = 0;//当获得随机抽取数表示选用那图片做为构造方块图形赋值给这个变量 . //获取资源图片 private void RetriveDrawable(Context c){ } //-----由于没有拟定每个小图片的大小,所以调用函数获得设定的宽和高-------- Resources res = ources(); drArr[0] = wable(le.a); drArr[1] = wable(le.b); drArr[2] = wable(le.c); drArr[3] = wable(le.d); drArr[4] = wable(le.e); drArr[5] = wable(le.f); drArr[6] = wable(le.g); drArrCartoonBG = wable(le.p4); . private int GetElosHeight(Drawable dr){ } private int GetElosWidth(Drawable dr){ } //------------------------------------------------------------------- return imumWidth(); return imumHeight(); private void AnnounceNewStage(){//显示关卡数并每关过后将下降速度加快 if (nOldStage != nStage){ xt(this, "第" + nStage + "关", _SHORT).show(); 少 . nTimeInterval = nTimeInterval - (nStage - 1)*50;//每关后睡眠时间减 } } nOldStage = nStage; private void ClearStageAndCentsAfterFail(){//开始的时候要清空关卡和分数 nCents = 0; nStage = 1; time=0; . } ntime=0; //---------------------------------游戏失败------------------------------------------- private boolean IsElosGameFail(){ thdTimer=null; ElosLogic visit = elosGuard[0][0]; while (visit != null){ if (() && !) return true; visit = sLogicRight();//一直在左边方框数组的第一行寻找存在有了图片并被画出的则返回true表示失败 } //------------------------------判断要消去的行数} return false; ---------------------------------- . private boolean IsWholeLineDrawed(ElosLogic logic){ if (logic == null) return false; ElosLogic keep1, keep2;//定义两个ElosLogic的变量 keep1 = keep2 = logic; . int nCount = 0; //通过两个分别左右循环的来查看这一行是否需要消除 while (keep1 != null){ } keep2 = sLogicRight(); while(keep2 != null){ } if (nCount == Columns) return true;//如果与列数相同,则需if (()) nCount++; if (()) nCount++; keep1 = sLogicLeft(); keep2 = sLogicRight(); 要消除返回true } private void ClearWholeLine(ElosLogic logic){//如果要消除,则将这一行全设return false; 定为不显示 . if (logic == null) return; ElosLogic keep1, keep2; . } keep1 = keep2 = logic; while (keep1 != null){ } keep2 = sLogicRight(); while(keep2 != null){ } w(false); keep2 = sLogicRight(); w(false); keep1 = sLogicLeft(); private void ElosLogicCopyAfterLineFull(ElosLogic src, ElosLogic des){ } private void ElosLogicLineCopyAfterLineFull(ElosLogic logic){//没消除掉行 = ; = false;//把上一行设置成不绘制 wable(wable());//将下一行保存了上一行的图片 数都得自动下降 . Rect rtElos = t(); Rect rtGuardZero = elosGuard[0][0].GetRect(); . int nLineNumber = ( - )/(); while (nLineNumber >= 1){ for (int i = 0; i < Columns; i++){ //依次对下一行的每列都换成上一行的图片 ElosLogicCopyAfterLineFull(elosGuard[nLineNumber - 1][i], elosGuard[nLineNumber][i]); } int CheckGuard(ElosLogic elosPlayer){//每次不再下降的时候都要核对一遍进行 } } nLineNumber--; 操作 . int nErasableLines = 0; if (elosPlayer == null) return nErasableLines; if (IsWholeLineDrawed(elosPlayer)){ ClearWholeLine(elosPlayer); ElosLogicLineCopyAfterLineFull(elosPlayer); nErasableLines++; } if (sLogicDown() != null){//向上查两行 if (IsWholeLineDrawed(sLogicDown())){ . ClearWholeLine(sLogicDown()); ElosLogicLineCopyAfterLineFull(sLogicDown()); nErasableLines++; } if (sLogicDown().GetElosLogicDown() != null){ if (IsWholeLineDrawed(sLogicDown().GetElosLogicDown())){ ClearWholeLine(sLogicDown().GetElosLogicDown()); ElosLogicLineCopyAfterLineFull(sLogicDown().GetElosLogicDown()); . } } nErasableLines++; } if (sLogicUp() != null){//向上查一行 if (IsWholeLineDrawed(sLogicUp())){ ClearWholeLine(sLogicUp()); ElosLogicLineCopyAfterLineFull(sLogicUp()); nErasableLines++; . } } } return nErasableLines;//返回所要消除的行数 //-------以下三个函数是分别相应当按下左,右和下的时候组合方块进行的移动------------- private ElosLogic PlayerMoveDown(ElosLogic elosPlayer, int nPlayerChoice){//如果向下可以移动的就得进行操作 了 elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer);//重新生成一 if (elosPlayer == null) return elosPlayer; if (!IsPlayerMoveableDown(elosPlayer)) {return elosPlayer; } Drawable dr = wable(); ClearPlayer(elosPlayer); elosPlayer = sLogicDown();//这个数组已经换成下一行的个跟下落前一样的方块 . } return elosPlayer; . private ElosLogic PlayerMoveLeft(ElosLogic elosPlayer, int nPlayerChoice){ if (elosPlayer == null) return elosPlayer; if (!IsPlayerMoveableLeft(elosPlayer)) {return elosPlayer; } Drawable dr = wable(); ClearPlayer(elosPlayer); elosPlayer = sLogicLeft(); elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer); return elosPlayer; } private ElosLogic PlayerMoveRight(ElosLogic elosPlayer, nPlayerChoice){ if (elosPlayer == null) return elosPlayer; if (!IsPlayerMoveableRight(elosPlayer)) {return elosPlayer; } Drawable dr = wable(); ClearPlayer(elosPlayer); elosPlayer = sLogicRight(); elosPlayer = CreatePlayer(dr, nPlayerChoice, elosPlayer); return elosPlayer; } . int . //--------------------------------------------------------------------------- //--------------------------及时清空上一个图-------------------------------- private void ClearElosLogicUnitUnitTag(ElosLogic elosPlayer){ if (elosPlayer == null) return; = false; if (sLogicLeft() != null sLogicLeft().bUnit) ClearElosLogicUnitUnitTag(sLogicLeft()); if (sLogicRight() != null sLogicRight().bUnit) ClearElosLogicUnitUnitTag(sLogicRight()); if (sLogicUp() != null sLogicUp().bUnit) ClearElosLogicUnitUnitTag(sLogicUp()); if (sLogicDown() != null sLogicDown().bUnit) ClearElosLogicUnitUnitTag(sLogicDown()); } . 形&& && && && . //--------------------判断下左右的值返回到函数IsRecursiveElosLogic中--------------------------------- private boolean IsElosLogicDownable(ElosLogic logic){//判断它的下面情况 if (logic == null){ return false;} if (sLogicDown() == null) { return false;}//表示图形已经到底了返回false if (sLogicDown().bUnit) return true;//表示下面已经有图形了返回true if (sLogicDown().IsDraw()) { return false;}//下面的没有绘制图片则返回false . } return true; private boolean IsElosLogicLeftable(ElosLogic logic){ } private boolean IsElosLogicRightable(ElosLogic logic){ if (logic == null) return false; if (sLogicLeft() == null) return false; if (sLogicLeft().bUnit) return true; if (sLogicLeft().bDraw) return false; return true; . } if (logic == null) return false; if (sLogicRight() == null) return false; if (sLogicRight().bUnit) return true; if (sLogicRight().bDraw) return false; return true; //--------------------------------------------------------------------------------- //------------------------------------通过上面三个函数返回值判断下左右能否移动----------------------- boolean IsRecursiveElosLogicDownable(ElosLogic elosLogic){//利用上面函数返还值判断方块是否可以移动 if (!IsElosLogicDownable(elosLogic)) return false; = false;//每次对方块中的一个数组量判断不出是否可以下降是先将量赋为false表示没有 if (sLogicDown() != null && sLogicDown().bUnit) if(!IsRecursiveElosLogicDownable(sLogicDown())) {//只要在一个方向不能动的时候就得将bUnit变为true表示有量 . return false;} = true;//知道通过上下左右检查出的确不能移动在将他设定 . 为true } private boolean IsRecursiveElosLogicLeftable(ElosLogic elosLogic){ if (!IsElosLogicLeftable(elosLogic)) return false; = false; if (sLogicLeft() != null && return true; sLogicLeft().bUnit) } private boolean IsRecursiveElosLogicRightable(ElosLogic elosLogic){ if (!IsElosLogicRightable(elosLogic)) return false; = false; if (sLogicRight() != null && if(!IsRecursiveElosLogicLeftable(sLogicLeft())) { = true;return false;} = true; return true; sLogicRight().bUnit) . if(!IsRecursiveElosLogicRightable(sLogicRight())) { = true;return false;} . } = true; return true; //--------------------------------------------------------------------------------------------- //----------------------------获得能否移动的结果后返回true和false的值给线程里--------------------------- . private boolean IsPlayerMoveableDown(ElosLogic elosPlayer){ } private boolean IsPlayerMoveableLeft(ElosLogic elosPlayer){ } private boolean IsPlayerMoveableRight(ElosLogic elosPlayer){ } if (elosPlayer == null) return false; return (IsRecursiveElosLogicRightable(elosPlayer)); if (elosPlayer == null) return false; return (IsRecursiveElosLogicLeftable(elosPlayer)); if (elosPlayer == null) return false;//调用的左边的数组中的量不为null return (IsRecursiveElosLogicDownable(elosPlayer)); . //------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- . private class TimerThread extends Thread{ Override public void run() { // TODO Auto-generated method stub (); while (bPlaying){ while(bPause){ validate(); try { sleep(nTimeInterval); } catch (InterruptedException e) { } //用来累计时间的 ntime=ntime+nTimeInterval; if(ntime%1000==0) // TODO Auto-generated catch block tackTrace(); . 数 time++; if (IsElosGameFail()){ } //创建的player在这个地方是指数组坐标(1,nTotalColumns/2) if (!erMoveableDown(player)){ ClearElosLogicUnitUnitTag(player); int nErasableLine = CheckGuard(player);//获得要消除的行bPlaying = false; bReportResult = true; validate(); nCents += 100*nErasableLine + (int)((nErasableLine == 0? 1: nErasableLine) - 1)*50;//若连续消除了两成以上额外加上消去的层数减一再乘50 nStage = nCents/(10*nTimeInterval) + 1;//对于每个关卡的计算 player = CreatePlayer(drArr[GetRandomDrawableChoice()], GetRandomPlayerChoice());//没核对完一次下落都要重新下一次的下落 . }else{ . . } player = MoveDown(player, nPlayerChoice); } } } validate();//执行完上面的都要重新绘制一下界面 } //--------------这两个函数是用来设置菜单的---------------------- Override public boolean onCreateOptionsMenu(Menu menu) { } // TODO Auto-generated method stub (0, 0, 0, "开始"); (0, 1, 1, "退出"); (0, 2, 2, "暂停"); return teOptionsMenu(menu); Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub . if (mId() == 0){ bPlaying = true; bPause = true; start=true; MakeElosLogicNet();//对左边界面的每个数组重新保存 validate(); ClearStageAndCentsAfterFail();//清空游戏的分数和关卡 //-------------------下面的函数是通过两个随机函数获得图片和使用图片组成的图形------------- player = CreatePlayer(drArr[GetRandomDrawableChoice()], GetRandomPlayerChoice()); . } //当创建了一个方块图形后就要进入一个线程 if (thdTimer == null){ } thdTimer = new TimerThread(); (); if (mId()==1){ } if (mId()==2){ (); . . } } if (le().equals("暂停")){ bPause = false; le("继续"); bled(false); }else { } bPause = true; le("暂停"); bled(true); return onsItemSelected(item); //--------------------------------------------------------- //-------------------------入口的主函数--------------------------------- Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub te(savedInstanceState); setContentView(); LinearLayout elos = (LinearLayout)ewById(); . Params params = new Params(_CONTENT, _PARENT); rgin = 1; argin = 1; //布局时对显示框的布局 = 1; w(evElos = new ElosView(this), params); params = new Params(params); = 5; w(esvElos = new ElosStateView(this), params); RetriveDrawable(this);//对图片进行提取 nElosHeight = GetElosHeight(drArr[0]); nElosWidth = GetElosWidth(drArr[0]); } //-----------------------------触发事件(触屏和-------------------------- Override . 键盘) . public boolean onTouchEvent(MotionEvent event){ //获得屏幕的宽和高 WindowManager windowManager = getWindowManager(); Display display = aultDisplay(); float screenWidth = th()*4/5; float screenHeight = ght(); float x = (); float y = (); if(ion()==_DOWN&&start==true){ if (y>screenHeight*2/3&&x player = PlayerMoveLeft(player, nPlayerChoice); }else (y>screenHeight*2/3&&x>screenWidth*2/3&&x player = PlayerMoveRight(player, nPlayerChoice); }else if (y ElosTransform(player); }else (x>screenWidth/3&&x if (erMoveableDown(player)) . if if . . } } } Override player = PlayerMoveDown(player, nPlayerChoice); date(); AnnounceNewStage(); return hEvent(event); public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if (keyCode == 21){//left player = PlayerMoveLeft(player, nPlayerChoice); }else if (keyCode == 22){//right player = PlayerMoveRight(player, nPlayerChoice); }else if (keyCode == 19){//up ElosTransform(player); }else if (keyCode == 20){//down if (erMoveableDown(player)) player = PlayerMoveDown(player, nPlayerChoice); . } } date(); AnnounceNewStage(); return own(keyCode, event); //-------------------------------------------------------------------------- //下面是组合方块的变形 private void ElosTransform1(ElosLogic elosPlayer){ if (r == 1){ Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 5); }else if (r == 6){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . . } } Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 0); private void ElosTransform2(ElosLogic elosPlayer){ if (r == 2){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; if (sLogicUp().GetElosLogicUp() == null) return; if (sLogicUp().GetElosLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 6); }else if (r == 7){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicRight().GetElosLogicRight() == null) return; if (sLogicRight().GetElosLogicRight().IsDraw()) return; . Drawable dr = wable(); . layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 7); }else if(r == 8){ if (sLogicDown() == null) return; if (sLogicDown().IsDraw()) return; if (sLogicDown().GetElosLogicDown() == null) return; if (sLogicDown().GetElosLogicDown().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 8); }else if (r == 9){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 1); . . } } //NNN // N private void ElosTransform3(ElosLogic elosPlayer){ if (r == 3){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 9); }else if (r == 10){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 10); }else if (r == 11){ if (sLogicDown() == null) return; if (sLogicDown().IsDraw()) return; Drawable dr = wable(); . } layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 11); }else if (r == 12){ } if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 2); //NNN //N private void ElosTransform4(ElosLogic elosPlayer){ if (r == 4){ if (sLogicLeft() == null) return; if (sLogicLeft().IsDraw()) return; if (sLogicDown().GetElosLogicDown() == null) return; if (sLogicDown().GetElosLogicDown().IsDraw()) return; . Drawable dr = wable(); . layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 12); }else if (r == 13){ if (sLogicUp() == null) return; if (sLogicUp().IsDraw()) return; if (sLogicLeft().GetElosLogicLeft() == null) return; if (sLogicLeft().GetElosLogicLeft().IsDraw()) return; . Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 13); }else if(r == 14){ if (sLogicRight() == null) return; if (sLogicRight().IsDraw()) return; if (sLogicUp().GetElosLogicUp() == null) return; if (sLogicUp().GetElosLogicUp().IsDraw()) return; Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 14); }else if (r == 15){ if (sLogicDown() == null) return; . if (sLogicDown().IsDraw()) return; if (sLogicRight().GetElosLogicRight() == null) return; if (sLogicRight().GetElosLogicRight().IsDraw()) return; . } } Drawable dr = wable(); layer(elosPlayer); AssembleElosUnitType(elosPlayer, dr, 3); private void ElosTransform(ElosLogic elosPlayer){ // Drawable dr = wable(); ElosTransform1(elosPlayer); ElosTransform2(elosPlayer); ElosTransform3(elosPlayer); ElosTransform4(elosPlayer); // wable(dr); } //----------------将界面分成的数组每个量new一个自定义的类ElosLogic对象rChoice = r - 1; . ----------------- private void InitElosLogicGuard(){ } //----------------------------------------------------------------------elosGuard = new ElosLogic[nTotalLines][nTotalColumns]; int i = 0; while (i < nTotalLines){ } for (int j = 0; j elosGuard[i][j] = new ElosLogic(); i++; ------------- //---------------将我们数组中每个量可能会使用的数据保存到自定义类中--------------- . private void MakeElosLogicNet(){ Rect rt = new Rect(); for (int i=0;i int j = 0; for (; j < Columns; j++){ //------------left------------------ if (j == 0){ . . elosGuard[i][j].SetElosLogicLeft(null); }else{ elosGuard[i][j].SetElosLogicLeft(elosGuard[i][j - 1]); } //------------right-------------------- if (j == Columns - 1){ elosGuard[i][j].SetElosLogicRight(null); }else{ elosGuard[i][j].SetElosLogicRight(elosGuard[i][j + 1]); } //-----------up-------------------------------- if (i == 0){ elosGuard[i][j].SetElosLogicUp(null); }else{ elosGuard[i][j].SetElosLogicUp(elosGuard[i - 1][j]); } //------------down------------------------- if (i == Lines - 1){ elosGuard[i][j].SetElosLogicDown(null); }else{ elosGuard[i][j].SetElosLogicDown(elosGuard[i + 1][j]); } . //----------------保存好数组中每个量的框架------------------ = j*idth + nElosXOffset; = i*eight + Offset; = + idth; = + eight; elosGuard[i][j].SetRect(rt);//将数组中的每个量的边框保存到自定义类中 } //---------------------------------------------------------------------- } elosGuard[i][j].SetDrawable(drArr[0]); elosGuard[i][j].SetDraw(false); elosGuard[i][j].bUnit = false; } ---------- //----------------------------这两个类主要是用来绘制界面的------------------------- . Rect rtDraw = new Rect(); //画图 . private void DrawElosLogicNet(Canvas canvas, ElosLogic[][] elosLogicGuard,Rect rtDraw){ 制 . for (int i = 0; i < ; i++) for (int j = 0; j < elosLogicGuard[i].length; j++) if (elosLogicGuard[i][j].IsDraw()) DrawElos(elosLogicGuard[i][j], canvas);//对数组的每个量进行绘} private void DrawElos(ElosLogic elosLogic, Canvas canvas){ } //----------------------------------------------------------------------if (!()) return; Drawable dr = wable(); if (dr == null) return; //-----------绘制左边数组中的每个量的边框和图片----------------- (t()); = - 1/2; = - 1/2; nds(rtDraw); (canvas);//将图片画在相应的矩形框架里 //------------------------------------------------------------