五子棋课程实训报告文档格式.docx
- 文档编号:18321024
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:28
- 大小:483.63KB
五子棋课程实训报告文档格式.docx
《五子棋课程实训报告文档格式.docx》由会员分享,可在线阅读,更多相关《五子棋课程实训报告文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
00,
星期三上午8:
星期四上午8:
第十六周星期一一天,
星期二一天
一、课程实训的目的及要求-------------------------------------------6
二、游戏设计思路---------------------------------------------------7
三、主要功能实现---------------------------------------------------9
四、程序调试-------------------------------------------------------12
五、程序源代码-----------------------------------------------------13
六、总结-----------------------------------------------------------21
七、课程设计评分表-------------------------------------------------22
一、课程实训的目的及要求
本次课程实训是专门针对大四学生的一次项目实践,当前3G移动互联网发展迅速,而Android系统已经成为当前时期移动终端设备的主流操作系统之一,在这样的条件下计算机与通信学院组织这次基于Android系统的手机项目实战,紧跟当前时代电子通信业的发展,让学生学习当前主流的新技术,扩展学生们的视野,为即将大学毕业的我们进入社会求职开辟了一条新道路。
通过这次课程实训我们主要了解和掌握了以下内容:
(1)会在eclipse下搭建Android系统的开发环境;
(2)熟悉Android系统应用程序架构和代码编写;
(3)了解游戏开发的原理,能够解决游戏在不同屏幕上的移植问题;
(4)熟悉Android系统的线程机制和绘图原理;
(5)能够在eclipse中对Android系统应用程序进行调试;
二、游戏设计思路
1、游戏功能介绍
五子棋游戏通过黑白双方在固定大小的方格棋盘上进行交替落子,直到有一方在落下一棋子后在该棋子的周围形成垂直方向、水平方向、左上到右下方向或左下到右上方向形成有大于等于5个同样颜色棋子的一条直线,则执该颜色棋子的玩家赢得该棋局。
在我所设计的游戏中,主要的功能为:
人与人对弈,给出当前该谁进行落棋子的提示,在游戏结束时给出游戏结束的提示对话框,实现在游戏过程中(未结束)重新开始游戏的功能,实现游戏过程中退出游戏的功能。
2、游戏模块的划分
该游戏由于是人与人之间的对弈,因此逻辑比较简单,因而实现的模块划分也较简单。
这里的主要的模块有三部分:
一是坐标转换模块,将屏幕点击位置的像素坐标位置转换为棋盘上的棋子的坐标位置;
二是绘图模块,根据用户点击屏幕的位置,判断应该做出的响应并进行屏幕的重绘;
三是游戏结束的判断模块,当用户点击落下一个棋子后,立刻判断该棋子的落下是否决定了该棋局的胜负。
其它的小模块还有游戏的初始化,游戏的重置,游戏的退出模块。
游戏运行的界面如下所示:
、3.
、游戏结束时的界面4.
三、主要功能模块的实现.
1、坐标转换模块的实现
用户输入的操作为用户对屏幕的点击操作,而游戏中的棋盘为9*9方格落子点。
棋盘是一张填充整个屏幕的背景图片,为了使用户点击的位置能够与图片上的棋盘的位置相对应,这里需要对图片进行等比例缩放以适应不同分辨率的屏幕。
在我的开发过程中,我使用的屏幕的分辨率为320*480,在该屏幕的分辨率下求得缩放的比例。
背景图片如下:
图一:
背景图片
棋子图片如下(两个图片时分开的):
图二:
棋子图片
在求解缩放比例需要获知以下信息:
;
x0,y0))棋盘左上角落子位置的像素坐标(1(.
(2)棋盘水平相邻两个落子点的距离unitx;
(3)棋盘垂直相邻两个落子点的距离unity;
(4)手机屏幕的分辨率大小width,height;
我的比例数据的获取是在分辨率为320*480即width=320,height=480的环境下获取的缩放比例。
求解其他的数值过程如下:
【1】原点坐标比例的求解过程
将背景图片在手机屏幕上进行全屏显示,然后用点击屏幕上棋盘原点(左上角落棋子点),记录该点的水平和垂直方向的像素坐标,同样操作10次,求得平均值。
我的操作结果为:
水平像素值为:
x=16,垂直像素值为:
y=175.8;
则求得水平的比例为:
320/16=20,垂直比例为:
480/175.8=2.73;
在程序中的书写为:
//原点位置的缩放比例
privatefinalstaticfloatscaleX0=20f;
privatefinalstaticfloatscaleY0=2.73f;
则得原点坐标值为:
x0=width/scaleX0;
;
=height/scaleY0y0【2】棋盘格子的长(unitx)与宽(unity)的求解过程:
沿左上到右下对角线方向,从离棋盘原点一个格子的位置开始,依次点击落棋子的位置,分别对水平和垂直方向的格子求值,最后进行求平均值即可得到棋盘格子的大小。
在我的操作中最后求得的棋盘格子的缩放比为:
//棋盘点间距的缩放比例
privatefinalstaticfloatscaleUnitx=8.858f;
privatefinalstaticfloatscaleUnity=13.278f;
得棋盘格子的单元长度像素值为:
unitx=width/scaleUnitx;
=height/scaleUnityunity其他的一些缩放比例信息为:
(1)棋子图片一半的大小chessHx,chessHy;
用于绘制棋子图片时确定绘制点里棋子中心点的距离;
其求解过程为:
//设置棋子图片的一半的大小值
chessHx=whiteChess.getWidth()/2.0f;
.getHeight()/2.0f;
=whiteChesschessHy
(2)提示棋子的绘制坐标位置(notex,notey);
//设置提示棋子的位置
;
chessHx-unitx/2)*length[0].map+(x0=notex
长度这里为了视觉效果,减去了图片的1/4-chessHy/2;
//y0notey=-2*unity
2、绘图模块的实现
绘图模块是在独立的线程中完成,绘图顺序为:
先绘制背景(棋盘)图片,然后绘制提示棋子的图片,最后绘制已经落下的棋子的图片。
对于落下的棋子图片的绘制,这里根据棋子的棋盘坐标然后转换成屏幕的像素坐标来进行绘制。
这是因为在该游戏中,棋盘被抽象成了一个二维矩阵,每落下一子,就相应的修改矩阵的值,然后由绘图线程根据矩阵中的值进行相应的图片绘制。
由于绘制图片是根据图片的左上角坐标来绘制的,而我求解的棋盘落子的坐标是以棋子中心为参照的,因此绘制图片时需要减去棋子图片的1/2长度,这样图片才能被绘制到棋盘的正确位置。
3、游戏结束判断模块的实现
每一颗棋子的落下,都要对其对棋局的影响作出判断,以经过当前落子位置向水平方向、垂直方向、左上到右下方向和左下到右上方向向外扩展,若有一个方向上有连续的大于等于5个同样的棋子,则认为当前落子的用户赢得游戏。
对于每一个方向的判断是分为两部分的,例如对于水平方向,先统计当前落子点超左边方向上连续的棋子数,然后统计当前棋子超右边方向的连续的同种棋子的个数,最后将在两个数据加起来,如果和大于等于5,则认为赢。
四、程序调试
在调试的程序中我遇到了各种各样的问题,其中最典型的问题有:
画图问题。
SurfaceView)背景图片与1(.
(2)像素坐标到棋盘矩阵数组的转换问题。
(3)线程终止与同步问题。
在程序设计时,我本来的思路是为SurfaceView设置背景图片,这样在下棋操作中只需要对棋子进行绘制而不必重新绘制背景图片,但是这样做并不能达到效果,在程序运行中,背景图片会一直显示在屏幕上,但绘制的棋子确并不能够显示出来。
而在其他线程又是不能更改主线程的界面的数据的,所以只能在其他线程中对背景图片进行重绘。
在绘制背景图片的过程中,如果不对图片进行缩放绘制,即指定图片原始大小和绘制后的大小,那么就会导致背景图片在大于图片尺寸的屏幕上图片不能充满整个屏幕的问题。
像素坐标到二维数组的转换是另外一个问题,在转换的过程中很可能对坐标系的x/y与数组中的行和列相混淆。
坐标系中的x对应着二维数组的列,坐标系中的y对应着二维数组的行。
由于这个应用程序的棋盘是一个方形的棋盘(行和列相等),因此这个错误并不会明显对程序的运行造成结果,但如果该应用程序棋盘不是方形的,那么程序运行就会出现错误。
在一盘棋结束后,应用程序会让用户选择将要采取的动作,是再玩儿一次还是退出应用程序。
在退出应用程序之前,必须要停止绘图的线程。
而通过Thread类的interupte方法是不能够停止线程的运行的,因此在程序中,我使用了一个棋局状态标志,绘图线程每次重绘之前都判断当前棋局是否结束,如果棋局已经结束,就不会进入绘图循环,从而跳出run()方法,结束线程的运行。
在线程同步方面,还有一个问题,如果下棋子太快,在已经有5个棋子连成一条线(即游戏处理结束状态)时,继续下棋子,还会有一个棋子显示在棋盘上,然后才会给出该棋局结束的提示。
这是由于棋子落下后,判断输赢状态耗费时间较长所导致的。
对于用户的每一次落子,都会判断该棋子的落下对棋局的影响。
如果该判断还未结束,而用户又下了另一个棋子,则该棋子就会改变棋盘上棋子的覆盖状态。
而绘图线程对棋盘的绘制是很快的,如果棋局已经结束而消息并为及时发送到绘图线程并且用户的下一次点击操作又已经改变了棋盘的状态,那么就会出现多绘一个棋子,甚至几个棋子的情况。
这种情况我现在还未找到适合的解决方法。
五、程序源代码
1、主Activity的代码如下:
packagehnie.zj.fivechess;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.view.Display;
importandroid.view.Window;
importandroid.view.WindowManager;
publicclassMainActivityextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
//隐藏标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//获取屏幕宽高
Displaydisplay=getWindowManager().getDefaultDisplay();
GameViewgameView=new
GameView(this,display.getWidth(),display.getHeight());
setContentView(gameView);
}
}
2、游戏界面操作View如下:
(GameView)
importandroid.app.AlertDialog;
importandroid.content.Context;
importandroid.content.DialogInterface;
importandroid.content.res.Resources;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.Paint;
importandroid.graphics.Rect;
importandroid.graphics.RectF;
importandroid.view.MotionEvent;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
publicclassGameViewextendsSurfaceViewimplements
SurfaceHolder.Callback,Runnable{
privateSurfaceHolderholder;
privatePaintpaint;
privateResourcesres;
privateContextcontext;
booleanwinState=false;
privateBitmapbackgroundPicture;
privateBitmapwhiteChess;
privateBitmapblackChess;
privateCanvasmCanvas;
privatefloatx0,y0;
//原点坐标的像素值
privatefloatunitx,unity;
//每个单元的横、竖像素值大小
privatefinalstaticfloatscaleUnity=13.278f;
//设置棋子图片的一半的大小
privatestaticfloatchessHx=0f;
privatestaticfloatchessHy=0f;
//设置提示棋子的位置坐标
privatestaticfloatnotex=0f;
privatestaticfloatnotey=0f;
privateRectsrc;
privateRectFdes;
//地图棋子分布数组
privateint[][]map;
publicGameView(Contextcontext,intwidth,intheight){
super(context);
this.context=context;
y0=height/scaleY0;
unity=height/scaleUnity;
des=newRectF(0,0,width,height);
map=newint[9][9];
holder=this.getHolder();
holder.addCallback(this);
//设置画笔
paint=newPaint();
paint.setAntiAlias(true);
//消除锯齿
res=getResources();
init();
setFocusable(true);
privatevoidinit(){
//初始化3张位图图片
backgroundPicture=BitmapFactory.decodeResource(res,
R.drawable.status);
//初始化背景图片原始矩形大小
src=new
Rect(0,0,backgroundPicture.getWidth(),backgroundPicture.getHeight());
whiteChess=BitmapFactory.decodeResource(res,R.drawable.human);
blackChess=BitmapFactory.decodeResource(res,R.drawable.ai);
chessHy=whiteChess.getHeight()/2.0f;
notex=x0+(map[0].length/2)*unitx-chessHx;
notey=y0-2*unity-chessHy/2;
//这里为了视觉效果,减去了图片的1/4长度
publicvoidrun(){
while(!
winState){
mCanvas=holder.lockCanvas();
//画背景图片
mCanvas.drawBitmap(backgroundPicture,src,des,paint);
//画提示棋子图片
if(isWhite){
mCanvas.drawBitmap(whiteChess,notex,notey,paint);
}else{
mCanvas.drawBitmap(blackChess,notex,notey,paint);
for(inti=0;
i<
map.length;
i++){
for(intj=0;
j<
map[0].length;
j++){
if(map[i][j]==1){
drawAt(mCanvas,whiteChess,i,j);
}elseif(map[i][j]==2){
drawAt(mCanvas,blackChess,i,j);
holder.unlockCanvasAndPost(mCanvas);
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
intheight){
//TODOAuto-generatedmethodstub
publicvoidsurfaceCreated(SurfaceHolderholder){
newThread(this).start();
publicvoidsurfaceDestroyed(SurfaceHolderholder){
publicbooleanonTouchEvent(MotionEventevent){
floatx=event.getX();
floaty=event.getY();
if((x>
x0+unitx*5.5)&
&
(y<
1.4*unity)){//点击了”退出“位置
stop();
if((x<
x0+2.5*unitx)&
1.4*unity)){//点击了”重玩“位置
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 五子棋 课程 报告