前幾天在用點陣製作音樂頻譜儀的時候,被人問到能不能來做一個簡單的貪吃蛇遊戲,作為一個超級業餘創客,在我眼裡就沒有不可以,所以就有了下面的這個作品。
這個貪食蛇的遊戲機是通過手機藍牙和arduino主控板以串口的方式連接,然後通過arduino主控板的I2C接口和8*8的點陣相連,控制點陣上的LED閃爍來進行遊戲。
MAX7219點陣顯示模塊 led矩陣/8x8/I2C接口
DFrobot的Bluno Beetle控制器(Bluno Beetle是一款只有SD卡大小,集成藍牙4.0功能的Arduino主控器,用法同UNO)
杜邦線若干條
大家可以前往https://www.arduino.cc/en/Main/Software的官方下載地址下載,但是官方下載由於是國外網站經常打不開或者軟體下載不下來,
所以在這給大家提供另一個下載地址http://www.makerspaces.cn/forum.php?mod=viewthread&tid=14&extra=
關於arduino的語法手冊WIKI,我也在該網址下做了漢化,方便大家查找。http://www.makerspaces.cn/forum.php
建議下載綠色安裝包的即可,下載下來直接解壓縮即可。
Windows:XP、WIN7 32位需要手工更新驅動,驅動在IDE目錄下drivers\FTDI USB Drivers目錄中,指定目錄為之後自動搜索即可。WIN7 64位,WIN8自動在線更新驅動即可。
現在有的時候買的開發板由於USB晶片採用的方案不同,所用的驅動也不一樣,有一個非常容易的解決方案,下載驅動精靈,然後在有網絡的情況下點擊安裝驅動即可安裝完成。
下載IDE並解壓後,點擊arduino.exe文件進入軟體開發環境,自從1.5.8環境開始軟體可以自動變成系統預設語言。
然後選擇控制板型號,本次實驗使用的是Bluno Beetle控制器(同UNO),工具→板,選擇為arduino UNO即可。
然後選擇通訊埠,首先在設備管理器中找到UNO對應的埠COM(例如COM3),然後在工具→埠下選擇COM3。
接線方式:
由於這裡用到led點陣,所以需要加入點陣控制庫文件
我們需要將一些設置放置在頭文件中方便修改,新建頭文件snake.h,然後在主程序中加入頭文件:
頭文件snake.h 包含所用的一些常量設置和結構體
#define LOAD 3 //設置LED點陣控制引腳#define UP_KEY SWITCH_1#define RIGHT_KEY SWITCH_2#define DOWN_KEY SWITCH_3#define LEFT_KEY SWITCH_4#define HEIGHT 8 設置點陣範圍是8*8的#define SHOW_SCORE_TIMES 3 // 得分滾動顯示次數#define DEFAULT_SNAKE_LIFE 1 // 小蛇默認有1條命#define DEFAULT_SNAKE_SPEED 9900 // 小蛇初始速度標量#define DEFAULT_SNAKE_LENGTH 3 // 小蛇初始長度#define FOOD_FLASH_SPEED 300 // 食物閃爍速度標量#define SOUND 137#define SOUND_DURATION 4#define DEBUG_PRINT(ARGV) Serial.println(ARGV)#define DEBUG_PRINT(ARGV) NORMAL = 0, // 無特殊效果,增加一個蛇身長度 DOUBLE, // 增加2個蛇身長度 SLOWDOWN, // 減緩30%小蛇移動速度 ADD_LIFE, // 增加一個生命值 int length; // 蛇身長度 int life; // 剩餘生命值 int speed; // 小蛇移動速度 Direction direction; // 移動方向 Point body[WIDTH * HEIGHT]; // 蛇身坐標 FoodType type; // 食物類型 int flashInterval; // 閃爍頻度 Point position; // 食物位置} Food;
下面是主控制程序
#include <LedControl.h> //加入LED點陣控制庫文件#include "snake.h" //加入自己寫的頭文件LedControl lc = LedControl(DATA_IN, CLK, LOAD, 1); //設置點陣控制引腳Snake snake; //定義snake的結構體Food food; //定義food的結構體unsigned long ticks; //定義分數 {0, 60, 102, 66, 66, 102, 60, 0},/*"0",0*/ {0, 8, 120, 8, 8, 8, 8, 0},/*"1",1*/ {0, 60, 66, 6, 56, 96, 126, 0},/*"2",2*/ {0, 60, 66, 28, 2, 66, 60, 0},/*"3",3*/ {0, 12, 52, 68, 254, 4, 4, 0},/*"4",4*/ {0, 62, 32, 124, 66, 66, 60, 0},/*"5",5*/ {0, 60, 66, 124, 66, 66, 60, 0},/*"6",6*/ {0, 126, 4, 8, 16, 16, 32, 0},/*"7",7*/ {0, 60, 66, 60, 66, 66, 60, 0},/*"8",8*/ {0, 60, 66, 66, 62, 6, 124, 0},/*"9",9*/}; //分別設置0~9的顯示數組void initLedMatrix() //初始化led點陣void initSnake() //初始化小蛇 snake.length = DEFAULT_SNAKE_LENGTH; snake.speed = DEFAULT_SNAKE_SPEED; snake.life = DEFAULT_SNAKE_LIFE; for(int i = 0; i < snake.length ; i++) { snake.body[i].x = HEIGHT >> 1; snake.body[i].y = i + (WIDTH >> 1); lc.setLed(0, snake.body[i].x, snake.body[i].y, true);void getRandomFoodPosition() //獲得隨機食物的坐標 for(i = 0; i < snake.length; i++) { if(x == snake.body[i].x && y == snake.body[y].y) {void initFood() //初始化食物 food.flashInterval = FOOD_FLASH_SPEED;void initGame() //初始化遊戲void updateSnakeDirection() //上傳蛇的位置 if (Serial.available() > 0) { /* unsigned int keyVal = (!Esplora.readButton(UP_KEY) << 3) + (!Esplora.readButton(DOWN_KEY) << 2) + (!Esplora.readButton(RIGHT_KEY) << 1) + !Esplora.readButton(LEFT_KEY); case 85: //u的ascii碼是85 if(snake.direction == LEFT || snake.direction == RIGHT) { case 68: //d的ascii碼是68 if(snake.direction == LEFT || snake.direction == RIGHT) { case 82: //r的ascii碼是82 if(snake.direction == UP || snake.direction == DOWN) { case 76: //l的ascii碼是76 if(snake.direction == UP || snake.direction == DOWN) { if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { for(int i = 0; i < snake.length - 1; i++) { if(x == snake.body[i].x && y == snake.body[i].y) { if(ticks % snake.speed != 0) { switch(snake.direction) { int newX = snake.body[0].x + dx; int newY = snake.body[0].y + dy; if(newX == food.position.x && newY == food.position.y) { lc.setLed(0, snake.body[snake.length - 1].x, snake.body[snake.length - 1].y, false); for(int i = snake.length - 1; i > 0; i--) { snake.body[i] = snake.body[i - 1]; for(int i = 0; i < snake.length; i++) { lc.setLed(0, snake.body[i].x, snake.body[i].y, true); DEBUG_PRINT("GAME OVER"); int tensNum = snake.length / 10; int bitsNum = snake.length % 10; while(++count <= SHOW_SCORE_TIMES) { for(int r = 0; r < 8; r++) { for(int i = 0; i < 8; i++) { lc.setRow(0, i - r, numbers[tensNum][i]); lc.setRow(0, i - r + 8, numbers[bitsNum][i]); if(food.flashInterval != 0) { if(ticks % food.flashInterval == 0) { lc.setLed(0, food.position.x, food.position.y, food.visiable); food.visiable = !food.visiable; lc.setLed(0, food.position.x, food.position.y, food.visiable); initGame(); //初始化遊戲下載串口工具,我使用的是ios的,在蘋果商店裡搜索HackerRemote的app下載
然後手機設置中打開藍牙後,點擊運行HackerRemote的APP,然後點擊Scan。
點擊Scan後出現上面的界面,點擊Bluno,會出現第一個界面,這個時候點擊Connect
控制界面,按鍵UDLR分別表示上下左右。
再配上一個狂醜的盒子……
然後就可以開始玩遊戲了!
果殼空間和果殼實驗室聯手組成果殼雙創空間!在這裡,創業團隊可以享受果殼實驗室提供的評測報告,獲得來自創客的建議;創客們也可以在這裡提供你的腦洞想法,我們共同實現!此外,還有更多有趣好玩的線上、線下活動等著你的參與,精彩內容,聯手奉上。