1. 程式人生 > >貪吃蛇(C++ OpenGL)

貪吃蛇(C++ OpenGL)

  系統地看了C++ primar,加上之前用過OpenGL庫,於是心血來潮想要寫一個簡單的貪吃蛇遊戲玩玩。

1.類間關係和類圖

這裡寫圖片描述
  我設計了四個類,分別是Draw(用於繪製),Board(負責記錄蛇身的位置和建立食物),Snake(儲存蛇身的位置資訊和前進的方向),keyEvent(按鍵事件,改變前進方向)。Draw類從Snake類中獲得蛇身體位置的資訊,從Board類中獲得食物位置的資訊,從而分別繪製蛇身和食物。蛇和食物都是實心正方形構成的,把實心正方形的右上角的座標作為正方形的位置座標。Board類中維護了一個座標矩陣,矩陣中的元素有0,1兩種值,1表示該位置被蛇身佔用,0表示該位置空閒,這個矩陣和Snake中的蛇身向量body同步更新,目的是在Board呼叫生成食物的方法時,從座標矩陣的空閒位置中隨機選取座標,這樣生成的食物不會和蛇身重疊。Snake類中的body變數儲存蛇身位置資訊,move()方法配合OpenGL的glutTimerFunc()函式使用,即每隔固定時間呼叫move(),使得蛇能不斷前進。move()方法中會呼叫dirCheck()和checkCrash()分別進行方向檢查和碰撞檢查,同時move()方法中還有一個是否吃到食物的判斷,經過判斷後執行不同的操作。設計keyEvent類的時候嘗試著使用了一下命令模式,即通過建構函式持有Snake物件的指標,這樣就可以修改Snake物件中的方向資訊了。

2.程式流程

這裡寫圖片描述

3.createFood

  從Board類維護的位置矩陣中隨機挑選值為0的座標,先挑行座標,再挑列座標,由於位置矩陣是隨時更新的,所以不會產生食物和蛇身重合的現象。

4.eatFood

  蛇移動的實現方法是這樣的:把移動方向的下一個位置插入蛇身變數vector body(Snake類中)的首位置,去掉body向量的最後一個元素。如果吃到食物,那麼就不需要去掉body向量的最後一個元素。所以在”去掉body向量的最後一個元素”這個操作前做一次是否吃到食物的判斷就可以了。

5.crash

  碰撞檢測分兩種,一種是撞到圍牆,一種是撞到自身。檢測是否撞到自身只需要遍歷一遍vector body,判斷是否有的點和body的首元素重複。而檢測撞到圍牆並不需要遍歷整個board的所有座標,只需要判斷蛇頭的橫座標是否到達board橫座標的極限,蛇頭的縱座標是否到達board縱座標的極限。

6.效果圖

這裡寫圖片描述