貪吃蛇大作戰JavaFx版完整原始碼

silence1772發表於2018-03-25

貪吃蛇大作戰 Java版

專案原始碼:https://github.com/silence1772/JavaFX-GreedySnake

(記得點star啊,收藏一個專案最好的方式是star而不是fork)

遊戲下載:貪吃蛇大作戰.exe

                 貪吃蛇大作戰.jar

遊戲截圖:



幾句話:

這個遊戲是去年寫的,用來交資料結構作業的,本來在大一暑假時我就開始寫,那時老師還沒提具體要求,我就用unity3d配合C#寫了個高仿貪吃蛇大作戰,自認為效果不錯,如下圖:



結果等到開學了老師佈置了一下具體要求,只能用Java或者C++來寫,沒辦法重新寫就重新寫吧,剛好新學期學Java,書上介紹的圖形介面程式設計庫是Javafx,於是就趕工寫了上面的遊戲交上去,程式碼質量肯定是有點不足,不過還是想分享出來給大家看一下。至於unity3d版的貪吃蛇大作戰,專案打包下載:點選開啟連結


遊戲說明:

專案結構如上圖,程式碼全都在src資料夾,有兩個包,第一個是core包,稱之為核心,程式碼抄襲自點選開啟連結還有點選開啟連結

第二個是snake包,主要的內容和操作都在這裡面,時間隔了太久也記不清具體的實現細節了,所以就直接把當時交的實驗報告裡的內容複製上來,因為交作業嘛,大家都懂,瞎扯的內容居多,閱讀體驗肯定比不上自己寫的部落格,還請各位看官多加包涵。


---------------------------------------------------分割線---------------------------------------------------

實驗報告部分內容如下:


2.1 確定技術路線

我們選擇Java作為此次開發的語言,同時選用JavaFx庫來進行圖形化介面程式設計。開發平臺為windows + eclipse

JavaFXJava的下一代圖形使用者介面工具包。JavaFX是一組圖形和媒體API,我們可以用它們來建立和部署富客戶端應用程式。

2.2 遊戲整體架構

遊戲的主要執行介面是基於JavaFx提供的canvas(畫布)API來實現的,為了編寫方便,同時也為了使程式更加簡潔高效,我們先編寫了一個基礎的遊戲框架,再以此框架為基礎,進行遊戲功能的開發。通過對要實現的遊戲功能進行初步討論確定,以及對各項功能進行技術可行性驗證後,我們最終確定瞭如下圖所示的整體架構:

 

2.3 程式開發分工

......

2.4 基礎框架編寫

基礎框架的編寫基於Javafx庫,Javafx已經內建在我們使用的jdk8環境中,因此直接匯入即可。編寫的第一步便是建立程式入口,在Javafx中,Application類是程式的入口點,該類中的launch用於啟動一個獨立的Javafx應用,也就是說,程式的主類要繼承Application類,並且重寫 (Overriding)start方法,然後在main方法中呼叫其launch方法來啟動程式。

public abstract class SApplication extends Application {

private Group mGroup;

private Scene mScene;

 

@Override

public void start(Stage primaryStage) throws Exception {

before();

mGroup = new Group();

mScene = new Scene(mGroup, SContants.WIDTH, SContants.HEIGHT);

after();

showStage(primaryStage);

}

}

以上為SApplication類程式碼片段(如無說明下文程式碼均為選取片段),該類start方法中引數Stage物件是Javafx中的一個窗體,類似舞臺,而Scene物件表示在舞臺下的一個場景,Group用於儲存場景中各種Object。當該類啟動時,JVM便建立該類的一個例項,同時呼叫其start方法。start方法一般用於將UI元件放入一個場景,並且在舞臺中顯示該場景。

有了主類後,接下來我們需要在這個舞臺、場景上進行表演,Javafx提供的Canvas(畫布)便是表演的組織形式,這裡我們引人遊戲程式設計中的幾個概念,一個是時間線,一個是幀,一個遊戲可以看成是一個無限迴圈執行的程式,亦即一條長長的時間線,在這個迴圈中每次迴圈便是一幀,我們定義一個SScreen類繼承自Canvas類,在每一幀中均重繪場景中的物件,便形成了一個動態執行的遊戲畫面。

public abstract class SScreen extends Canvas implements SEvent {

public SScreen(double width, double height) {

super(width, height);

initTimeLine();

}

private void initTimeLine() {

timeline = new Timeline();

timeline.setCycleCount(Timeline.INDEFINITE);

keyFrame=newKeyFrame(Duration.millis(duration),newEventHandler<ActionEvent>() {

@Override

public void handle(ActionEvent arg0) {

draw(getGraphicsContext2D());

update();

}

});

timeline.getKeyFrames().add(keyFrame);

}

}

