版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
..绪论项目背景本题目将设计一个俄罗斯方块〔Tetris,俄文:Тетрис。它是一款风靡全球的电视游戏机和掌上游戏机游戏,由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。开发平台此项目基于android环境进行开发,使用的编程工具为eclipse,它是以android语言作为其基本语言的一种可视化编程工具。Android是Google开发的基于Linux平台的开源手机操作系统.Android四大基本组件分别是Activity,Service服务,ContentProvider内容提供者,BroadcastReceiver广播接收器。应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。你的应用可以使用它对外部事件进行过滤只对感兴趣的外部事件<如当呼入时,或者数据网络可用时>进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。一个Service是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。android平台提供了ContentProvider使一个应用程序的指定数据集提供给其他应用程序。 注:Activity生命周期项目规则及设计思路项目规则玩家通过点触虚拟键盘,左右控制方块左右移动,按上代表旋转,按下代表加速向下移动,每满一行消除,获得相应积分100,积分每增长2000,等级加1,游戏速度加快实现思路界面设计游戏菜单界面游戏菜单界面游戏结束界面游戏运行界面排行榜界面帮助界面游戏结束界面游戏运行界面排行榜界面帮助界面注:游戏界面中,利用二维数组进行保存,其值为1代表该点有方块占用,值为0代表空白,根据值绘制整张游戏窗口。功能设计从游戏的基本玩法出发,主要算法在于俄罗斯方块的形状和旋转。在游戏设计中,方块采用最基本的7种造型,包括长条型,正方型,正S型,反S型,正7型,反7型,T型,每种造型又可以通过逆时针旋转变化出4种形状,因此利用三维数组保存28种方块形状,并且编号为K~K+3<K=0,1…7>的四个形状为一组。方块采用4*4的二维数组的数据结构,以此在界面中根据其数组对应值进行方块绘制。在旋转过程进行之前,先判断在该位置能否进行旋转,若能,则将其在三维数组中的编号K,编号为K+<K+1>%4的形状即为旋转结果。游戏过程中,利用随机函数在一个预览窗体中提前展示形状供用户参考,然后将展示的形状复制到游戏窗体中进行摆放,在游戏窗体中用户就可以使用键盘的方向键来控制方块的运动,然后对每一行进行判断,如果有某行的方块是满的,则消除这行的方块,并且使上面的方块自由下落,其中,方块向下的速度通过调用函数进行控制。同时用户也可以使用向下键加快下落速度,定义一个变量,对消除的行数进行记录,最后得出用户的分数,用条件语句对分数进行判断,达到一定的积分就可以升级到下一个等级。程序流程图总流程到达底部部到达底部部到底游戏结束到达底部部结束销行操作生成下一个下坠物将新生的下坠物代替旧的"下一个下坠物"将旧的"下一个下坠物"用作当前下坠物销行操作游戏结束处理下降一个单位开始底部到达的判断与销行的实现:是是否堆积方块,判断接触面状态及是否得分2.统计分数判断是否过关关数增加,游戏速度将变快。开始新的一关,继续游戏游戏窗口重绘1.判断行满、处理销行、堆积方块向下移动将新的下坠物放置到游戏区域中去,这时可能出现马上到达底部的情况,因此需要对它进行判断,如果是到达底部,则进行销行处理,并且修改相应的数据状态。而判断是否已经到达了底部,可以通过当前下坠物件所对应的接触面的方块位置为被占用状态来确定。统计分数:在消行处理里面有一个专门用来统计消行数的变量,然后根据变量的值决定分数的多少。如果总分数达到过关条件就过关,改变游戏速度,开启新的一关,然后再加载方块。没有达到过关分数或者没有满行,则加载下一个方块继续游戏。是是否是否否是是否接上图1点底行判断当前行是否为空判断当前行是否为满判断是否有满行判断移动行方块是否为空当前行向上推动一行将要移动行所有数据移至当前行将当前行的所有数据初始化统计连续几行为满如果有销行,则刷新游戏区域。接上图2点随机方块的产生是是否7654321随机抽取一个数随机数一字形田字形L形J形T形S形Z字形型游戏是否结束保存当前方块坐标显示方块于屏幕上游戏结束保存信息关数初始化返回开始界面部分截图 5.1初始界面 5.2游戏界面 5.3帮助界面 5.4排行界面关键代码ActivityGame.javapackagecom.HDU.tetris;importandroid.app.Activity;importandroid.app.AlertDialog;importandroid.app.Dialog;lertDialog.Builder;importandroid.content.Intent;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.Window;publicclassActivityGameextendsActivity{ //总游戏窗口 privatestaticfinalStringTAG="ActivityGame"; TetrisViewmTetrisView=null; //处理游戏进程的类 publicvoidonCreate<Bundlesaved> //创建活动 { super.onCreate<saved>;//启动窗体的拓展特性 requestWindowFeature<Window.FEATURE_NO_TITLE>; init<>; } privatevoidinit<> { mTetrisView=newTetrisView<this>; Intentintent=getIntent<>; //得到当前的intent//获取额外信息——等级 intlevel=intent.getIntExtra<ActivityMain.LEVEL,1>; mTetrisView.setLevel<level>; //设置等级 intflag=intent.getFlags<>; //得到当前intent的标记符 if<flag==ActivityMain.FLAG_CONTINUE_LAST_GAME> {//当遇到继续上次游戏事件 mTetrisView.restoreGame<>; //恢复上次游戏 }//得到当前声音设置 booleanisVoice=intent.getBooleanExtra<ActivityMain.VOICE,true>; mTetrisView.setVoice<isVoice>; //设置声音 setContentView<mTetrisView>; //设定当前使用的视图 } publicvoidonPause<> //暂停活动 { mTetrisView.onPause<>; super.onPause<>; } publicvoidonResume<>//执行活动 { super.onResume<>; mTetrisView.onResume<>; } publicvoidonStop<> //停止活动 { super.onStop<>; mTetrisView.saveGame<>; //保存游戏 mTetrisView.freeResources<>; //释放游戏占用的资源 }}ActivityHelp.javapackagecom.HDU.tetris;importandroid.app.Activity;importandroid.os.Bundle;publicclassActivityHelpextendsActivity{ //帮助窗口 publicvoidonCreate<Bundlesaved> //开始 { super.onCreate<saved>; setContentView<R.layout.help>; //初始化帮助窗口的界面 }}ActivityMain.javapackagecom.HDU.tetris;//Author:HDU//2010.3importandroid.app.Activity;importandroid.content.Intent;importandroid.content.SharedPreferences;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;importandroid.widget.CheckBox;importandroid.widget.TextView;publicclassActivityMainextendsActivity{ publicstaticfinalintFLAG_NEW_GAME=0; //开始新游戏 publicstaticfinalintFLAG_CONTINUE_LAST_GAME=1; //继续上一次的游戏 publicstaticfinalStringFILENAME="settingInfo";//文件名 publicstaticfinalStringLEVEL="level"; //游戏级别 publicstaticfinalStringVOICE="voice"; //游戏声音 privateintmLevel=1; //当前游戏等级 privateButtonbtNewgame=null; //新游戏按钮 privateButtonbtContinue=null; //继续游戏按钮 privateButtonbtHelp=null; //帮助按钮 privateButtonbtRank=null; //排名按钮 privateButtonbtPre=null; //等级下降按钮 privateButtonbtNext=null; //等级上升按钮 privateButtonbtExit=null; //退出按钮 privateTextViewtvLevel=null; //等级编辑框 privateCheckBoxcbVoice=null; //声音选项/**Calledwhentheactivityisfirstcreated.*/OverridepublicvoidonCreate<BundlesavedInstanceState>{ //创建,程序执行时的第一步super.onCreate<savedInstanceState>;setContentView<R.layout.menu>; //设置开始界面的菜单btNewgame=<Button>findViewById<R.id.bt_new>;//通过ID查找新游戏按钮在VIEW子控件btContinue=<Button>findViewById<R.id.bt_continue>;//继续游戏按钮控件btHelp=<Button>findViewById<R.id.bt_help>; //帮助按钮控件btRank=<Button>findViewById<R.id.bt_rank>; //排名按钮控件btPre=<Button>findViewById<R.id.bt_pre>; //等级下降按钮控件btNext=<Button>findViewById<R.id.bt_next>; //等级上升按钮控件btExit=<Button>findViewById<R.id.bt_exit>; //退出按钮控件tvLevel=<TextView>findViewById<R.id.tv_speed>;//等级编辑框控件cbVoice=<CheckBox>findViewById<R.id.cb_voice>;//声音选项框控件btNewgame.setOnClickListener<buttonListener>;//在新游戏按钮上设置点击监听器btContinue.setOnClickListener<buttonListener>;//在继续游戏按钮上设置点击监听器btHelp.setOnClickListener<buttonListener>; //在帮助按钮上设置点击监听器btRank.setOnClickListener<buttonListener>; //在排名按钮上设置点击监听器btPre.setOnClickListener<buttonListener>; //在等级下降按钮设置点击监听器btNext.setOnClickListener<buttonListener>; //在等级上升按钮上设置点击监听器btExit.setOnClickListener<buttonListener>; //在退出按钮上设置点击监听器restoreSettings<>; //恢复初始设置}privateButton.OnClickListenerbuttonListener=newButton.OnClickListener<>{ //按钮上的点击监听器类 Override publicvoidonClick<Viewv>{ //按钮点击时的处理程序 if<v==btNewgame> //当被点击的按钮为新游戏按钮时 { Intentintent=newIntent<ActivityMain.this,ActivityGame.class>;//在两个Activity类之间传输数据 intent.setFlags<FLAG_NEW_GAME>; //设置标记符 intent.putExtra<VOICE,cbVoice.isChecked<>>; //添加声音的附加信息 intent.putExtra<LEVEL,mLevel>; //添加等级的附加信息 startActivity<intent>; //将此intent类传入相应的Activity中 return; } if<v==btContinue> //继续游戏按钮处理程序 { Intentintent=newIntent<ActivityMain.this,ActivityGame.class>;//建立intent类 intent.setFlags<FLAG_CONTINUE_LAST_GAME>; //设置标记符intent.putExtra<VOICE,cbVoice.isChecked<>>; //添加声音选项的附加信息 startActivity<intent>; //将此intent类传入相应的Activity中 return; } if<v==btHelp> //帮助按钮的处理程序 { Intentintent=newIntent<ActivityMain.this,ActivityHelp.class>;//建立intent类 startActivity<intent>; //将此intent类传入相应的Activity中 return; } if<v==btRank> //排名按钮的处理程序 { Intentintent=newIntent<ActivityMain.this,ActivityRank.class>;//建立intent类 startActivity<intent>; //将此intent类传入相应的Activity中 return; } if<v==btPre> //等级下降按钮的才护理程序 { btPre.setBackgroundColor<0xffc0c0c0>; //设置背景颜色 Strings=tvLevel.getText<>.toString<>; //从等级编辑框中获取信息,传入字符串中 intlevel=Integer.parseInt<s>; //将获取的字符串转化为数字 --level; //等级减1 level=<level-1+TetrisView.MAX_LEVEL>%TetrisView.MAX_LEVEL;//避免等级益处标准范围,形成循环设置 ++level;//等级加1,从0~5改为标准的1~6 s=String.valueOf<level>; //将数字转化为字符串,传回 tvLevel.setText<s>;//等级编辑框的内容显示为新的等级数 mLevel=level;//当前等级改为设置的等级 btPre.setBackgroundColor<0x80cfcfcf>; //设置背景颜色 return; } if<v==btNext> //等级上升按钮的处理程序 { btNext.setBackgroundColor<0xffc0c0c0>; //设置背景颜色 Strings=tvLevel.getText<>.toString<>; //从等级编辑框中获取信息,传入字符串中 intlevel=Integer.parseInt<s>; //将获取的字符串转化为数字 --level;//等级减1 level=<level+1>%TetrisView.MAX_LEVEL; //避免等级益处标准范围,形成循环设置 ++level;//等级加1,从0~5改为标准的1~6 s=String.valueOf<level>; //将数字转化为字符串,传回 tvLevel.setText<s>; //等级编辑框的内容显示为新的等级数 mLevel=level; //当前等级改为设置的等级 btNext.setBackgroundColor<0x80cfcfcf>; //设置背景颜色 return; } if<v==btExit> //退出按钮的处理程序 { ActivityMain.this.finish<>; //结束该活动 } }};privatevoidsaveSettings<> //保存设置方法{//SharedPreferences是轻量级的存储类,主要是保存一些常用的配置 SharedPreferencessettings=getSharedPreferences<FILENAME,0>;//得到当前设置信息 settings.edit<> .putInt<LEVEL,mLevel> .putBoolean<VOICE,cbVoice.isChecked<>> mit<>; //将各种信息保存如settings中,完成更新设置}privatevoidrestoreSettings<> //恢复初始设置{ SharedPreferencessettings=getSharedPreferences<FILENAME,0>;//得到当前设置信息 mLevel=settings.getInt<LEVEL,1>; //等级恢复为1 booleanhasVoice=settings.getBoolean<VOICE,true>; tvLevel.setText<String.valueOf<mLevel>>; // 显示初始等级到等级编辑框中 cbVoice.setChecked<hasVoice>; // 声音设置为开启}publicvoidonStop<> //活动停止方法{ super.onStop<>; saveSettings<>; //保存当前设置}}ActivityRank.javapackagecom.HDU.tetris;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.ListView;importandroid.widget.SimpleAdapter;importandroid.widget.SimpleCursorAdapter;publicclassActivityRankextendsActivity{ //排名窗口 privateRankDatabasemDatabase=null; //数据库信息//通过ListView控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本。 privateListViewmListView=null; publicvoidonCreate<Bundlesaved> //创建该活动 { super.onCreate<saved>; setTitle<"排行榜">; //显示标题nk>; //设置窗口初始化信息 } }Court.javapackagecom.HDU.tetris;importandroid.content.Context;importandroid.graphics.Canvas;importandroid.graphics.Color;importandroid.graphics.Paint;publicclassCourt{ //游戏窗口 publicfinalstaticintCOURT_WIDTH=11;//窗口的宽度 publicfinalstaticintCOURT_HEIGHT=23+4; //窗口的高度 publicfinalstaticintBLOCK_WIDTH=20; //每个格子的宽度 publicfinalstaticintBLOCK_HEIGHT=20; //每个格子的高度 publicfinalstaticintABOVE_VISIBLE_TOP=4; //允许显示的最高点 publicfinalstaticintBEGIN_DRAW_X=0; //开始画图的坐标 publicfinalstaticintBEGIN_DRAW_Y=TetrisView.SCREEN_HEIGHT-Court.BLOCK_WIDTH*Court.COURT_HEIGHT; privateint[][]mCourt=newint[COURT_WIDTH][COURT_HEIGHT];//保存窗口信息的数组 privateContextmContext=null; //context的作用,就是android应用连接service的桥梁。 privateResourceStoremRs=null; //应用环境中的资源信息 publicCourt<Contextcontext> { mContext=context; //保存应用环境全局信息 mRs=newResourceStore<context>; //获取应用环境中的资源信息 clearCourt<>; //清空游戏窗口 } publicvoidclearCourt<> //清除窗口信息 { inti,j; for<i=0;i<COURT_WIDTH;i++>//遍历窗口所有的点 { for<j=0;j<COURT_HEIGHT;j++> { mCourt[i][j]=0;//将相应数组信息清空 } } } publicbooleanisGameOver<> //判断游戏是否结束 { for<inti=0;i<COURT_WIDTH;i++> {//其中某一行的方块到达可允许显示的最高点,则游戏结束 if<mCourt[i][ABOVE_VISIBLE_TOP]!=0> returntrue; } returnfalse; } publicbooleanisSpace<intposX,intposY>//判断该点是否为空 { if<posX<0||posX>=COURT_WIDTH>//超出行边界线出错 returnfalse; if<posY<0||posY>=COURT_HEIGHT>//超出列边界线出错 returnfalse; if<0==mCourt[posX][posY]>//对应数组的值为0,即为空 returntrue; returnfalse; } publicbooleanavailableForTile<int[][]tile,intx,inty>//判断该格子能否放方块 { for<inti=0;i<4;i++>{//遍历所有点 for<intj=0;j<4;j++>{ if<tile[i][j]!=0>{ if<!isSpace<x+i,y+j>>{//该点已经有方块占据 returnfalse; } } } } returntrue; } publicvoidplaceTile<TileViewtile>//放置方块 { inti,j; for<i=0;i<4;i++> { for<j=0;j<4;j++> { if<tile.mTile[i][j]!=0>//没有被占据 {//窗口中该点的位置放置相应的方块 mCourt[tile.getOffsetX<>+i][tile.getOffsetY<>+j]=tile.getColor<>; } } } } publicintremoveLines<>//消除完成了的一整行 { inthigh=0; intlow=COURT_HEIGHT; // 初始最低点 high=highestFullRowIndex<>; //得到可消除的最高行数 low=lowestFullRowIndex<>; //得到可消除的最低行数 intlineCount=low-high+1; //可消除的总行数 if<lineCount>0> //存在可消除的行 { eliminateRows<high,lineCount>; //消除找到的可消除的行 returnlineCount; //返回消除的行数 } return0; } privatevoideliminateRows<inthighRow,introwAmount>//消除已完成的行上的方块 { inti,j; for<i=highRow+rowAmount-1;i>=rowAmount;i--> { for<j=0;j<COURT_WIDTH;j++> {//将待消除行上方的方块整体向下移动,覆盖待消除的行 mCourt[j][i]=mCourt[j][i-rowAmount]; } } } privateinthighestFullRowIndex<>//查找已完成行的最高行数 { intresult=0; booleanremoveable=true; //标记是否可以消除 inti,j; for<i=0;i<COURT_HEIGHT;i++> //从上往下遍历 { removeable=true; for<j=0;j<COURT_WIDTH&&removeable;j++> { if<isSpace<j,i>> //该点上没有方块 { result++; removeable=false; //标记该行不可消除 } } if<removeable> //可消除,则找到结果,退出 break; } returnresult; } privateintlowestFullRowIndex<>//查找已完成行的最低行数 { intresult=COURT_HEIGHT-1; //初始最低点 booleanremoveable=true; inti,j; for<i=COURT_HEIGHT-1;i>=0;i-->//从下往上遍历 { removeable=true; for<j=0;j<COURT_WIDTH&&removeable;j++> { if<isSpace<j,i>> //该点上没有方块 { result--; removeable=false; //标记该行不可消除 } } if<removeable> //可消除,则找到结果,退出 break; } returnresult; } privatevoidremoveSingleLine<intlineIndex,inttime>//消除单行 { intt,i,j; for<t=0;t<time;t++> { for<i=lineIndex;i>0;i-->//将待消除行上方的方块全部向下移动一行 { for<j=0;j<COURT_WIDTH;j++> { mCourt[j][i]=mCourt[j][i-1];//上一行覆盖下一行 } } } } publicvoidpaintCourt<Canvascanvas> //根据画布信息画游戏窗口 {//Paint中包含了很多方法对其属性进行设置,绘制时所使用的画笔 Paintpaint=newPaint<>; paint.setAlpha<0x60>; //设置Alpha值//对图片添加透明效果 canvas.drawBitmap<mRs.getCourtBackground<>,0,0,paint>; paint.setAlpha<0xee>; for<inti=0;i<Court.COURT_WIDTH;i++> { for<intj=0;j<Court.COURT_HEIGHT;j++> { if<mCourt[i][j]!=0> {//画出各个小方格 canvas.drawBitmap<mRs.getBlock<mCourt[i][j]-1>,BEGIN_DRAW_X+i *Court.BLOCK_WIDTH,BEGIN_DRAW_Y+j*Court.BLOCK_WIDTH,paint>; } } } } publicint[][]getMatrix<> //得到游戏窗口的数组 { returnmCourt; }}DrawTool.javapackagecom.HDU.tetris;importandroid.graphics.Bitmap;importandroid.graphics.Canvas;publicclassDrawTool{ publicstaticvoidpaintImage<Canvascanvas,Bitmapbitmap,intx,inty> { canvas.drawBitmap<bitmap,x,y,null>; //在指定位置绘制图象 }}MusicPlayer.javapackagecom.HDU.tetris;importandroid.content.Context;importandroid.media.MediaPlayer;publicclassMusicPlayer{ privateMediaPlayermMoveVoice=null; //创建移动时的声音类 privateMediaPlayermBombVoice=null; //创建炸毁时的声音类 privatebooleanmIsMute=false; publicMusicPlayer<Contextcontext> { mMoveVoice=MediaPlayer.create<context,R.raw.move>;//指定相应的音乐 mBombVoice=MediaPlayer.create<context,R.raw.bomb>; } publicvoidplayMoveVoice<> { if<mIsMute> return; mMoveVoice.start<>;//开始播放音乐 } publicvoidplayBombVoice<> { if<mIsMute> { return; } mBombVoice.start<>;//开始播放音乐 } publicvoidsetMute<booleanb>//设置变量的值 { mIsMute=b; } publicvoidfree<> //释放 { mMoveVoice.release<>; //结束该类的生命周期 mBombVoice.release<>; }}RankDatabase.javapackagecom.HDU.tetris;importandroid.content.Context;importandroid.database.Cursor;importandroid.database.sqlite.SQLiteDatabase;importandroid.database.sqlite.SQLiteOpenHelper;.SQLiteDatabase.CursorFactory;publicclassRankDatabase{ privatestaticfinalStringTAG="RankDatabase"; //标记 privatestaticfinalStringDB_NAME="rank.db"; //数据库名 privatestaticfinalStringDB_TABLE="table1"; //数据库表格 privatestaticfinalintDB_VERSION=1; //数据库视图 privatestaticfinalStringKEY_ID="_id"; //id publicstaticfinalStringKEY_RANK="rank"; //排名 publicstaticfinalStringKEY_SCORE="score"; //成绩 publicstaticfinalStringKEY_NAME="name"; //用户名字 privatestaticfinalStringDB_CREATE="CREATETABLE" +DB_TABLE+"<" +KEY_ID+"INTEGERPRIMARY_KEY," +KEY_RANK+"INTEGER," +KEY_SCORE+"INTEGER" +KEY_NAME+"TEXT>"; //数据库查询语句 privateContextmContext=null; //应用环境全局信息 privateSQLiteDatabasemDatabase=null; ////用于管理和操作SQLite数据库 privateDatabaseHelpermHelper=null; //数据库连接字符串 publicvoidRankDatabase<Contextcontext> { mContext=context; //保存应用环境 } privatestaticclassDatabaseHelperextendsSQLiteOpenHelper { publicDatabaseHelper<Contextcontext>//管理相应的数据库 { super<context,DB_NAME,null,DB_VERSION>; } Override publicvoidonCreate<SQLiteDatabasedb> //创建活动 { db.execSQL<DB_CREATE>; //执行数据库语句 } Override publicvoidonUpgrade<SQLiteDatabasedb,intoldVersion,intnewVersion>//数据库升级 { } } publicvoidopen<> //打开数据库 { mHelper=newDatabaseHelper<mContext>;//建立数据库管理 mDatabase=mHelper.getWritableDatabase<>;//得到可写数据库 } publicvoidclose<> //关闭数据库 { mHelper.close<>;//关闭数据库管理 }}RefreshHandle.javapackagecom.HDU.tetris;importandroid.os.Handler;importandroid.os.Message;importandroid.util.Log;classRefreshHandlerextendsHandler{ finalstaticintMESSAGE_REFRESH=0xeeeeeeee; finalstaticintDELAY_MILLIS=100; //延迟时间 TetrisViewmV=null; //游戏视图 booleanmIsPaused=false; //暂停标记 publicRefreshHandler<TetrisViewv> //构造函数 { super<>; mV=v; } publicvoidhandleMessage<Messagems> //信息处理 { if<!mIsPaused> //不是暂停状态 { if<ms.what==MESSAGE_REFRESH>//消息编码更新时 { mV.logic<>; // mV.invalidate<>; //重绘游戏窗口 } } } publicvoidpause<> //暂停活动 { mIsPaused=true; //标记为暂停 } publicvoidresume<> //恢复运行 { mIsPaused=false; //改变暂停标记 }}ResourceStore.javapackagecom.HDU.tetris;importandroid.content.Context;importandroid.content.res.Resources;importandroid.graphics.Bitmap;importandroid.graphics.Canvas;importandroid.graphics.drawable.BitmapDrawable;importandroid.graphics.drawable.Drawable;//ResourceStore是一个SingletonpublicclassResourceStore{ privatestaticBitmapmBackground=null; //背景图片 privatestaticBitmap[]mBlocks=null; //方块图片 privatestaticBitmapmMenuBackground=null; //菜单背景图片 privatestaticBitmapmMenu=null; //菜单图片 privatestaticBitmapmSpeed=null; //速度 privatestaticBitmapmLine=null; // privatestaticBitmapmScore=null; //分数 privatestaticBitmapmGameover=null; //游戏结束 privateContextmContext=null; //应用环境全局信息 privateResourcesmR=null; //资源 publicResourceStore<Contextcontext> { mContext=context; mR=mContext.getResources<>;//得到资源//创建各个图片 if<mBackground==null> mBackground=createImage<mR.getDrawable<R.drawable.courtbg>,Court.COURT_WIDTH*Court.BLOCK_WIDTH,TetrisView.SCREEN_HEIGHT>; if<mMenuBackground==null> mMenuBackground=createImage<mR.getDrawable<R.drawable.menubg>,TetrisView.SCREEN_WIDTH,TetrisView.SCREEN_HEIGHT>; if<mMenu==null> mMenu=createImage<mR.getDrawable<R.drawable.menu>,200,100>; if<mSpeed==null> mSpeed=createImage<mR.getDrawable<R.drawable.speed>,200,100>; if<mLine==null> mLine=createImage<mR.getDrawable<R.drawable.line>,200,100>; if<mScore==null> mScore=createImage<mR.getDrawable<R.drawable.score>,200,100>; if<mGameover==null> mGameover=createImage<mR.getDrawable<R.drawable.gameover>,200,100>; if<mBlocks==null> //装载方块图片 { mBlocks=newBitmap[8]; for<inti=0;i<8;i++> { mBlocks[i]=createImage<mR.getDrawable<R.drawable.block0+i>,Court.BLOCK_WIDTH,Court.BLOCK_WIDTH>; } } } publicBitmapgetCourtBackground<> //获取游戏场地背景图片信息 { returnmBackground; //返回对应图片ID } publicBitmapgetMenuBackground<> //获取菜单背景图片信息 { returnmMenuBackground; } publicBitmapgetMenu<> //获取菜单图片信息 { returnmMenu; } publicBitmapgetBlock<intindex> //获取方块图片信息 { returnmBlocks[index]; } publicBitmapgetGameover<> //获取游戏结束图片信息 { returnmGameover; } publicvoidloadImage<intindex,Bitmapbitmap> //根据索引值装载图片 {//获取资源中的图片 bitmap=<<BitmapDrawable>mContext.getResources<>.getDrawable<index>>.getBitmap<>; } publicstaticBitmapcreateImage<Drawabletile,intw,inth>{ //根据参数创建新位图 Bitmapbitmap=Bitmap.createBitmap<w,h,Bitmap.Config.ARGB_8888>;//以bitmap对象创建一个画布,则将内容都绘制在bitmap上 Canvascanvas=newCanvas<bitmap>; tile.setBounds<0,0,w,h>;//对可画的对象设置大小 tile.draw<canvas>; //将可画对象显示到画布上 returnbitmap; }}TerisView.javapackagecom.HDU.tetris;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.util.Properties;importandroid.content.Context;import;importandroid.graphics.Canvas;importandroid.graphics.Color;importandroid.graphics.Paint;importandroid.os.Message;import;importg;importandroid.view.KeyEvent;importandroid.view.View;publicclassTetrisViewextendsViewimplementsRunnable{finalstaticintSCREEN_WIDTH=320;//设置游戏界面的宽为320像素finalstaticintSCREEN_HEIGHT=455;//设置游戏界面的高为455像素finalintSTATE_MENU=0;//设置菜单的状态值为0finalintSTATE_PLAY=1;//设置开始游戏的状态值为1finalintSTATE_PAUSE=2;//设置暂停的状态值为2finalintSTATE_OVER=3;//设置游戏结束的状态值为3publicstaticfinalintMAX_LEVEL=6;//最大游戏等级为6//初始化两个字符串publicstaticfinalStringTAG="TetrisView";//publicstaticfinalStringDATAFILE="save.dt";//文件名intmGamestate=STATE_PLAY;//设置当前的游戏状态为开始状态intmScore=0;//初始化得分为0intmSpeed=1;//初始化速度等级为1intmDeLine=0;//初始化被消去的行数为0booleanmIsCombo=false;//初始化:是否连击:否booleanmIsPaused=false;//初始化:是否暂停:否booleanmIsVoice=true;//初始化:是否打开声音:是longmMoveDelay=600;//移动延时为600mslongmLastMove=0;//最近移动时间privateContextmContext=null;//应用环境的全局信息初始化为nullprivatePaintmPaint=newPaint<>;//创建一个Paint的对象mPaint RefreshHandlermRefreshHandler=null;//刷新线程 TileViewmCurrentTile=null;//当前的方块,置空 TileViewmNextTile=null;//下一个方块,置空 CourtmCourt=null;//置游戏窗口为空 ResourceStoremResourceStore=null;//初始化资源 MusicPlayermMPlayer=null;//置响应声音为空publicTetrisView<Contextcontext>{super<context>; init<context>;//调用protectedvoidinit<Contextcontext }protectedvoidinit<Contextcontext>//初始化 {//相应的变量赋值mContext=context;mCurrentTile=newTileView<context>; Log.i<"tetris","mCurrentTilebuiled">;//记录日志文件mNextTile=newTileView<context>;mCourt=newCourt<context>;mRefreshHandler=newRefreshHandler<this>; mResourceStore=newResourceStore<context>;mMPlayer=newMusicPlayer<context>; setLevel<1>;//设置当前的等级为1mPaint.setAntiAlias<true>;//设置画笔的锯齿效果mPaint.setColor<Color.RED>;//设置画笔的颜色 setFocusable<true>;//可获取焦点newThread<this>.start<>;//执行当前线程 }publicvoidlogic<> {switch<mGamestate> {caseSTATE_MENU://当游戏的当前状态为STATE_MENU//mGamestate=STATE_PLAY;//将游戏的当前状态转为STATE_PLAYbreak;caseSTATE_PLAY://当游戏的当前状态为STATE_PLAY//startGame<>; playGame<>;//调用开始游戏函数break;caseSTATE_PAUSE://当游戏的当前状态为STATE_PAUSE,不改变游戏状态break;caseSTATE_OVER://当游戏的当前状态为STATE_OVER,不改变游戏状态break;default:; } }publicvoidstartGame<>//开始游戏 {mGamestate=STATE_PLAY;//将当前的游戏状态改为STATE_PLAY状态mCourt.clearCourt<>;//清空游戏窗口mCurrentTile=newTileView<mContext>;//将当前的方块信息保存在mCurrentTile变量中mNextTile=newTileView<mContext>;//将下一块方块信息保存在mNextTile变量中//初始化相关信息 setLevel<1>;mScore=0;mDeLine=0;mIsPaused=false;mIsCombo=false; playGame<>; }publicvoidplayGame<>//进入玩游戏 {longnow=System.currentTimeMillis<>;//以毫秒保存当前的系统时间if<now-mLastMove>mMoveDelay>//当前时间与最近移动时间间隔大于mMoveDelay时,移动方块的位置 {if<mIsPaused>//若当前游戏状态为暂停,直接返回 {return; }if<mIsCombo>//方块到达最低点 {mCourt.placeTile<mCurrentTile>;//在游戏窗体中显示当前的方块mMPlayer.playMoveVoice<>;//播放方块移动的声音if<mCourt.isGameOver<>>//若游戏结束 {mGamestate=STATE_OVER;return; }intline=mCourt.removeLines<>;//将一次消去的行数保存在line变量中if<line>0>//若有消去,播放响应声音 {mMPlayer.playBombVoice<>; }mDeLine+=line;//更改总的消去的行数 countScore<line>;//积分mCurrentTile=mNextTile;//将下一个方块设置为当前的方块mNextTile=newTileView<mContext>;//获取下一个方块mIsCombo=false;//置方块到达最低点为false } moveDown<>;//方块向下运行mLastMove=now;//更新最近移动时间 } }privatevoidcountScore<intline>//积分 {switch<line> {//根据一次消去的行数累加相应的分数case1:mScore+=100;break;case2:mScore+=300;break;case3:mScore+=600;break;case4:mScore+=1000;break;default:; }//根据当前的得分情况,相应的更改游戏等级if<mScore>=2000&&mScore<4000> { setLevel<2>; }elseif<mScore>=4000&&mScore<6000> { setLevel<3>; }elseif<mScore>=6000&&mScore<8000> { setLevel<4>; }elseif<mScore>=8000&&mScore<10000> { setLevel<5>; }elseif<mScore>=10000> { setLevel<6>; } }protectedvoidonDraw<Canvascanvas>//根据游戏不同的状态绘制出游戏界面 {switch<mGamestate> {caseSTATE_MENU: paintMenu<canvas>;//绘制出菜单页break;caseSTATE_PLAY: paintGame<canvas>;//绘制出游戏游戏开始的界面break;caseSTATE_PAUSE: paintPause<canvas>;//绘制出暂停游戏页break;caseSTATE_OVER: paintOver<canvas>;//绘制出游戏结束的界面break;default:; } }publicbooleanisGameOver<>//判断游戏是否结束 {returnmCourt.isGameOver<>; }publicbooleanonKeyDown<intkeyCode,KeyEventevent>//对用户按键作出反应 {switch<keyCode> {caseKeyEvent.KEYCODE_DPAD_UP://当按下"↑"if<mGamestate==STATE_PLAY> {//若当前状态为STATE_PLAY,且方块没有到达最低时,翻转方块if<!mIsPaused> { rotate<>;mMPlayer.playMoveVoice<>;//播放方块移动的响应声音 } }//如果当前的游戏状态为STATE_PAUSE或STATE_MENU,不做出反应elseif<mGamestate==STATE_PAUSE> { }elseif<mGamestate==STATE_MENU> { }break;caseKeyEvent.KEYCODE_DPAD_DOWN://当按下"↓"if<mGamestate==STATE_PLAY> {//若当前状态为STATE_PLAY,且方块没有到达最低时if<!mIsPaused> { moveDown<>;//向下移动mMPlayer.playMoveVoice<>;//播放方块移动的响应声音 } }//如果当前的游戏状态为STATE_PAUSE或STATE_MENU,不做出反应elseif<mGamestate==STATE_PAUSE> { }elseif<mGamestate==STATE_MENU> { }break;caseKeyEvent.KEYCODE_DPAD_LEFT://当按下"←"if<mGamestate==STATE_PLAY> {//若当前状态为STATE_PLAY,且方块没有到达最低时if<!mIsPaused> { moveLeft<>;//向左移动mMPlayer.playMoveVoice<>;//播放方块移动的响应声音 } }//如果当前的游戏状态为STATE_PAUSE或STATE_MENU,不做出反应elseif<mGamestate==STATE_PAUSE> { }elseif<mGamestate==STATE_MENU> { }break;caseKeyEvent.KEYCODE_DPAD_RIGHT://当按下"→"if<mGamestate==STATE_PLAY> {//若当前状态为STATE_PLAY,且方块没有到达最低时if<!mIsPaused> { moveRight<>;//向右移动mMPlayer.playMoveVoice<>;//播放方块移动的响应声音 } }//如果当前的游戏状态为STATE_PAUSE或STATE_MENU,不做出反应elseif<mGamestate==STATE_PAUSE> { }elseif<mGamestate==STATE_MENU> { }break;caseKeyEvent.KEYCODE_ENTER:;//按下回车键,不做出反应caseKeyEvent.KEYCODE_DPAD_CENTER://按下中间确定键if<mGamestate==STATE_PLAY> {//若当前状态为STATE_PLAY,且方块没有到达最低时if<!mIsPaused> { fastDrop<>;//快速向下移动mMPlayer.playMoveVoice<>;//播放方块移动的响应声音 } }//如果当前的游戏状态为STATE_PAUSE或STATE_MENU,不做出反应elseif<mGamestate==STATE_PAUSE> { }elseif<mGamestate==STATE_MENU> { }break;//caseKeyEvent.KEYCODE_S://若按下S键if<mGamestate==STATE_PLAY> {//若当前的游戏状态为STATE_PLAY,置暂停状态为truemIsPaused=true; }elseif<mGamestate==STATE_PAUSE> {//若当前的游戏状态已经为暂停,置暂停状态为falsemIsPaused=false; }elseif<mGamestate==STATE_MENU> {//若当前的游戏状态为STATE_MENU,不做出反应 }break;caseKeyEvent.KEYCODE_SPACE://若按下空格键mIsPaused=!mIsPaused;//更改暂停状态标志if<mIsPaused> {//若为暂停mRefreshHandler.pause<>;//中断线程 }else {mRefreshHandler.resume<>;//否则继续执行线程 }break;default:; }returnsuper.onKeyDown<keyCode,event>;////继续执行父类的其他点击事件 }privatevoidrotate<>//翻转方块 {if<!mIsCombo>//若没有到达最低点mCurrentTile.rotateOnCourt<mCourt>;//调用TileView的相应方法 }privatevoidmoveDown<>//方块向下运动 {if<!mIsCombo>//若没有到达最低点 {if<!mCurrentTile.moveDownOnCourt<mCourt>>//调用TileView的相应方法mIsCombo=true;//到达最低点,则mIsCombo置为true } }privatevoidmoveLeft<>//方块向左运动 {if<!mIsCombo>//若没有到达最低点 {mCurrentTile.moveLeftOnCourt<mCourt>;//调用TileView的相应方法 } }privatevoidmoveRight<>//方块向右运动 {if<!mIsCombo>//若没有到达最低点 {mCurrentTile.moveRightOnCourt<mCourt>;//调用TileView的相应方法 } }privatevoidfastDrop<>//方块快速向下运动 {if<!mIsCombo>//若
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《信息光学》课程教学大纲
- 《行政管理专业导论》课程教学大纲
- 2024年低价小型租房合同范本大全
- 2024年出售二级钢坯合同范本
- 园林绿化员工安全培训
- 2型糖尿病的查房
- 一例剖宫产个案护理
- 2024政府设备采购合同
- 2024卷闸门安装合同
- 中国爱情服务行业独立市场研究报告
- 中国农业文化遗产与生态智慧智慧树知到期末考试答案章节答案2024年浙江农林大学
- HSE2015153附件一燃气常规工程监理记录表单旁站记录
- 最新版个人征信报告模板-2020年-word版-可编辑-带水印
- 齿轮参数计算(内啮合)-内齿圈-行星轮
- 案例思念休闲吧
- 《外国航空运输企业航线经营许可规定》(CCAR-287)
- (完整版)《运输管理》课程教学大纲
- 小学五年级(上册)数学期末试卷附命题意图说明
- 金属学与热处理课后习题答案(机械工业出版社)第二版
- 普通发票销售清单
- 测量复核记录
评论
0/150
提交评论