华容道游戏开发--android小组
這個是我們小組的同學做的一個游戲,游戲界面做的比較簡單一點,但是還是麻雀雖小五臟俱全滴。。。
1,游戲背景
華容道是古老的中國游戲,以其變化多端、百玩不厭的特點與七巧板、九連環合稱“中國的難題”。
華容道游戲取自著名的三國故事,曹操在赤壁大戰中被劉備和孫權的“苦肉計”、“火燒連營”打敗,被迫退逃到華容道,又遇上諸葛亮的伏兵,關羽為了報答曹操對他的恩情,明逼實讓,終于幫助曹操逃出了華容道。
游戲就是依照“曹瞞兵敗走華容,正與關公狹路逢。只為當初恩義重,放開金鎖走蛟龍”這一故事情節進行設計的。
2,功能簡介
游戲的操作非常簡單,其具體方法如下:
(1)運行游戲,首先進入的是主菜單界面,如圖1所示。
(2)在菜單界面,可以通過“打開聲音”/“關閉聲音”來控制游戲聲音的開關,單擊幫助菜單可進入幫助界面,如圖2所示。
(3)在菜單界面單擊“開始游戲”可進入游戲的主界面,如圖3所示
(4)在游戲界面,玩家可以通過單擊人物圖片,對人物進行移動;可以單擊聲音按鈕控制游戲聲音;單擊“上一關”或“下一關”按鈕選擇關卡;單擊“重玩”可以從頭開始玩本關。如圖4所示。
(5)當“曹操”被移動到棋盤最下方的綠線處時,游戲勝利。游戲會記錄當前已走的步數,以及每一關的歷史最好成績。
(6)在游戲過程中,玩家可以單擊X處,結束游戲,回到主菜單。圖2 游戲簡介
1,游戲背景
華容道是古老的中國游戲,以其變化多端、百玩不厭的特點與七巧板、九連環合稱“中國的難題”。
華容道游戲取自著名的三國故事,曹操在赤壁大戰中被劉備和孫權的“苦肉計”、“火燒連營”打敗,被迫退逃到華容道,又遇上諸葛亮的伏兵,關羽為了報答曹操對他的恩情,明逼實讓,終于幫助曹操逃出了華容道。
游戲就是依照“曹瞞兵敗走華容,正與關公狹路逢。只為當初恩義重,放開金鎖走蛟龍”這一故事情節進行設計的。
2,功能簡介
游戲的操作非常簡單,其具體方法如下:
(1)運行游戲,首先進入的是主菜單界面,如圖1所示。
(2)在菜單界面,可以通過“打開聲音”/“關閉聲音”來控制游戲聲音的開關,單擊幫助菜單可進入幫助界面,如圖2所示。
(3)在菜單界面單擊“開始游戲”可進入游戲的主界面,如圖3所示
(4)在游戲界面,玩家可以通過單擊人物圖片,對人物進行移動;可以單擊聲音按鈕控制游戲聲音;單擊“上一關”或“下一關”按鈕選擇關卡;單擊“重玩”可以從頭開始玩本關。如圖4所示。
(5)當“曹操”被移動到棋盤最下方的綠線處時,游戲勝利。游戲會記錄當前已走的步數,以及每一關的歷史最好成績。
(6)在游戲過程中,玩家可以單擊X處,結束游戲,回到主菜單。
??
?
???????????????????圖1 游戲主菜單?
???????????????????
?圖2 游戲簡介
????????????????? 圖3 游戲主界面
??
3,游戲的策劃及準備工作
l? 游戲類型
該游戲屬于中國傳統益智游戲,其操作方式類似拼圖,游戲變化多端,百玩不厭。
l? 運行平臺
目標平臺為Android2.2,但開發過程中采用的技術都是Android的基礎技術,所以在低版本的Android平臺上也可以正常運行。
l? 操作方式
本游戲采用屏幕事件進行操作,玩家可使用觸控筆單擊屏幕來完成對游戲的控制。
l? 音效設計
考慮到玩家的體驗,并結合游戲的背景,我們選擇了“三國殺”的音樂作為背景音樂,游戲過程中,移動曹操時,還會有特別的音效。
l? 游戲開發的準備工作
游戲開發前的準備工作是必不可少的,主要是要搜集需要用到的圖片、聲音等資源。本游戲的開發過程中用到的資源主要有以下幾大類:
圖片資源:
(1)人物頭像(2)菜單及按鈕(3)關卡名稱(4)游戲背景界面
圖4 頭像圖片
圖5 按鈕
圖6 關卡名稱
聲音資源:
背景音樂:gamesound.wav
移動曹操時的音樂:caocaosound.wav
游戲勝利有的音樂:caocao_succed.wav
4,游戲的架構
我們將游戲中的類分成3部分,下面分別對其進行介紹
4.1,共有類
Activity的實現類Huarongdao.java。該類是通過擴展基類Activity得到的,是整個游戲的控制器,也是整個程序的入口。
Huarongdao類實現代碼如下:
public class Huarongdao extends Activity {
??? boolean isSound = true;//是否播放聲音
??? MediaPlayer gamesound;//游戲聲音
??? MediaPlayer caocaoSound;
??? MediaPlayer caocaoSucceed;
??? static int CURRENT_LEVEL=0;
??? static int[] bestSteps=new int[Maps.LEVEL_NUM];
??? String[] level=new String[]{"level0","level1","level2","level3","level4","level5","level6","level7","level8","level9"};
??? Handler myHandler = new Handler(){//用來更新UI線程中的控件
??????? public void handleMessage(Message msg) {
??????? if(msg.what == 1){//MenuView傳來的消息,切換到GameView
??????? ???? initGameView();//初始化并切換到游戲界面
??????? }
??????? else if(msg.what ==2){//MenuView傳來的消息,切換到HelpView
??????? ???? initHelpView();//初始化并切換到幫助界面
??????? }
??????? else if(msg.what==3){
??????? ???? initMenuView();//切換到menuview
??????? }
??????? }
??? };
??? /** Called when the activity is first created. */
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? //全屏
??????? requestWindowFeature(Window.FEATURE_NO_TITLE);
??????? getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,?
??? ????????????? WindowManager.LayoutParams.FLAG_FULLSCREEN);
??????? gamesound? = MediaPlayer.create(this, R.raw.gamesound);//游戲過程的背景聲音
??????? caocaoSound=MediaPlayer.create(this, R.raw.caocaosound);//游戲過程中曹操移動時的聲音
??????? caocaoSucceed=MediaPlayer.create(this, R.raw.caocao_succeed);//游戲過程的背景聲音
?????? gamesound.setLooping(true);//設置游戲聲音循環播放
?????? caocaoSound.setLooping(false);
?????? caocaoSucceed.setLooping(false);
?????? //從preferences中讀取出每一關的最好成績
?????? SharedPreferences beststeps=getPreferences(Activity.MODE_PRIVATE);
?????? for(int i=0;i<Maps.LEVEL_NUM;i++)
?????? bestSteps[i]=beststeps.getInt(level[i], 0);?????
??????? this.initMenuView();//初始化菜單界面
???????
??? }
??? private void initMenuView() {
?????? // TODO Auto-generated method stub
?????? if(this.isSound){//是否播放聲音
??? ??? gamesound.start();//播放聲音
??? }
?????? this.setContentView(new MenuView(this,this));
??????
??? }
??? protected void initHelpView() {
?????? // TODO Auto-generated method stub
?????? this.setContentView(new HelpView(this,this));
??????
??? }
??? protected void initGameView() {
?????? // TODO Auto-generated method stub
?????? this.setContentView(new GameView(this,this));
??????
??? }
??? public void updateBestSteps() {
?????? // TODO Auto-generated method stub
?????? SharedPreferences newsteps=getPreferences(0);
?????? SharedPreferences.Editor editor=newsteps.edit();
?????? editor.putInt(level[CURRENT_LEVEL], bestSteps[CURRENT_LEVEL]);
?????? editor.commit();
??????
??? }
4.2,輔助界面相關類
有3個:菜單界面類MenuView,為菜單界面的實現類,負責繪制菜單界面以及對菜單界面的屏幕進行監聽。
MenuView類的實現如下:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MenuView extends SurfaceView implements SurfaceHolder.Callback{
?Huarongdao activity;
?Bitmap startGame;
?Bitmap openSound;
?Bitmap closeSound;
?Bitmap help;
?Bitmap exit;
?private TutorialThread thread;//刷幀的線程
?
?
?public MenuView(Context context,Huarongdao huarongdao) {
??super(context);
??// TODO Auto-generated constructor stub
??this.activity=huarongdao;//得到huarongdao引用
??getHolder().addCallback(this);
??????? this.thread = new TutorialThread(getHolder(), this);//啟動刷幀線程
??initBitmap();
?}
?private void initBitmap() {
??// TODO Auto-generated method stub
??startGame = BitmapFactory.decodeResource(getResources(), R.drawable.startgame);//開始游戲按鈕
??openSound = BitmapFactory.decodeResource(getResources(), R.drawable.opensound);//開始聲音按鈕
??closeSound = BitmapFactory.decodeResource(getResources(), R.drawable.closesound);//關閉聲音按鈕
??help = BitmapFactory.decodeResource(getResources(), R.drawable.help);//幫助按鈕
??exit = BitmapFactory.decodeResource(getResources(), R.drawable.exit);//退出按鈕??
?}
?
?public void onDraw(Canvas canvas){
??canvas.drawColor(Color.BLACK);//清屏
??canvas.drawBitmap(startGame, 50, 50, null);//繪制圖片
??if(activity.isSound){//放聲音時,繪制關閉聲音圖片
???canvas.drawBitmap(closeSound, 50, 150, null);//繪制關閉聲音
??}else{//沒有放聲音時繪制打開聲音圖片
???canvas.drawBitmap(openSound, 50, 150, null);//繪制開始聲音
??}
??canvas.drawBitmap(help, 50, 250, null);//繪制幫助按鈕
??canvas.drawBitmap(exit, 50, 350, null);//繪制退出按鈕
??
?}
?public boolean onTouchEvent(MotionEvent event) {//屏幕監聽
??if(event.getAction() == MotionEvent.ACTION_DOWN){
???if(event.getX()>105 && event.getX()<220
?????&&event.getY()>60 && event.getY()<95){//點擊的是開始游戲
????activity.myHandler.sendEmptyMessage(1);
???}
???
???else if(event.getX()>105 && event.getX()<220
?????&&event.getY()>160 && event.getY()<195){//點擊的是聲音按鈕
????activity.isSound = !activity.isSound;//將聲音開關取反
????if(!activity.isSound){//當沒有放聲音時
?????if(activity.gamesound != null){//檢查當前是否已經有聲音正在播放
??????if(activity.gamesound.isPlaying()){//當游戲聲音正在播放時,
???????activity.gamesound.pause();//停止聲音的播放
??????}?
?????}
????}else{//當需要播放聲音時
?????if(activity.gamesound != null){//當gamesound不為空時
??????if(!activity.gamesound.isPlaying()){//且當前聲音沒有在播放
???????activity.gamesound.start();//則播放聲音
??????}?
?????}
????}
???}
???
???else if(event.getX()>105 && event.getX()<220
?????&&event.getY()>260 && event.getY()<295){//點擊的是幫助按鈕
????activity.myHandler.sendEmptyMessage(2);//向activity發送Hander消息通知切換View
???}else if(event.getX()>105 && event.getX()<220
?????&&event.getY()>360 && event.getY()<395){//點擊的是退出游戲
????
????
????System.exit(0);//直接退出游戲
???}
??}
??return super.onTouchEvent(event);
?}
?
?class TutorialThread extends Thread{//刷幀線程
??private int span = 500;//睡眠的毫秒數
??private SurfaceHolder surfaceHolder;//SurfaceHolder的引用
??private MenuView menuView;//MenuView的引用
??private boolean flag = false;//循環標記位
??????? public TutorialThread(SurfaceHolder surfaceHolder, MenuView menuView) {//構造器
??????????? this.surfaceHolder = surfaceHolder;//得到surfaceHolder引用
??????????? this.menuView = menuView;//得到menuView引用
??????? }
??????? public void setFlag(boolean flag) {//設置循環標記位
??????? ?this.flag = flag;
??????? }
??public void run() {//重寫的run方法
???Canvas c;//畫布
??????????? while (this.flag) {//循環
??????????????? c = null;
??????????????? try {
??????????????? ?// 鎖定整個畫布,在內存要求比較高的情況下,建議參數不要為null
??????????????????? c = this.surfaceHolder.lockCanvas(null);
??????????????????? synchronized (this.surfaceHolder) {//同步鎖
??????????????????? ?menuView.onDraw(c);//調用繪制方法
??????????????????? }
??????????????? } finally {//使用finally保證下面代碼一定被執行
??????????????????? if (c != null) {
??????????????????? ?//更新屏幕顯示內容
??????????????????????? this.surfaceHolder.unlockCanvasAndPost(c);
??????????????????? }
??????????????? }
??????????????? try{
??????????????? ?Thread.sleep(span);//睡眠指定毫秒數
??????????????? }catch(Exception e){//捕獲異常
??????????????? ?e.printStackTrace();//有異常時打印異常堆棧信息
??????????????? }
??????????? }
??}
?}
?@Override
?public void surfaceChanged(SurfaceHolder holder, int format, int width,
???int height) {
??// TODO Auto-generated method stub
??
?}
?@Override
?public void surfaceCreated(SurfaceHolder holder) {
??// TODO Auto-generated method stub
??this.thread.setFlag(true);//設置循環標志位
??????? this.thread.start();//啟動線程
??
?}
?@Override
?public void surfaceDestroyed(SurfaceHolder holder) {
??// TODO Auto-generated method stub
??boolean retry = true;//循環標志位
??????? thread.setFlag(false);//設置循環標志位
??????? while (retry) {//循環
??????????? try {
??????????????? thread.join();//等待線程結束
??????????????? retry = false;//停止循環
??????????? }catch (InterruptedException e){}//不斷地循環,直到刷幀線程結束
??????? }
??
?}
}
HelpView,實現幫助界面。Maps用于存放關卡布局信息,如果要新增關卡,只需修改這個類即可。
HelpView實現如下:
public class HelpView extends SurfaceView implements SurfaceHolder.Callback{
??? Bitmap bg;
??? Bitmap introduction;
??? Bitmap exit2;
??? Huarongdao activity;
??? int intro_y=480;//文字的y坐標
??? private TutorialThread thread;//刷幀的線程
???
???
??? public HelpView(Context context,Huarongdao huarongdao) {
?????? super(context);
?????? // TODO Auto-generated constructor stub
?????? this.activity=huarongdao;//得到huarongdao引用
?????? getHolder().addCallback(this);
??????? this.thread = new TutorialThread(getHolder(), this);//啟動刷幀線程
?????? initBitmap();
??? }
???
??? public void onDraw(Canvas canvas){
?????? canvas.drawColor(Color.BLACK);//清屏
?????? canvas.drawBitmap(bg, 0, 0, null);//繪制背景圖片
??????
?????? canvas.drawBitmap(introduction, 0, intro_y, null);//繪制文字介紹
?????? if(intro_y==0)
?????? canvas.drawBitmap(exit2, 240, 440, null);// 繪制退出按鈕
??????
??? }
???
??? public boolean onTouchEvent(MotionEvent event) {
?????? if (event.getAction() == MotionEvent.ACTION_DOWN) {// 只取鼠標按下的事件
?????????? if (event.getX() > 240 && event.getX() < 280
????????????????? && event.getY() > 440
????????????????? && event.getY() < 480) {// 按下了退出按鈕
????????????? activity.myHandler.sendEmptyMessage(3);// 發送消息,切換到MenuView
?????????? }?????
?????? }
?????? return super.onTouchEvent(event);
??? }
?
?
??? private void initBitmap() {
?????? // TODO Auto-generated method stub
?????? bg=BitmapFactory.decodeResource(getResources(), R.drawable.bg);
?????? introduction=BitmapFactory.decodeResource(getResources(), R.drawable.introduction);
?????? exit2=BitmapFactory.decodeResource(getResources(), R.drawable.exit2);
??????
??? }
?
?
??? @Override
??? public void surfaceChanged(SurfaceHolder holder, int format, int width,
?????????? int height) {
?????? // TODO Auto-generated method stub
??????
??? }
?
?
??? @Override
??? public void surfaceCreated(SurfaceHolder holder) {
?????? // TODO Auto-generated method stub
?????? this.thread.setFlag(true);//設置循環標志位
??????? this.thread.start();//啟動線程
??? }
?
??? @Override
??? public void surfaceDestroyed(SurfaceHolder holder) {
?????? // TODO Auto-generated method stub
?????? boolean retry = true;//循環標志位
??????? thread.setFlag(false);//設置循環標志位
??????? while (retry) {//循環
??????????? try {
??????????????? thread.join();//等待線程結束
??????????????? retry = false;//停止循環
??????????? }catch (InterruptedException e){}//不斷地循環,直到刷幀線程結束
??????? }
??????
??? }
???
??? class TutorialThread extends Thread{//刷幀線程
?????? private int span = 100;//睡眠的毫秒數
?????? private SurfaceHolder surfaceHolder;//SurfaceHolder的引用
?????? private HelpView helpView;
?????? private boolean flag = false;//循環標記位
??????? public TutorialThread(SurfaceHolder surfaceHolder, HelpView helpView) {//構造器
??????????? this.surfaceHolder = surfaceHolder;//得到surfaceHolder引用
??????????? this.helpView = helpView;
??????? }
??????? public void setFlag(boolean flag) {//設置循環標記位
??????? this.flag = flag;
??????? }
?????? public void run() {//重寫的run方法
?????????? Canvas c;//畫布
??????????? while (this.flag) {//循環
??????????????? c = null;
??????????????? try {
??????????????? ? // 鎖定整個畫布,在內存要求比較高的情況下,建議參數不要為null
??????????????????? c = this.surfaceHolder.lockCanvas(null);
??????????????????? synchronized (this.surfaceHolder) {//同步鎖
??????????????????? ?? helpView.onDraw(c);//調用繪制方法
??????????????????? }
??????????????? } finally {//使用finally保證下面代碼一定被執行
??????????????????? if (c != null) {
??????????????????? ?? //更新屏幕顯示內容
??????????????????????? this.surfaceHolder.unlockCanvasAndPost(c);
??????????????????? }
??????????????? }
??????????????? try{
??????????????? ? Thread.sleep(span);//睡眠指定毫秒數
??????????????? ? if(intro_y>0)
??????????????? ? intro_y-=3;
??????????????? }catch(Exception e){//捕獲異常
??????????????? ? e.printStackTrace();//有異常時打印異常堆棧信息
??????????????? }
??????????? }
?????? }
??? }
?}
?
4.3,游戲界面相關類
GameView.java是本游戲中最主要的類,負責繪制游戲過程中所有的信息,如布局、最好成績、關卡名、各個按鈕等。該類中還包含了一個非常重要的線程TutorialThread,它負責游戲界面的定時刷新。
GameView是本游戲中最重要的類,它繼承了SurfaceView,同時實現了SurfaceHolder.Callback,重寫了屏幕監聽方法onTouchEvent(MotionEvent event),該類中還包含了一個刷幀的線程TutorialThread,每隔一段時間調用一次GameView的onDraw方法進行屏幕的重繪。
??? 在數據存儲方面,考慮到本游戲需要存儲的數據只有“最好成績”這一項,所以我們沒有采用數據庫,而是使用了輕量級的Preference存儲方案。Preference主要用于存儲和查詢簡單數據類型的數據,這些簡單數據類型包括boolean,int,float,long以及string等,存儲方式以鍵值對的形式存放在應用程序的私有文件夾下。
5,游戲的優化與改進
經過我們的努力,游戲的基本功能已經完成,但是有很多地方可以提升。例如,現在的版本中,我們需要先選中人物,再點擊空格位置,才能移動人物。更好的方法是,點擊人物后,就自動移動到空位置。此外,游戲的界面還可以做的更漂亮一些。
通過這個小游戲的開發,我們加深了對Android操作系統的認識,對Android的基礎知識有了更深入的了解,也為以后大型游戲和應用的開發打好了基礎。
轉載于:https://www.cnblogs.com/SCUTMSTechClub/archive/2011/03/19/1988623.html
總結
以上是生活随笔為你收集整理的华容道游戏开发--android小组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java开发:笔记
- 下一篇: 如何将一个数据库中的一个表复制到另一个数