編程一直很有趣,使用Arduino等開發平臺變得更好。幾乎每個程序員都會嘗試使用他們學習/練習的語言開發某種游戲。這有助于他們以有趣而富有成效的方式調整他們的編程技能。自從我接觸到Arduino以來,我一直是它的忠實粉絲,并且一直想嘗試一些很酷的東西,當我發現像諾基亞5110這樣的圖形LCD和Arduino可以變得多么酷時,我開發游戲的想法開始了。這是一種有趣的方式,可以調整一些編程技能,同時又能獲得樂趣,所以盡管你們可能也對開發游戲感興趣。因此,在本教程中,我們將學習如何使用 Arduino 和圖形 LCD 創建體面的游戲。
游戲計劃:
在我們開始之前,計劃你的游戲的實際運作方式是非常重要的。我選擇了諾基亞5110圖形LCD和操縱桿作為我的硬件選擇。我假設在本教程中您也選擇了相同的內容。由于諾基亞5110沒有太多空間,因此我們將整個游戲計劃在顯示器的84 * 48像素分辨率內。
在這個空間內,我們必須緊密地適應游戲區域和記分板區域,該區域將顯示分數等內容。了解放置東西的像素位置非常重要,以跟蹤像素位置并在屏幕上更新它們。
一旦確定了游戲屏幕外觀,我們就必須決定游戲中的角色。對于我的游戲,我們只有兩個,玩家角色是一艘宇宙飛船,一個是敵人角色,它應該看起來像一艘外星飛船。諾基亞LCD可以顯示位圖圖像,所以我決定使用該選項來顯示我的宇宙飛船和敵人。
因此,我們將有一艘宇宙飛船正在穿越外星人的宇宙飛船,這艘宇宙飛船將有三條車道可以改變,以避免與外星人撞擊。在任何時候,外星人只能占據兩條軌道,玩家應該能夠開車穿過自由軌道。一旦這些想法結束,我們就可以繼續硬件,然后進行編程。
電路圖:
這款Arduino游戲的電路非常簡單;我們只需要將諾基亞5110 LCD模塊和操縱桿與Arduino連接即可。完整的電路圖如下所示
諾基亞 5110 LCD 與 3.3V 配合使用,操縱桿模塊使用 5V 工作,因此請確保僅使用 3.3V 連接 LCD,因為 5V 可能會永久損壞它。LCD通過SPI協議與Arduino通信,操縱桿僅讀取ADC以讀取電壓變化。連接設置如下所示
先決條件:
在我們深入研究編程部分之前,重要的是你們使用顯示模塊和操縱桿很方便,因此您可以使用以下教程來了解有關它們的更多信息,然后回到這里以確保事情按照我們需要的方式工作!
為太空競賽游戲編程Arduino:
游戲的完整程序可以在本頁末尾找到;您可以直接在Arduino IDE上使用它并將其上傳到Board。但是,如果您想知道代碼中實際發生了什么,請進一步閱讀。
與往常一樣,我們從添加庫頭文件開始程序,我們需要為這個項目提供三個庫,默認情況下,SPI 庫會添加到您的 IDE 中。另外兩個庫必須從Adafruit Github頁面下載。如果您不確定如何添加庫,請按照先決條件部分中提到的 LCD 接口教程進行操作。
#include //SPI librarey for Communication
#include //Graphics lib for LCD
#include //Nokia 5110 LCD library
如果您遵循了本教程,您應該知道可以在LCD中顯示位圖圖像。因此,我們必須使用教程中提到的軟件將所需的圖像轉換為位圖代碼,您可以從Internet中選擇任何圖像并通過將它們轉換為位圖代碼來使用它。確保圖像足夠簡單,可以顯示在我們的LCD屏幕上,在實際嘗試LCD屏幕之前檢查預覽。在我們的程序中,我們使用了兩個位圖字符,一個是宇宙飛船,另一個是敵方飛船,兩者的位圖代碼都添加到我們的代碼中,如下所示。
//Bitmap Data for SpaceShip
static const unsigned char PROGMEM ship[] =
{
B00000000,B00000000,
B00000001,B00000000,
B00000011,B10000000,
B00000010,B10000000,
B00000010,B11000000,
B00000111,B11000000,
B00001101,B11100000,
B00011111,B11110000,
B00111111,B11111000,
B01111111,B11111100,
B01111111,B11111100,
B01111111,B11111100,
B00011111,B11110000,
B00000111,B11100000,
B00000000,B00000000,
};
//Bitmap Data for enemyship
static const unsigned char PROGMEM enemy[] =
{
B00000101,B11000000,
B00001011,B11100000,
B00000011,B11100000,
B00110011,B11111000,
B01111111,B11111100,
B10111111,B11111010,
B01110111,B11011100,
B01111110,B11111100,
B00111111,B11111100,
B11101111,B11101110,
B11000001,B00000110,
B10000001,B00000010,
B10000000,B00000010,
B00000000,B00000000,
};
我們必須指定諾基亞LCD 5110顯示器連接到的引腳。顯示器使用SPI通信進行通信,如果您遵循了上面的電路圖,則初始化LCD的代碼將如下所示,您無需更改它。
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3); //Specifiy the pins to which the LCD is connected
在設置功能中,我們只需以9600波特率啟動串行監視器,以便我們可以調試內容,然后初始化LCD顯示。我們還必須設置LCD顯示器的對比度,每個顯示器在不同的對比度水平下效果最好,因此請使用該值來檢查哪個最適合您。最后,我們還清除顯示屏以重新開始。
void setup() {
Serial.begin(9600); //Serial Monitor for Debugging
display.begin(); //Begin the LCD communication
display.setContrast(30); //Set the contrast of the display
display.clearDisplay(); // clears the screen and start new
}
清除屏幕后,我們立即跳入循環功能,然后顯示游戲屏幕。游戲屏幕只不過是顯示游戲的基本骨架以及分數和速度級別。我們使用線條功能繪制三條線作為邊框,并在右側顯示文本分數和速度,就像舊的復古手持游戲設備一樣。
void gamescreen()
{
//Draw the Border for Screen
display.drawLine(0, 0, 0, 47, BLACK);
display.drawLine(50, 0, 50, 47, BLACK);
display.drawLine(0, 47, 50, 47, BLACK);
//Enter Default Texts
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(52,2);
display.println("Speed");
display.setCursor(54,12);
display.println(game_speed);
display.setCursor(52,25);
display.println("Score");
display.setCursor(54,35);
display.println(score);
}
接下來,我們必須從用戶那里獲得輸入,以允許他/她控制宇宙飛船。輸入將從連接到引腳 A1 的操縱桿模塊接收。如果不移動,傳感器的模擬值將為 512,沿 X 軸移動時將增加和減少。我們使用這些值來確定用戶是要向左還是向右移動。如果您發現難以理解以下程序,您應該閱讀先決條件中提到的與 Arduino 接口的操縱桿接口教程。
//Get input from user
Joy_X = analogRead(A1); //Read the X vaue from Joystick
if (Joy_X < 312 && POS!=1 && control==true) //If joy stick moves right
{ POS--; control = false;} //Decrement position of spaceship
else if (Joy_X > 712 && POS!=3 && control==true) //If joy stick moves right
{ POS++; control = false;} //Increment position of spaceship
else if (Joy_X >502 && Joy_X<522) //If joystick back to initial position
control = true; //Preare it for next move
//Input from user received
從用戶那里獲得宇宙飛船的位置后,我們必須將宇宙飛船放置在該特定位置。我們使用以下函數并將位置值作為參數傳遞,然后根據位置將宇宙飛船放置在其各自的軌道上。
void player_car(char pos) //Place the spaceship based on the user selected position
{
if (pos==1)
display.drawBitmap(2, 32, ship, 15, 15, BLACK);
if (pos==2)
display.drawBitmap(18, 32, ship, 15, 15, BLACK);
if (pos==3)
display.drawBitmap(34, 32, ship, 15, 15, BLACK);
}
現在我們的飛船已經放在屏幕上并準備好參加比賽,我們必須介紹將與玩家一起競爭的敵艦。每當一艘敵艦越過屏幕時,我們都會假設他已經死了,當他死了時,我們必須制造一艘新的宇宙飛船。下面的函數也做同樣的事情。它為兩艘敵艦創建一個新位置,并將它們放置在屏幕頂部。
if (enemy_dead) //Check of enemy ships are dead
{ //If they are dead
enemy_0_pos = POS; //create first enemy above the space ship
enemy_1_pos = random(0,4); //create secound enemy at some other random place
enemy_phase = 0; //Bring the enemy form the top
enemy_dead = false; //Enemy is created so they are not dead anymore
}
將敵艦放在屏幕頂部后,我們必須將其放下,使其像我們的玩家正在向上奔跑一樣長矛,為此,我們只需要增加相位(顯示圖像的位置),以便它慢慢下降。對兩艘敵艦都做了同樣的事情,如下所示
enemy_ship (enemy_0_pos,enemy_phase); enemy_phase++; //Place the first enemy on screen and drive him down
enemy_ship (enemy_1_pos,enemy_phase); enemy_phase++; //Place the secound enemy on screen and drive him down
函數enemy_ship如下所示,它與播放器汽車函數非常相似,但這里我們有兩個參數。一種是將敵人放在軌道上,另一種是將敵人移動到底部。
void enemy_ship(int place, int phase) //Place the enemy_ship in the new place and phase
{
if (place==1)
display.drawBitmap(2, phase, enemy, 15, 15, BLACK);
if (place==2)
display.drawBitmap(18, phase, enemy, 15, 15, BLACK);
if (place==3)
display.drawBitmap(34, phase, enemy, 15, 15, BLACK);
}
下一段代碼應該檢查宇宙飛船是否避開了敵艦。要檢查這一點,我們需要知道敵艦和玩家的宇宙飛船的位置。既然我們知道了這一切,我們只需要檢查宇宙飛船的位置是否與敵艦相同。只有當敵艦到達宇宙飛船附近時,我們才會檢查這一點。如果玩家沒有避開敵人,則意味著游戲結束。
if (enemy_phase>22 && ((enemy_0_pos == POS) || (enemy_1_pos == POS)) ) //If the Spaceship touches any one of the enemy
game_over(); //Display game over
如果玩家成功避開了敵人,那么我們應該殺死敵人并給玩家一分。為此,我們只需檢查敵人是否已到達屏幕底部,如果是,我們將使用以下代碼將其殺死
if (enemy_phase>40) //If thespace ship escapes the enemies
{enemy_dead = true; score++;} //Increase the score and kill the enemies
如果我們在獲得高分時不增加游戲的難度,那將是多么有趣。因此,我們使用另一個功能來監控玩家的分數,并根據分數提高游戲速度。速度實際上是通過使用延遲功能來控制的,這將控制游戲的刷新間隔,從而使它變得快或慢。
void Level_Controller() //Increase the speed of game based on the score.
{
if (score>=0 && score<=10) //If score 0-10
{
game_speed = 0; delay(80); //slow the game by 80ms
}
if (score>10 && score<=20) //If score 10-40
{
game_speed = 1; delay(70); //slow the game by 70ms
}
if (score>20 && score<=30) //If score 20-40
{
game_speed = 2; delay(60); //slow the game by 60ms
}
if (score>30 && score<=40) //If score 30-40
{
game_speed = 3; delay(50); //slow the game by 50ms
}
}
Arduino太空賽車游戲工作:
在確保了解硬件和程序后,只需構建電路并將代碼上傳到Arduino板即可。您應該注意到游戲開始,如下所示
使用操縱桿通過向左或向右移動來逃離敵艦。為了避開每個敵人,你的分數會增加一個。當分數變高時,游戲的速度也會增加,也就是說,每獲得 10 分,速度就會增加 10 毫秒。您可以繼續在此游戲的基礎上引入新的關卡,或者每個人都使用加速度計進行一些硬件更改以通過運動來控制它。
/* SPACE RACE Game using Arduino and Nokia 5110 LCD
* Coded by: Aswinth Raj
* Input -> Joystick (A0,A1)
*/
#include //SPI librarey for Communication
#include //Graphics lib for LCD
#include //Nokia 5110 LCD librarey
//Bitmap Data for SpaceShip
static const unsigned char PROGMEM ship[] =
{
B00000000,B00000000,
B00000001,B00000000,
B00000011,B10000000,
B00000010,B10000000,
B00000010,B11000000,
B00000111,B11000000,
B00001101,B11100000,
B00011111,B11110000,
B00111111,B11111000,
B01111111,B11111100,
B01111111,B11111100,
B01111111,B11111100,
B00011111,B11110000,
B00000111,B11100000,
B00000000,B00000000,
};
//Bitmap Data for enemyship
static const unsigned char PROGMEM enemy[] =
{
B00000101,B11000000,
B00001011,B11100000,
B00000011,B11100000,
B00110011,B11111000,
B01111111,B11111100,
B10111111,B11111010,
B01110111,B11011100,
B01111110,B11111100,
B00111111,B11111100,
B11101111,B11101110,
B11000001,B00000110,
B10000001,B00000010,
B10000000,B00000010,
B00000000,B00000000,
};
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3); //Specifiy the pins to which the LCD is connected
int enemy_0_pos, enemy_1_pos, enemy_phase;
int Joy_X;
int game_speed = 0;
int score = 0;
char POS=2;
boolean enemy_dead = true;
boolean control = true;
void setup() {
Serial.begin(9600); //Serial Monitor for Debugging
display.begin(); //Begin the LCD communication
display.setContrast(30); //Set the contrast of the display
display.clearDisplay(); // clears the screen and start new
}
void loop() {
display.clearDisplay(); // clears the screen and start new
gamescreen(); //Displays the box, score and speed values
//Get input from user
Joy_X = analogRead(A1); //Read the X vaue from Joystick
if (Joy_X < 312 && POS!=1 && control==true) //If joy stick moves right?
{ POS--; control = false;} //Decrement position of spaceship
else if (Joy_X > 712 && POS!=3 && control==true) //If joy stick moves right
{ POS++; control = false;} //Increment position of spaceship
else if (Joy_X >502 && Joy_X<522) //If joystick back to initial position?
control = true; //Preare it for next move
//Input from user received
player_car(POS); //Place the Space ship based on the input from user
if (enemy_dead) //Check of enemy ships are dead
{ //If they are dead
enemy_0_pos = POS; //create first enemy above the space ship
enemy_1_pos = random(0,4); //create secound enemy at some other random place
enemy_phase = 0; //Bring the enemy form the top
enemy_dead = false; //Enemy is created so they are not dead anymore
}
enemy_ship (enemy_0_pos,enemy_phase); enemy_phase++; //Place the first enemy on screen and drive him down
enemy_ship (enemy_1_pos,enemy_phase); enemy_phase++; //Place the secound enemy on screen and drive him down
if (enemy_phase>22 && ((enemy_0_pos == POS) || (enemy_1_pos == POS)) ) //If the Spaceship touches any one of the enemy
game_over(); //Display game over
if (enemy_phase>40) //If thespace ship escapes the enemys
{enemy_dead = true; score++;} //Increase the score and kill the enemys
Level_Controller(); //BAsed on score increase the speed of game
display.display(); //Update the display with all the changes made so far
}
void Level_Controller() //Increase the speed of game based on the score.
{
if (score>=0 && score<=10) //If score 0-10 ?
{
game_speed = 0; delay(80); //slow the game by 80ms
}
if (score>10 && score<=20) //If score 10-40 ?
{
game_speed = 1; delay(70); //slow the game by 70ms
}
if (score>20 && score<=30) //If score 20-40 ?
{
game_speed = 2; delay(60); //slow the game by 60ms
}
if (score>30 && score<=40) //If score 30-40 ?
{
game_speed = 3; delay(50); //slow the game by 50ms
}
}
void enemy_ship(int place, int phase) //Place the enemy_ship in the new place and phase
{
if (place==1)
display.drawBitmap(2, phase, enemy, 15, 15, BLACK);
if (place==2)
display.drawBitmap(18, phase, enemy, 15, 15, BLACK);
if (place==3)
display.drawBitmap(34, phase, enemy, 15, 15, BLACK);
}
void game_over() //Display game over screen
{
while(1) //The program will be stuck here for ever
{
delay(100);
display.clearDisplay();
display.setCursor(20,2);
display.println("GAME OVER");
display.display();
}
}
void gamescreen()
{
//Draw the Border for Screen
display.drawLine(0, 0, 0, 47, BLACK);
display.drawLine(50, 0, 50, 47, BLACK);
display.drawLine(0, 47, 50, 47, BLACK);
//Enter Default Texts
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(52,2);
display.println("Speed");
display.setCursor(54,12);
display.println(game_speed);
display.setCursor(52,25);
display.println("Score");
display.setCursor(54,35);
display.println(score);
}
void player_car(char pos) //Place the spaceship based on the user selected position
{
if (pos==1)
display.drawBitmap(2, 32, ship, 15, 15, BLACK);
if (pos==2)
display.drawBitmap(18, 32, ship, 15, 15, BLACK);
if (pos==3)
display.drawBitmap(34, 32, ship, 15, 15, BLACK);
}
-
lcd
+關注
關注
34文章
4432瀏覽量
167837 -
Arduino
+關注
關注
188文章
6472瀏覽量
187358
發布評論請先 登錄
相關推薦
評論