20162327WJH实验五——数据结构综合应用

实 验 报 告

课程:程序设计与数据结构

班级: 1623

姓名: 王旌含

学号:20162327

成绩:

指导教师:娄嘉鹏 王志强

实验密级: 非密级

预习程度: 已预习

实验时间:15:25-17:15

必修/选修: 必修

实验序号: cs_23

实验内容

  • 1.分析系统架构

  • 2.编译、运行、测试系统

  • 3.修改系统

  • 4.分析数据结构、排序、查找算法的应用

一、游戏架构分析

  • 游戏简介:点击游戏图标,第一个出线的界面就是游戏的主界面,界面上有四个按钮,分别是开始游戏、排行榜、选项和退出游戏。点击开始游戏按钮手机会弹出选择关卡界面(对应欢迎界面类);点击排行榜会弹出游戏的排行榜(这里会用到排序的相关知识);点击选项,会弹出声音设置以及制作人员的介绍;点击退出游戏则会直接退出游戏。目前在游戏中我们设置了十个关卡,点击对应关卡就会进入相应的游戏界面(对用选择关卡的类);游戏过程中会调用主界面类对玩家的每一步操作进行逻辑判断;通关后,会弹出胜利界面(对应胜利界面类)。游戏的大概过程就是这样的,下面会进行详细的介绍。

二、编译、运行、测试系统

  • 1、用Android将项目克隆指定的文件夹中

  • 2、编译

  • 3、运行

三、修改系统

  • 1、设置一个按钮,点击后显示学号信息

    在游戏的选项界面里加入一个按钮,按钮的名称为自己名字,然后在GameOption活动中获取按钮组件为按钮设置监听器,点击按钮时发出一条Tost消息显示学号。

  • 2、修改地图

    游戏中的地图是由16*16的二维矩阵完成的,其中1代表地板、2代表红点、3代表墙、4代表箱子、5代表搬运工,在矩阵中改变数组就会改变地图中现实的东西。

四、分析数据结构、排序、查找算法的应用

1、选择关卡的有关代码

  • 1、游戏选择关卡的界面是由一个网格布局完成的
<TextView
android:id="@+id/tv_select_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/select_level"
android:gravity="center"
android:textSize="24sp"
android:paddingBottom="12dp"/>
<GridView//网格布局
android:id="@+id/gv_levels"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:layout_below="@id/tv_select_level"
android:layout_centerHorizontal="true"
android:verticalSpacing="20dp"
android:horizontalSpacing="8dp"
android:gravity="center"> </GridView>
  • 2、加载网格布局后,按下关卡按钮后就会进行话地图等一系列操作
//加载布局
setContentView(R.layout.activity_game_level);
//添加到活动结束类
SysApplication.getInstance().addActivity(this);
GridView gv_levels = (GridView) findViewById(R.id.gv_levels);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.gv_levels_item_textview, GameLevels.getLevelList());
//网格加载适配器
gv_levels.setAdapter(arrayAdapter);
gv_levels.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(GameLevelActivity.this, GameActivity.class);
intent.putExtra(GameActivity.KEY_SELECTED_LEVEL, i + 1);
MainActivity.mediaPlayer.pause();
MainActivity.mediaPlayer2.start();
MainActivity.mediaPlayer2.setLooping(true);
startActivity(intent);
}
});

2、如何绘制游戏地图(这里用到了查找的有关知识)

  • 1、首先在GameLevels中制作好地图矩阵,每个数字代表的图片内容如下面的代码所示,代码中只表示了第一关的地图矩阵,后面的几个关卡类同。
