Android群英傳-拼圖遊戲puzzle-代碼設計和實現

來源:互聯網
上載者:User

Android群英傳-拼圖遊戲puzzle-代碼設計和實現
上個周末,3個小時總體上讀完了《Android群英傳》,本周主要在研究代碼層次的設計和實現。
編譯安裝在手機上,玩了幾把,結合代碼,一周時間才掌握了整體的思路。
大部分時間,其實花在了“重構”上。
重構的過程,就是學習和思考的過程。

本文,算是一篇學習總結,總體介紹下這款小遊戲的實現思路。
後面抽空,再改造下這個遊戲不合理的設計方式,即格子是N*N+1,而不是N*N個。

寫到快吐了:在寫過的幾百篇文章裡,其中有很多案例了,寫得次數越多,越發現很多流程和思路是一致的。
因此,很有必要把一些通用的知識總結下。寫清楚了,再介紹就清楚多了。
文章的名字初步定為“可視化介面GUI應用開發總結:Android、iOS、Web、Swing、Windows開發等”,預計2015年12月7日之前發表。

代碼講解

1.包結構

cn.fansunion.puzzle
--activity
GlobalConst.java 幾個全域常量
MainActivity.java 遊戲的入口Activity
PuzzleActivity.java 拼圖遊戲過程的Activity
--adapter
MainGridViewAdapter.java 遊戲入口介面的Gridview的適配器,可以理解成GridView的資料提供者
PuzzleGridViewAdapter.java拼圖介面的GridView的適配器
--bean
GridItem.java 表格中的1個元素
--util
GameUtil.java 封裝了遊戲規則
ImageUtil.java 圖片處理工具
ScreenUtil.java 螢幕工具

2.基礎類講解
GameUtil.java

isMoveable:判斷圖片是否可以移動,或者稱為“能否和空格進行交換”,根據GridView中的position,判斷是否和空格是“相鄰”的就可以了。
swapItems:交換2個GridItem的位置,在判斷可以移動之後
isSuccess:判斷當前拼圖是否完成
getPuzzleGenerator:產生隨機的Item,就是把N*N個數位位置,打亂
canSolve:判斷隨機產生的Item是否有解,即能否通過移動交換圖片,還原“原圖”。
(這個地方的設計,也比較坑。我目前認為,可以換種方式產生初始拼圖,即隨機交換空格和周邊的圖片N次。因為“交換是可逆的”,所以總是有解)

ImageUtil.java:把1個圖片,切成N*N個;放大圖片。
ScreenUtil.java:獲得螢幕的大小、密度。

GridItem.java:遊戲拼圖的核心Model,表格中的1項,id、圖片資源id、圖片資源,方便繪圖和遊戲規則實現。
MainGridViewAdapter.java和PuzzleGridViewAdapter.java:繼承android.widget.BaseAdapter,重載若干方法。

GlobalConst.java:一些常量,太簡單了吧。

3.遊戲的流程
遊戲入口MainActivity.java

核心流程:
a.設定主體介面
setContentView(R.layout.xpuzzle_main);
b.初始化其它介面,按鈕等
initViews();
c.資料配接器
gridView.setAdapter(new MainGridViewAdapter(
MainActivity.this, bitmapList));
d.按鈕、介面等綁定事件
gridView.setOnItemClickListener
e.事件響應

重要事件
a.選擇遊戲難度,儲存到Type欄位中。給使用者一個“彈出對話方塊”選擇。

 selectedTypeTextView.setOnClickListener(                new OnClickListener() {                    @Override                    public void onClick(View v) {                        // 彈出popup window                        popupShow(v);                    }                });    }


b.遊戲內建若干圖片和使用系統圖片。
用表格展示的,Item點擊監聽,最後1個圖片,表示選擇“本地圖庫或者相機拍攝”,其它圖片就直接選擇了。
 gridView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView arg0, View view,                                    int position, long arg3) {                if (position == photoResourceIdArray.length - 1) {                    // 選擇本地圖庫 相機                    showDialogCustom();                } else {                    // 選擇預設圖片                    Intent intent = new Intent(                            MainActivity.this,                            PuzzleMain.class);                    intent.putExtra(GlobalConst.SELECT_PHOTO_ID, photoResourceIdArray[position]);                    intent.putExtra(GlobalConst.TYPE, type);                    startActivity(intent);                }            }        });


本地圖庫和相機拍照,是2套類似的邏輯。使用者選擇之後,調用圖庫相機回調方法,儲存使用者選擇的圖片。
然後就進入到“拼圖遊戲主介面”了。

拼圖遊戲主介面PuzzleActivity.java
核心流程:
a.設定主體布局
setContentView(R.layout.xpuzzle_puzzle_detail_main);
b.獲得使用者選擇的圖片,並切圖
getIntent().getExtras().getInt(GlobalConst.SELECT_PHOTO_ID);
c. 初始化其它Views
initViews();
d. 調用GameUtil產生遊戲初始資料,並啟動定時器。(寫到這裡突然發現,又不合理了,定時器,應該在程式全部初始化完成之後,再開啟。)
generateGame();
e.事件綁定。
// 返回按鈕點擊事件
backButton.setOnClickListener(this);
// 顯示原圖按鈕點擊事件
imageButton.setOnClickListener(this);
// 重設按鈕點擊事件
restartButton.setOnClickListener(this);

// GridView點擊事件(最重要的其實是這個),圖片可否移動,在能夠移動的情況下,需要“交換圖片、”“更新繪圖”、“更新步數”。
//在成功的情況下,後續處理(停止計時等)
  gridView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView arg0, View view,                                    int position, long arg3) {                // 判斷是否可移動                if (GameUtil.isMoveable(position)) {                    // 交換點擊Item與空格的位置                    GameUtil.swapItems(                            GameUtil.gridItemList.get(position),                            GameUtil.blankGridItem);                    // 重新擷取圖片                    recreateData();                    // 通知GridView更改UI                    puzzleGridViewAdapter.notifyDataSetChanged();                    // 更新步數                    stepCount++;                    stepCountTextView.setText( + stepCount);                    // 判斷是否成功                    if (GameUtil.isSuccess()) {                        // 將最後一張圖顯示完整                        recreateData();                        bitmapItemList.remove(TYPE * TYPE - 1);                        bitmapItemList.add(lastBitmap);                        // 通知GridView更改UI                        puzzleGridViewAdapter.notifyDataSetChanged();                        Toast.makeText(PuzzleMain.this, 拼圖成功!,                                Toast.LENGTH_LONG).show();                        gridView.setEnabled(false);                        timer.cancel();                        timerTask.cancel();                    }                }            }        });


4.資源
布局、菜單、字串,結合Java代碼,很容易讀懂。
 

個人看法
目前的技術,入門,達到中級水平,能夠幹活和賺錢,還是比較容易的。
達到一定水平之後,想要繼續高深,就要看個人對技術的理解了。
至於重構、代碼規範、遊戲設計,每個人都有自己的理解。
結合實際情況,再做具體考量。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.