如上,我們初始化時間線,並且在時間線上新增關鍵幀,在每一幀中我們都呼叫draw()方法和update()方法,這兩個方法主要是渲染圖形和重新整理圖形。

在這個程式中,我們把所有遊戲物件都抽象成一個基類SObject,這個類主要是物件的各種屬性,如長度、寬度等,同時也有一個檢測是否兩個Object是否接觸的方法用來檢測貪吃蛇是否發生碰撞。

public abstract class SObject implements SEvent {

protected DoubleProperty widthProperty = new SimpleDoubleProperty(0);

protected DoubleProperty heightProperty = new SimpleDoubleProperty(0);

protected DoubleProperty xProperty = new SimpleDoubleProperty(0);

protected DoubleProperty yProperty = new SimpleDoubleProperty(0);

protected BooleanProperty updateProperty = new SimpleBooleanProperty(true);

protected BooleanProperty visibleProperty = new SimpleBooleanProperty(true);

}

有了以上三個基礎類後整個遊戲框架就基本建立起來了,再來就是配置類SCcontants用來管理視窗的大小,蛇的大小等,事件類SEvent表示鍵盤滑鼠事件。

2.5 蛇相關類編寫

蛇相關類是整個程式最重要的一部分,首先對於一條蛇,我們將其看作是由一個蛇頭和蛇身組成的,分別對應BaseSnake類和BaseBody類,前者負責控制蛇頭按照其Direction(方向)變數移動,後者則控制蛇身移動。這裡蛇身的移動策略是這樣的,首先它的建構函式有一個引數為BaseSnake類,這裡將兩者位置屬性繫結在一起,蛇身是由一個個圓形排列在一起形成的,使用類似雙端佇列的結構(list)儲存,每次移動時,就將這一串圓形的最後一個刪除,同時新增一個新的圓形到蛇頭的位置,因為蛇頭也在這段時間內向前移動了,這樣就形成了前進的效果,當然如果是吃到了食物的話,那就只新增圓形而不刪除。如下圖所示:

 

有了這兩個基礎類組成蛇之後,我們還需要分別設計兩個類來繼承BaseSnake類,一個作為被玩家使用鍵盤控制的蛇UserSanke類,另一個為電腦控制的蛇AISnake類。對於玩家來說,主要是通過方向鍵來控制蛇,蛇的移動有八個方位,玩家使用方向鍵可改變基類中的Direction變數,然後基類通過計算該方向在x軸、y軸的移動量來往這個方向移動。而電腦蛇的移動策略也比較簡單,每個一段時間檢測一次食物在哪個方位,然後更新方向變數即可。

2.6 介面UI

介面UI比較簡單,主要是呼叫Canvas的渲染影像api把圖形畫出來,包括兩個類,一個是Info類,負責顯示遊戲進行中的各種資訊,如當前得分、剩餘時間等,另一個是GameOver類,負責顯示遊戲結束時的提示畫面。

2.7 食物類與時間類

食物類主要是隨機選取一個位置生成食物,當食物被吃了之後,就繼續生成一個。

時間類,其實就是提供給介面UI的倒數計時,這個類單獨開了一個執行緒,在這個執行緒上設定遞減計數,每計一次執行緒就休眠一秒,再把計數器宣告一個方法暴露出去,這樣就形成了按秒的倒數計時。

2.8 主遊戲場景

這個GameScreen類繼承自SScreen類,是遊戲的主要執行場景,這裡要引人一個層的概念,即遊戲畫面是由一層層的物件疊加而成的,在這個類中,我們將UI層放在最上面,將蛇(包括user蛇和AI蛇)放在中間層,最底層是食物,這樣疊加起來就形成我們看到的遊戲畫面了。

同時在這個類中,我們進行大部分的操作,如呼叫UI更新資訊的方法,檢測是否吃到食物,是否發生碰撞等。

另外,這裡還設定了一個功能,就是蛇的穿牆操作,當蛇前進到邊界後,它會從邊界的映象方向出現,形成了穿牆,其實就是當蛇頭進入邊界外後,更新蛇的位置座標到相反方向。

2.9 程式入口

MainEnter類既是程式的入口,也是程式的流程控制器,當進入程式後,它先顯示出開始介面以及開始遊戲的按鈕,點選按鈕後,程式會把主遊戲場景掛載在該類下,也就是顯示了主遊戲場景,開始了遊戲,當遊戲結束或者點選返回按鈕後,程式會把主遊戲場景刪除掉,繼而回到開始介面,形成一個完整的遊戲邏輯。

 

相關文章