资源描述
湖南商学院
《移动互联网应用开发》 课程设计报告
题 目 基于Android俄罗斯方块设计与实现
姓 名:
学 号:
专 业:
班 级:
指引教师:
职 称:
计算机与信息工程学院
11月
课程设计评审表
级别
成绩
构成
先进
良好
中档
及格
不及格
平
时
成
绩
1.考勤满勤
2.作业全,均在A以上。
3.实验报告全,均在A以上。
1.考勤90%到
2.作业90%全,均在B以上。
3.实验报告90%全,均在B以上。
1.考勤80%到
2.作业80%全,均在B以上。
3.实验报告80%全,均在B以上。
1.考勤70%到
2.作业70%全,均在C以上。
3.实验报告70%全,均在C以上。
1.考勤70%如下。
2.作业70%如下,或均在C如下。
3.实验报告70%如下,或均在C如下。
课
程
设
计
成
绩
设
计
文
档
1.完全按照课程设计文档规范规定。
2.构造合理、层次清晰。
3.内容充实、设计详细。
1.完全按照课程设计文档规范规定。
2.构造较合理、层次较清晰。
3.内容较充实、设计较详细。
1.基本按照课程设计文档规范规定。
2.构造较合理、层次较清晰。
3.内容较充实、设计较详细。
1.基本按照课程设计文档规范规定。
2.构造欠合理、层次欠清晰。
3.内容欠充实、设计欠详细。
1.没有按照课程设计文档规范规定。
2.构造不合理、层次不清晰。
3.内容不充实、设计不详细。
界
面
设
计
1.布局合理。
2.界面美观,色调和谐,风格统一。
3.无链接错误。
1.布局较合理。
2.界面较美观,色调和谐,风格统一。
3.无链接错误。
1.布局较合理。
2.界面较美观,色调和谐,风格统一。
3.链接错误很少。
1.布局欠合理。
2.界面欠美观。
3.链接错误较少。
1.布局不合理。
2.界面不美观。
3.链接错误诸多。
功
能
设
计
1.可以较好完毕课程设计题目基本功能。
2.可以完毕异常数据和边界数据和谐解决。
3.类与接口设计合理。
4.功能实现无错误。
1.可以较好完毕课程设计题目基本功能。
2.基本可以完毕异常数据和边界数据和谐解决。
3.类与接口设计合理。
4.功能实现错误较少。
1.可以较好完毕课程设计题目基本功能。
2.基本可以完毕异常数据和边界数据和谐解决。
3.类与接口设计较合理。
4.功能实现错误较少。
1.可以完毕课程设计题目大某些基本功能。
2.未能完毕异常数据和边界数据和谐解决。
3.类与接口设计较合理。
4.功能实现错误较多。
1.未能完毕课程设计题目大某些基本功能。
2.未能完毕异常数据和边界数据和谐解决。
3.类与接口设计不合理。
4.功能实现错误较多。
综合成绩评估: 评阅教师(签章):
年 月 日
目 录
1 游戏简介
2 俄罗斯方块需求分析
2.1 游戏功能分析
2.1.1游戏方块控制功能
2.1.2方块生成显示功能
2.1.3方块摆放消行功能
2.1.4游戏分数记录功能
2.1.5游戏结束控制功能
2.2 方块及旋转变换需求分析
2.3 游戏运营分析
3 游戏总体设计分析
3.1 总体设计思想
3.2功能模块
3.2.1游戏区模块
3.2.2游戏控制模块
4 详细设计与实现
4.1 游戏开始菜单界面设计
4.2 方块类设计与实现
4.3 方块控制设计和判断
5 总结
6 参照资料
1 游戏简介
俄罗斯方块是家喻户晓益智小游戏,它由俄罗斯人阿列克谢∙帕基特诺夫(Alexey Pazhitnov)在1984年6月运用空暇时间编写游戏程序,故此得名。俄罗斯方块基本规则是移动、旋转和摆放游戏随机产生各种方块,使之排列成完整一行或多行并且消除得分。它看似简朴却变化无穷,俄罗斯方块上手极其简朴,且游戏过程变化无穷,作为游戏自身很有魅力,但是要纯熟掌握其中操作和摆放技巧,难度却不低。此软件给顾客提供了一种呈现自己高超技艺场合,在这里,它不但放松自己,还能感受到游戏中乐趣。
游戏区域会从顶部不断落下7种下坠物一种,游戏区域右上角有一种区域可以显示下一种下坠物形状,玩家可以控制下坠物移动、旋转和一键究竟,通过玩家操作,下坠物在游戏区域以“摆积木”形式浮现。下坠物在一行或多行堆满后就可以自动消除,消行后会得到相应分数,如果当前下坠物堆积至窗口顶端,则游戏结束。
2 俄罗斯方块需求分析
2.1 游戏功能分析
先分析一下整个游戏详细实现,一方面,游戏有开始、切换界面、结束等操作接口,而在游戏过程中,随着玩家按键,会浮现下坠物形态变化、下坠物迅速下坠、摆放下坠物件、销毁填满行、产生下一种方块等功能。先分析游戏特点,然后对这些功能一一进行细化,从而完毕整个游戏设计。
2.1.1游戏方块控制功能
当玩家按下相应操作键位时,通过条件判断,判断该操作与否可行,如果可行就执行相应操作。重要操作有游戏方块左移,右移,迅速下降,旋转变形。
2.1.2方块生成显示功能
游戏中会有两个地方产生方块,一种是游戏区域上方会有方块落下,尚有就是在屏幕右上角,也会产生一种方块,该方块为游戏区域下一种要产生方块。同步当游戏方块左右移动,下落,旋转变形时,要清除先前游戏方块,还规定出被操作后方块坐标,用新坐标重绘游戏方块。
2.1.3方块摆放消行功能
当方块落究竟部时候,通过条件判断,把方块摆放在屏幕底部并持续显示,当某行或者某几行被填满时候,要把这几行消除,并且被消除行数上方方块整体下移。
2.1.4游戏分数记录功能
记录游戏积分,每当有行被消除时,游戏积分会依照一次消除行数而增长相应分数。
2.1.5游戏结束控制功能
通过判断,如果摆放方块超过屏幕顶端时候,则游戏结束,可以返回菜单重新开始游戏。
2.2 方块及旋转变换需求分析
本游戏共有7种类型方块,而每种类型方块还可以通过旋转变换成4种不同形态方块进行摆放。
方块生成后可以将它们摆放在一种20*10区域内,该区域可以看作是有许各种等面积小方格构成区域,而这些区域状态只有两种,被方块占据或空闲。因而,对于整个游戏区域空间是占据或空闲,可以用一位数来标记,对于7种方块和它们旋转后形态咱们可以用不同标记进行标记。
对于旋转,游戏中所有方块都是按照顺时针旋转规则进行,并且在旋转过程中它们不会由于旋转而下降,总会保持在同一高度,但是在同一高度最多旋转三次,就会下降一格,任何下坠物通过一种旋转周期还会变回原型。
2.3 游戏运营分析
游戏开始后会随机产生一种方块,显示在游戏区域,同步右上角也会随机产生一种新方块,该方块为游戏区域下一种将要产生方块,游戏区域不再随机生成方块。当游戏区域方块下落究竟后,新方块再次进入游戏区域,如此循环,直到游戏结束,这就是游戏正常工作。
当顾客进行一定操作交互时候,运营程序可以依照顾客操作批示对方块进行控制,而这些操作都是响应有关按键而执行。
按键盘上键,此事件实现下坠方块旋转操作,方块并非任何状况都能旋转,如果旋转后与已摆放好方块有冲突或超过边界时,均不能发生旋转。因而一方面要判断与否有足够空间进行旋转,然后决定与否旋转。
按键盘下键,此事件实现下坠方块一键究竟操作,使方块迅速下降到游戏区域底部或者已经摆放好方块之上。
按键盘左键,此事件实现下坠方块左移操作,一方面要判断此方块与否可以发生左移,当越界或被其她摆放好方块阻挡时,则不能左移。
按键盘右键,此事件实现下坠方块右移操作。一方面要判断此方块与否可以发生右移,当越界或被其她摆放好方块阻挡时,则不能右移。
3 游戏总体设计分析
3.1 总体设计思想
俄罗斯方块游戏设计重要从9个方面进行构思。
(1)游戏主界面设计。
(2)方块设计。
(3)方块旋转。
(4)方块运动状况(涉及向左、向右、下坠)。
(5)方块自动消行功能。
(6)游戏速度调节。
(7)游戏积分计算。
(8)游戏开始菜单设计。
(9)游戏结束界面设计。
3.2功能模块
3.2.1游戏区模块
创立游戏区,解决玩家操作,显示操作成果
3.2.2游戏控制模块
开始,暂停继续,停止,新游戏,协助
4 详细设计与实现
4.1 游戏开始菜单界面设计
游戏开始菜单界面是游戏重要构成某些,为了增强游戏界面美化效果,同步又使界面简洁直观,添加了一种按钮,当监听到开始按钮被点击时,游戏会跳转到游戏开始Activity,该类实现起来较为简朴。
4.2 方块类设计与实现
方块是游戏最基本元素,俄罗斯方块所有操作都是建立在对方块操作上,方块可以用不同颜色方格图片来显示。
public class LeftCorner extends ShapeAbstract {
private static final long serialVersionUID = -5552787L;
private final static int COLOR = Color.CYAN;
{
Rectangle[][] data = null;
data = getEmptyShape();
data[0][1].setSolid(true);
data[0][1].setColor(COLOR);
data[1][1].setSolid(true);
data[1][1].setColor(COLOR);
data[1][2].setSolid(true);
data[1][2].setColor(COLOR);
data[2][2].setSolid(true);
data[2][2].setColor(COLOR);
m_shapes.add(data);
data = getEmptyShape();
data[0][2].setSolid(true);
data[0][2].setColor(COLOR);
data[0][3].setSolid(true);
data[0][3].setColor(COLOR);
data[1][1].setSolid(true);
data[1][1].setColor(COLOR);
data[1][2].setSolid(true);
data[1][2].setColor(COLOR);
m_shapes.add(data);
}
public String toString() {
return "LeftCorner";
}
}
4.3 方块控制设计
对方块控制,实际就是对二维数组array控制,该二维数组用来布置游戏区域方块显示,方块控制重要在TetrisController类里实现,用来判断方块各种操作与否可行,如果可行则执行相应操作,否则操作无效。
控制方块时,一方面要判断该操作与否可以执行,判断办法重要有判断方块与否可以左右移动,判断方块与否碰壁,判断方块与否触顶。
判断方块与否可以左移。
public class TetrisController {
private final static int BASE_COLUMN = 3;
private final static int MIN_GAP_TIME = 200;
private final static int MAX_GAP_TIME = 500;
private Shape m_current;
private Shape m_next;
private int m_row;
private int m_column = BASE_COLUMN;
private Rectangle[][] m_table;
private int m_score;
private transient Timer m_timer;
private transient Handler m_hanlder;
private boolean m_started;
private boolean m_paused;
private int m_rectWidth = 40;
private int m_rectHeight = 40;
private int m_nextRectWidth = 20;
private int m_nextRectHeight = 20;
private int m_gapTime = MAX_GAP_TIME;// shape fall down gap time
public TetrisController() {
Rectangle[][] rs = new Rectangle[20][10];
for (int i = 0;i < 20;i++) {
for (int j = 0;j < 10;j++) {
int color = Color.BLACK;
Rectangle r = new Rectangle();
r.setColor(color);
r.setWidth(m_rectWidth);
r.setHeight(m_rectHeight);
rs[i][j] = r;
}
}
m_table = rs;
}
public void setRectSize(int width,int height) {
m_rectWidth = width;
m_rectHeight = height;
if (m_table != null) {
for (Rectangle[] row :m_table) {
for (Rectangle rect :row) {
rect.setWidth(m_rectWidth);
rect.setHeight(m_rectHeight);
}
}
}
}
public void setNextRectSize(int width,int height) {
m_nextRectWidth = width;
m_nextRectHeight = height;
if (m_next != null) {
m_next.setWidth(m_nextRectWidth);
m_next.setHeight(m_nextRectHeight);
}
}
public void start() {
if (m_timer == null) {
m_row = 0;
m_score = 0;
m_gapTime = MAX_GAP_TIME;
clearTable();
prepare();
put(m_current.getShape(),m_row,m_column);
resetTimer(m_gapTime);
m_started = true;
}
m_paused = false;
notifyUpdateUI();
notifyScore();
}
private void resetTimer(int gapTime) {
if (m_timer != null) {
m_timer.cancel();
m_timer.purge();
m_timer = null;
}
m_timer = new Timer();
TimerTask task = new TetrisTask();
m_timer.schedule(task,gapTime,gapTime);
}
public void pause() {
m_paused = true;
}
public void stop() {
m_started = false;
m_timer.cancel();
m_timer = null;
notifyGameState();
}
private void notifyGameState() {
Message msg = new Message();
msg.what = TetrisActivity.MSG_GAVE_OVER;
m_hanlder.sendMessage(msg);
}
private void notifyScore() {
Message msg = new Message();
msg.what = TetrisActivity.MSG_UPDATE_SCORE;
m_hanlder.sendMessage(msg);
}
private Shape getRandomShape() {
Shape shape = null;
Random r = new Random();
int ran = Math.abs(r.nextInt()) % 8;
switch (ran) {
case 0:
shape = new Point();
break;
case 1:
shape = new Bar();
break;
case 2:
shape = new LeftCorner();
break;
case 3:
shape = new RightCorner();
break;
case 4:
shape = new LeftCrutch();
break;
case 5:
shape = new RightCrutch();
break;
case 6:
shape = new Hill();
break;
case 7:
shape = new Square();
break;
}
return shape;
}
public boolean down() {
synchronized (m_table) {
clearShape(m_row,m_column);
boolean move = move(m_current.getShape(),m_row + 1,m_column);
if (!move) {
recoverShape(m_current.getShape(),m_row,m_column);
return false;
} else {
m_row++;
notifyUpdateUI();
}
}
return true;
}
private boolean up() {
synchronized (m_table) {
clearShape(m_row,m_column);
boolean move = move(m_current.getShape(),m_row - 1,m_column);
if (!move) {
recoverShape(m_current.getShape(),m_row,m_column);
return false;
} else {
m_row--;
}
}
return false;
}
private boolean move(Rectangle[][] shape,int toRow,int toColumn) {
synchronized (m_table) {
List<int[]> coordinates = new ArrayList<int[]>();
for (int i = 0;i < shape.length;i++) {
for (int j = 0;j < shape[i].length;j++) {
Rectangle rect = shape[i][j];
if (rect.isSolid()) {
int row = i + toRow;
int column = j + toColumn;
if (row >= m_table.length || row < 0) {
return false;
}
if (column < 0 || column >= m_table[0].length) {
return false;
}
Rectangle gameRect = m_table[row][column];
if (gameRect.isSolid()) {
return false;
} else {
int[] coor = new int[3];
coor[0] = row;
coor[1] = column;
coor[2] = rect.getColor();
coordinates.add(coor);
}
}
}
}
Iterator<int[]> its = coordinates.iterator();
while (its.hasNext()) {
int[] coor = its.next();
int row = coor[0];
int column = coor[1];
int color = coor[2];
Rectangle gameRect = m_table[row][column];
gameRect.setSolid(true);
gameRect.setColor(color);
}
}
return true;
}
private int gainScore() {
int lines = removeLine();
if (lines > 0) {
int scoreBak = m_score;
switch (lines) {
case 1:
m_score += 1;
break;
case 2:
m_score += 3;
break;
case 3:
m_score += 6;
break;
case 4:
m_score += 10;
break;
}
notifyScore();
if (m_score / 50 > scoreBak / 50) {
if (m_gapTime > MIN_GAP_TIME) {
m_gapTime -= 50;
resetTimer(m_gapTime);
notifySpeedUp();
}
}
}
return lines;
}
private void notifySpeedUp() {
Message msg = new Message();
msg.what = TetrisActivity.MSG_UPDATE_SPEED;
int level = (m_score / 50);
if (m_gapTime <= MIN_GAP_TIME) {
msg.obj = "难度:" + level + ". 最后难度,你能坚持多久?!";
} else {
msg.obj = "难度:" + level;
}
m_hanlder.sendMessage(msg);
}
private int removeLine() {
int lines = 0;
synchronized (m_table) {
for (int i = 0;i < m_table.length;i++) {
Rectangle[] row = m_table[i];
boolean remove = true;
for (int j = 0;j < row.length;j++) {
Rectangle rect = row[j];
if (!rect.isSolid()) {
remove = false;
break;
}
}
if (remove) {
lines++;
for (int k = i;k > 0;k--) {
for (int m = 0;m < m_table[k].length;m++) {
m_table[k][m]
.setColor(m_table[k - 1][m].getColor());
m_table[k][m].setSolid(m_table[k - 1][m].isSolid());
}
}
for (int n = 0;n < m_table[0].length;n++) {
m_table[0][n].setColor(Shape.DEFAULT_COLOR);
m_table[0][n].setSolid(false);
}
}
}
}
return lines;
}
public boolean change() {
synchronized (m_table) {
clearShape(m_row,m_column);
Rectangle[][] next = m_current.getNextShape();
boolean move = move(next,m_row,m_column);
if (!move) {
recoverShape(m_current.getPreShape(),m_row,m_column);
return false;
} else {
notifyUpdateUI();
}
}
return false;
}
public boolean left() {
synchronized (m_table) {
clearShape(m_row,m_column);
Rectangle[][] shape = m_current.getShape();
boolean move = move(shape,m_row,m_column - 1);
if (move) {
m_column--;
notifyUpdateUI();
} else {
recoverShape(m_current.getShape(),m_row,m_column);
return false;
}
展开阅读全文