public class GameLevels {
public static final int DEFAULT_ROW_NUM = 16;
public static final int DEFAULT_COLUMN_NUM = 16;
//游戏区单元格放了什么
public static int [] Steps;
public static final int FLOOR = 1; //地板
public static final int NOTHING = 0; //没有
public static final int BOX = 4; //该单元格放的是箱子
public static final int FLAG = 2; //红旗,表示箱子的目的地
public static final int MAN = 5; //搬运工
public static final int WALL = 3; //墙
public static final int MAN_FLAG = 5; //搬运工 + 小球
public static final int BOX_FLAG = 6; //箱子 + 小球 public static final int [][] LEVEL_1 = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 3, 0, 0, 0, 0},
{0, 0, 0, 0, 3, 3, 3, 4, 1, 4, 2, 3, 0, 0, 0, 0},
{0, 0, 0, 0, 3, 2, 1, 4, 5, 3, 3, 3, 0, 0, 0, 0},
{0, 0, 0, 0, 3, 3, 3, 3, 4, 3, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
  • 2、创建一个线性表,元素类型设为二位数组,将写好的游戏地图放入这个线性表中,在选择关卡界面选择关卡时,会在这个线性表中调取游戏地图
 public static ArrayList<int[][]> OriginalLevels = new ArrayList<>();

    public static void loadGameLevels(){
if (OriginalLevels.isEmpty()) {
OriginalLevels.add(LEVEL_1);
OriginalLevels.add(LEVEL_2);
OriginalLevels.add(LEVEL_3);
OriginalLevels.add(LEVEL_4);
OriginalLevels.add(LEVEL_5);
OriginalLevels.add(LEVEL_6);
OriginalLevels.add(LEVEL_7);
OriginalLevels.add(LEVEL_8);
OriginalLevels.add(LEVEL_9);
OriginalLevels.add(LEVEL_10);
}
} public static int [][] getLevel(int level){
loadGameLevels();
return OriginalLevels.get(level - 1);
}
  • 3、确定图片的大小及显示的区域,设置for循环来遍历地图矩阵,在每个数字对应的地方画上相应的图片,这样就画好了游戏地图
 private void drawGameBoard(Canvas canvas) {
Rect srcRect; //表示图片内部的区域
Rect destRect; //表示图片在屏幕中显示的区域
//得到表示局面的二维矩阵
int [][] labelInCells = mGameActivity.getCurrentState().getLabelInCells(); for (int r = 0; r < labelInCells.length; r++) //逐行地扫描矩阵
for (int c = 0; c < labelInCells[r].length; c++){ //对当前行r,逐列地扫描
destRect = getRect(r, c); //得到图片在屏幕中的显示区域
srcRect = new Rect(0, 0,GameBitmaps.FlagBitmap.getWidth(), GameBitmaps.FlagBitmap.getHeight());//获得显示图片的大小
switch (labelInCells[r][c]){
case 1:
canvas.drawBitmap(GameBitmaps.FloorBitmap,srcRect,destRect,null); //绘制地板
break;
case 2:
canvas.drawBitmap(GameBitmaps.FlagBitmap, srcRect, destRect, null); //绘制标记
break;
case 3:
canvas.drawBitmap(GameBitmaps.WallBitmap, srcRect, destRect, null); //绘制墙
break;
case 4:
canvas.drawBitmap(GameBitmaps.BoxBitmap, srcRect, destRect, null); //绘制箱子
break;
case 5:
canvas.drawBitmap(GameBitmaps.ManBitmap, srcRect, destRect, null); //绘制人
break;
case 6:
canvas.drawBitmap(GameBitmaps.ReadboxBitmap, srcRect, destRect, null); //绘制红箱子
break;
}
}
}

3、游戏按钮的支持代码

-1、绘制虚拟按钮,第一个参数是图片的来源,第二个参数是按钮的大小,第三个参数是按钮的位置

//绘制虚拟按钮
canvas.drawBitmap(GameBitmaps.UpBitmap,buttonRect,new Rect(2*width,getWidth(),3*width,getWidth()+hight),null); //绘制虚拟按键
canvas.drawBitmap(GameBitmaps.LeftBitmap,buttonRect,new Rect(width,getWidth()+hight,2*width,getWidth()+2*hight),null);
canvas.drawBitmap(GameBitmaps.OKBitmap,buttonRect,new Rect(4*width,0,5*width,hight),null);
canvas.drawBitmap(GameBitmaps.RightBitmap,buttonRect,new Rect(3*width,getWidth()+hight,4*width,getWidth()+2*hight),null);
canvas.drawBitmap(GameBitmaps.DownBitmap,buttonRect,new Rect(2*width,getWidth()+2*hight,3*width,getWidth()+3*hight),null);
  • 2、保存手触摸手机的位置
 public boolean onTouchEvent(MotionEvent event) {
//忽略Down, MOVE型的动作的处理
if(event.getAction() != MotionEvent.ACTION_UP || mGameActivity.getCurrentState().isGameOver())
return true;
//关卡数组的行
int r = mGameActivity.getCurrentState().getManRow();
//关卡数组的列
int c = mGameActivity.getCurrentState().getManColumn();
int touch_x = (int) event.getX(); //触摸点的x坐标
int touch_y = (int) event.getY(); //触摸点的y坐标
if (touch_blow_to_man(touch_x, touch_y,r ,c )) { //按下键
mGameActivity.getCurrentState().handleDown();
MainActivity.mediaPlayer4.start();
} if (touch_right_to_man(touch_x, touch_y,r ,c )) { //按右键
mGameActivity.getCurrentState().handleRight();
MainActivity.mediaPlayer4.start();
} if (touch_above_to_man(touch_x, touch_y,r ,c )) { //按上键
mGameActivity.getCurrentState().handleAbove();
MainActivity.mediaPlayer4.start();
} if (touch_left_to_man(touch_x, touch_y,r ,c )) {//按下键
mGameActivity.getCurrentState().handleLeft();
MainActivity.mediaPlayer4.start();
} if (touch_back_to_man(touch_x, touch_y,r ,c )) { //按重置键
mGameActivity.getCurrentState().handleback();
MainActivity.mediaPlayer3.start();
}
postInvalidate();
return true;
}
  • 3、判断手触摸的位置是否为按钮的位置,如果是则执行按钮的操作
//判断按键对象
private boolean touch_blow_to_man(int touch_x, int touch_y, int manRow, int manColumn) {
int width = (int) buttonWidth;
int hight = (int) buttonHight;
Rect belowRect = new Rect(2*width,getWidth()+2*hight,3*width,getWidth()+3*hight);
return belowRect.contains(touch_x, touch_y);
} private boolean touch_above_to_man(int touch_x, int touch_y, int manRow, int manColumn) {
int width = (int) buttonWidth;
int hight = (int) buttonHight;
Rect aboveRect = new Rect(2*width,getWidth(),3*width,getWidth()+hight);
return aboveRect.contains(touch_x, touch_y);
} private boolean touch_left_to_man(int touch_x, int touch_y, int manRow, int manColumn) {
int width = (int) buttonWidth;
int hight = (int) buttonHight;
Rect leftRect = new Rect(width,getWidth()+hight,2*width,getWidth()+2*hight);
return leftRect.contains(touch_x, touch_y);
} private boolean touch_right_to_man(int touch_x, int touch_y, int manRow, int manColumn) {
int width = (int) buttonWidth;
int hight = (int) buttonHight;
Rect rightRect = new Rect(3*width,getWidth()+hight,4*width,getWidth()+2*hight);
return rightRect.contains(touch_x, touch_y);
}
private boolean touch_back_to_man(int touch_x, int touch_y, int manRow, int manColumn) {
int width = (int) buttonWidth;
int hight = (int) buttonHight;
Rect rightRect = new Rect(4*width,0,5*width,hight);
return rightRect.contains(touch_x, touch_y);
}
 public void handleback() {//还原建的支持代码
for (int i = 0; i < mLabelInCells.length; i++)
for (int j = 0; j < mLabelInCells[i].length; j++) {
if(temp[i][j]==5){
mManRow = i;
mManColumn = j;
}
mLabelInCells[i][j] = temp[i][j];
}
steps = 0;
}

4、如何判断游戏是否通关以及胜利界面

  • 1、首先判断游戏是否通关,通关后通知通关。
//判断游戏是否通关
public boolean isGameOver(){
for(int i=0;i<mLabelInCells.length;i++)
for (int j=0;j<mLabelInCells[i].length;j++){
if(temp[i][j]==2 || temp[i][j]==6)
if (mLabelInCells[i][j]!=6)
return false;
}
return true;
}
//如果过关了,要报告过关
if(mGameActivity.getCurrentState().isGameOver()) {
Intent intent = new Intent(mContext,WinActivity.class);
GameLevels.Steps[mGameActivity.selected_level-1] = mGameActivity.getCurrentState().steps;
intent.putExtra("LV",mGameActivity.getIntent().getIntExtra(mGameActivity.KEY_SELECTED_LEVEL,1));
GameState.becom();
mGameActivity.startActivity(intent);
}
  • 2、弹出的胜利界面有两个按钮,左边的按钮是返回上一关,右边的是进入下一关,是最后一关,使用Toast显示出来。

5、音效的插入

  • 1、创建几个音乐播放器
mediaPlayer = MediaPlayer.create(this, R.raw.gameview);
mediaPlayer2 = MediaPlayer.create(this, R.raw.gaming);
mediaPlayer3 = MediaPlayer.create(this, R.raw.button);
mediaPlayer4 = MediaPlayer.create(this, R.raw.button2);
mediaPlayer5 = MediaPlayer.create(this, R.raw.success);
  • 2、音乐播放的切换功能,例如,打开游戏是一个音乐,进入游戏界面切换另一首音乐(就是音乐开始的时间和停止时间的设定)
 public void onPause() {
super.onPause();
MainActivity.mediaPlayer2.pause();
}
public void onStart() {
super.onStart();
if (!MainActivity.mediaPlayer2.isPlaying()){
MainActivity. mediaPlayer2.start();
}

7、排序算法的实现

  • 在排行榜的功能实现中会有体现,完成后补上。

20162327WJH实验五——数据结构综合应用的更多相关文章

  1. 2017-2018-2 1723《程序设计与数据结构》实验四 & 实验五 & 课程总结 总结

    作业地址 实验四作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1943 提交情况如图: 实验五作业:https://edu ...

  2. 20155324 《Java程序设计》实验五 网络编程与安全

    20155324 <Java程序设计>实验五 网络编程与安全 实验内容 任务一 编写MyBC.java实现中缀表达式转后缀表达式的功能 编写MyDC.java实现从上面功能中获取的表达式中 ...

  3. 20172308 实验五《Java面向对象程序设计 》实验报告

    20172308 2017-2018-2 实验五 <网络编程与安全>报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 周亚杰 学号:20172308 实验教师:王志 ...

  4. 实验五Java网络编程及安全

    实验五 Java网络编程及安全 结对伙伴:20135231林涵锦(负责服务器方)http://www.cnblogs.com/20135213lhj/  实验目的与要求: 1.掌握Java网络编程的方 ...

  5. 20162327WJH实验四——图的实现与应用

    20162327WJH实验四--图的实现与应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验日期:11月2 ...

  6. 20155201 实验五《Java面向对象程序设计》实验报告

    20155201 实验五<Java面向对象程序设计>实验报告 一.实验内容 1. 数据结构应用 2. 结对编程:利用IDEA完成网络编程任务,1人负责客户端,1人负责服务器 3. 密码结对 ...

  7. 20155318 《Java程序设计》实验五 (网络编程与安全)实验报告

    20155318 <Java程序设计>实验五 (网络编程与安全)实验报告 实验内容 了解计算机网络基础 掌握Java Socket编程 理解混合密码系统 掌握Java 密码技术相关API的 ...

  8. 20155334 实验五 Java网络编程及安全

    20155334 实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 实验1: 参考 结对实现中缀表达式转后缀表达式 ...

  9. 20162327WJH 实验三 《敏捷开发与XP实践》 实验报告

    20162327WJH 实验三 <敏捷开发与XP实践> 实验报告 一.实验内容 1.XP基础 2.XP核心实践 3.相关工具 二.实验要求 1.没有Linux基础的同学建议先学习<L ...

随机推荐

  1. CodeForces 724G: Xor-matic Number of the Graph

    题目传送门:CF724G. 题意简述: 一张 \(n\) 个点的无向图,边有边权. 定义三元组 \((u,v,w)(1\le u < v\le n)\) 合法当且仅当存在从点 \(u\) 到点 ...

  2. 【codeforces】【比赛题解】#849 CF Round #431 (Div.2)

    cf的比赛越来越有难度了……至少我做起来是这样. 先看看题目吧:点我. 这次比赛是北京时间21:35开始的,算是比较良心. [A]奇数与结束 "奇数从哪里开始,又在哪里结束?梦想从何处起航, ...

  3. 音频自动增益 与 静音检测 算法 附完整C代码【转】

    转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...

  4. OpenJDK,Oracle's OpenJDK,Oracle JDK的区别与选择

    OpenJDK 单纯的OpenJDK指的是JDK的源码,以GPL协议开源,由企业和社区开发者共同维护和开发. Oracle's OpenJDK Oracle started providing ope ...

  5. Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)

    本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...

  6. ThinkPHP联表查询

    $list = db($pnav['ename']) -> field('a.*,b.name as pname') ->alias('a') -> join('sbl_nav b' ...

  7. web文件<async-supported>错误分析

    <async-supported>true</async-supported> 出现 cvc-complex-type.2.4.a: Invalid content was f ...

  8. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  9. TeamViewer的下载地址,低调低调

    https://github.com/cary-zhou/TeamViewer13-Crack

  10. NSPredicate用法总结(Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取)

    简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...