項目開設計(俄羅斯方塊).doc
俄羅斯方塊游戲JAVA版
項目開發(fā)設計文檔
Ver 1.0
編制:駱華
審核:
2014年8月
1、 項目介紹
俄羅斯方塊是一款風靡全球的掌上游戲機和PC機游戲, 它造成的轟動與創(chuàng)造的經濟價值可以說是游戲史上的一件大事。它由俄羅斯人阿列克謝帕基特諾夫在1984年6月利用空閑時間所編寫的游戲程序,故得此名。俄羅斯方塊的基本規(guī)則是移動、旋轉和擺放游戲自動輸出的各種方塊,使之排列成完整的一行或多行并且消除得分。它看似簡單卻變化無窮,俄羅斯方塊上手極其簡單,但是要熟練地掌握其中的操作與擺放技巧,難度卻不低。作為家喻戶曉老少皆宜的大眾游戲,其普及程度可以說是史上任何一款游戲都無法相比的。相信大多數人都還記得為它癡迷得茶不思飯不想的那個俄羅斯方塊的時代。由于俄羅斯方塊具有的教學性、動態(tài)性與知名度,也經常拿來作為游戲程序設計的練習題材。
2、 項目需求
(一) 功能需求
運行游戲后,可選擇游戲難度,游戲開始后,由程序隨機產生所定義的圖形,右上角可看到下一個圖形,無操作時,方塊豎直緩慢下落,圖形在接觸障礙物之前,可以由鍵盤控制向左右下移動,可通過空格鍵進行翻轉,可以進行暫停、重新開始游戲,當某一行被下落的方塊填滿后消除并計分,難度越大方塊下落速度相對提高,另外可修改游戲窗體風格。
(二) 性能需求
1、游戲在不同分辨率下應能適應各種分辨率保證不變形。
2、保證游戲性能,在雙核512M內存下應能流暢運行。
3、 涉及主要知識點
(一)、開發(fā)環(huán)境搭建與配置
1、jdk安裝配置
2、eclipse安裝配置
(二)、界面布局
1、AWT、Swing
2、菜單使用
(三)、游戲方塊
整個游戲中總共7種方塊樣式,每個方塊有4種變形,通過線程控制由4 * 4 個方格構成的一個方塊的移動、下落以及變形。
(四)、游戲畫布
通過線程動態(tài)改變游戲畫布的方格顏色,畫布通過檢查方格顏色來體現方塊的移動
(五)、事件
鍵盤監(jiān)聽事件
(六)、線程
整個游戲由線程控制,一輪游戲過程,實現了Runnable接口,一輪游戲是一個大循環(huán),在這個循環(huán)中,每隔100毫秒;檢查游戲中的當前塊是否已經到底了,如果沒有,就繼續(xù)等待。如果到底了,就看有沒有全填滿的行,如果有就刪除它,并為游戲者加分,同時隨機產生一新的當前塊,讓它自動下落。當新產生一個塊時,先檢查畫布最頂上的一行是否已經
被占了,如果是,可以判斷Game Over了。
4、 概要設計
(采用開發(fā)模式、框架、模塊劃分、模塊之間通訊設計等,本項目無)
5、 數據庫設計
(概念數據模型、物理數據模型、表、字段、約束、存儲過程、函數、視圖等,本項目無)
6、 界面設計
本游戲只包含1個主界面
游戲菜單下包括開始新游戲、設置游戲方塊顏色、設置背景顏色、改變游戲難度等。
控制菜單下包括游戲的暫停、繼續(xù)、重新開始以及停止。
窗體風格菜單下用來設置游戲窗體風格。
關于菜單下包括幫助和游戲簡介
7、 類設計
本項目包含ErsBlock、ErsBlocksGame、ControlPanel、ErsBox 以及GameCanvas 5個類,具體設計如下:
(一)ErsBlock類
該類的主要功能為設計游戲方塊類,繼承自線程類(Thread),由 4 * 4 個方格(ErsBox)構成一個塊,控制塊的移動、下落、變形等。
(二)ErsBlocksGame類
該類的主要功能為游戲主類,繼承自JFrame類,負責游戲的全局控制。內含
1一個GameCanvas畫布類的實例引用,
2一個保存當前活動塊(ErsBlock)實例的引用,
3一個保存當前控制面板(ControlPanel)實例的引用;
利用線程實現了一輪游戲過程,一輪游戲是一個大循環(huán),在這個循環(huán)中,每隔100毫秒,檢查游戲中的當前塊是否已經到底了,如果沒有,就繼續(xù)等待。如果到底了,就看有沒有全填滿的行,如果有就刪除它,并為游戲者加分,同時隨機產生一個新的當前塊,讓它自動下落。
當新產生一個塊時,先檢查畫布最頂上的一行是否已經被占了,如果是,可以判斷Game Over了。
(三)ControlPanel類
該類的主要功能控制面板類,繼承自JPanel.上邊安放預顯窗口、等級、得分、控制按鈕,主
要用來控制游戲進程。
(四)ErsBox類
該類的主要功能是實現方格類,是組成塊的基本元素,用自己的顏色來表示塊的外觀
(五)GameCanvas類
該類的主要功能是實現畫布類,內有行數 * 列數個方格類實例。繼承自JPanel類。 ErsBlock線程類動態(tài)改變畫布類的方格顏色,畫布類通過檢查方格顏色來體現ErsBlock塊的移動情況。
8、 技術難點、解決方案和關鍵代碼
1、 游戲方塊的旋轉和移動
游戲中總共有7種方塊類型,每種方塊有4種翻轉,因此我們在程序中利用點陣圖,把4位16進制數按每位換算成一行4位2進制數的結果矩陣,理解為一個4*4的矩陣,比如說0x04e0轉換完后就是
0000
0100
1110
0000
其中將0看作空的,1看作方塊的塊,就可以看出正好是長條形在4*4空間中的橫豎切換
/**
* 方塊的樣式數目為7
*/
private final static int BLOCK_KIND_NUMBER = 7;
/**
* 每一個樣式的方塊的反轉狀態(tài)種類為4
*/
private final static int BLOCK_STATUS_NUMBER = 4;
/**
* 分別對應對7種模型的28種狀態(tài)
*/
public final static int[][] STYLES = {// 共28種狀態(tài)
{0x0f00, 0x4444, 0x0f00, 0x4444}, // 長條型的四種狀態(tài)
{0x04e0, 0x0464, 0x00e4, 0x04c4}, // T型的四種狀態(tài)
{0x4620, 0x6c00, 0x4620, 0x6c00}, // 反Z型的四種狀態(tài)
{0x2640, 0xc600, 0x2640, 0xc600}, // Z型的四種狀態(tài)
{0x6220, 0x1700, 0x2230, 0x0740}, // 7型的四種狀態(tài)
{0x6440, 0x0e20, 0x44c0, 0x8e00}, // 反7型的四種狀態(tài)
{0x0660, 0x0660, 0x0660, 0x0660}, // 方塊的四種狀態(tài)
};
方塊的移動分為向左、右和下3個方向,
/**
* 塊向左移動一格
*/
public void moveLeft() {
moveTo(y, x - 1);
}
/**
* 塊向右移動一格
*/
public void moveRight() {
moveTo(y, x + 1);
}
/**
* 塊向下落一格
*/
public void moveDown() {
moveTo(y + 1, x);
}
/**
* 將當前畫移動到newRow/newCol所指定的位置
* @param newRow int, 目的地所在行
* @param newCol int, 目的地所在列
* @return boolean, true-移動成功,false-移動失敗
*/
private synchronized boolean moveTo(int newRow, int newCol) {
if (!isMoveAble(newRow, newCol) || !moving) return false;
earse();
y = newRow;
x = newCol;
display();
canvas.repaint();
return true;
}
對于方塊的翻轉,
/**
* 塊變型
*/
public void turnNext() {
for (int i = 0; i < BLOCK_KIND_NUMBER; i++) {
for (int j = 0; j < BLOCK_STATUS_NUMBER; j++) {
if (STYLES[i][j] == style) {
int newStyle = STYLES[i][(j + 1) % BLOCK_STATUS_NUMBER];
turnTo(newStyle);
return;
}
}
}
}
/**
* 將當前塊變成newStyle所指定的塊樣式
* @param newStyle int,將要改變成的塊樣式,對應STYLES的28個值中的一個
* @return boolean,true-改變成功,false-改變失敗
*/
private boolean turnTo(int newStyle) {
if (!isTurnAble(newStyle) || !moving) return false;
earse();
int key = 0x8000;
for (int i = 0; i < boxes.length; i++) {
for (int j = 0; j < boxes[i].length; j++) {
boolean isColor = ((newStyle & key) != 0);
boxes[i][j].setColor(isColor);
key >>= 1;
}
}
style = newStyle;
display();
canvas.repaint();
return true;
}
2、 游戲中消行和結束
如果游戲畫布中有全填滿的行,我們就應該從畫布中刪除當行,根據最頂行是否被占來判斷游戲是否結束。
/**
* 檢查畫布中是否有全填滿的行,如果有就刪除之
*/
public void checkFullLine() {
for (int i = 0; i < canvas.getRows(); i++) {
int row = -1;
boolean fullLineColorBox = true;
for (int j = 0; j < canvas.getCols(); j++) {
if (!canvas.getBox(i, j).isColorBox()) {
fullLineColorBox = false;
break;
}
}
if (fullLineColorBox) {
row = i--;
canvas.removeLine(row);
}
}
}
/**
* 當一行被游戲者疊滿后,將此行清除,并為游戲者加分
* @param row int, 要清除的行,是由ErsBoxesGame類計算的
*/
public synchronized void removeLine(int row) {
for (int i = row; i > 0; i--) {
for (int j = 0; j < cols; j++)
boxes[i][j] = (ErsBox) boxes[i - 1][j].clone();
}
score += ErsBlocksGame.PER_LINE_SCORE;
scoreForLevelUpdate += ErsBlocksGame.PER_LINE_SCORE;
repaint();
}
/**
* 根據最頂行是否被占,判斷游戲是否已經結束了。
* @return boolean, true-游戲結束了,false-游戲未結束
*/
private boolean isGameOver() {
for (int i = 0; i < canvas.getCols(); i++) {
ErsBox box = canvas.getBox(0, i);
if (box.isColorBox()) return true;
}
return false;
}
9、 參考資料
1、 http://www.docin.com/p-304555640.html 俄羅斯方塊需求分析
2、 http://wenku.baidu.com/link?url=e07lO7mcb4f_tzFRQXveVjow0R4otowq9ROZLL5aoANQBUG3VlE0z0kYpBOuxtowHUISeTL8lepul-hSyDoixn49aWnLq3HBvqsBs-a875S 基JAVA的俄羅斯方塊游戲開發(fā)
3、 http://image.baidu.com/i?ct=503316480&z=&tn=baiduimagedetail&ipn=d&word 多線編程
4、 http://wenku.baidu.com/link?url=Hh_oYQfhalWzjDX2HHWbtOCHCTKkAb_1J2RuO2u_oLZNk5eTvEyFD-nneOCKFMIh_iscam9rtu6_aZo1RFiyEb7PdOuozLwwgYU4NLUGuMm 俄羅斯方塊設計文檔