|
编程一直是一项非常有趣的工作,使用像Arduino这样的开发平台会更加有趣。几乎所有的程序员都会尝试使用他们学习/练习的语言来开发某种游戏。这有助于他们以有趣而富有成效的方式调整自己的编程技巧。自从我认识它之后,一直是Arduino的忠实拥趸,并且一直想要尝试一些酷酷的东西,当我发现一起使用像诺基亚5110这样的图形液晶显示器和Arduino开发板是那么酷的事情时,开发游戏的想法开始实施。这是一个有趣的方式来调整一些编程技巧,同时玩得开心,同样你们也可以对开发你的游戏感兴趣。因此,在本教程中,我们将学习如何使用Arduino和图形LCD创建平面游戏。
我们已经使用Arduino开发板制作了老式的Snake游戏,所以这次我们尝试了一些新的东西,并且将此游戏命名为太空竞赛,您需要使用操纵杆使您的船舶免受敌方船只的伤害。
游戏设计 在我们开始之前,设计你的游戏如何实际工作是非常重要的。我选择了诺基亚5110图形液晶显示器和操纵杆作为硬件。由于诺基亚5110没有很大的空间,我们已经在显示器的84×48像素分辨率内规划了整个游戏。
在这个游戏中,我们必须使用游戏区域,以及在比分板区域显示比分等。了解像素放置位置的位置非常重要,以便跟踪像素位置并在屏幕上更新它们。
一旦游戏画面出现,我们必须决定游戏中的角色。对于我的比赛,我们只有两名球员角色,一名太空飞船和一名敌人角色,应该看起来像一艘外星飞船。诺基亚LCD可以显示位图图像,所以我决定使用该选项来显示我的太空飞船和敌人。
因此,我们将有一艘太空飞船通过外星人太空船进行比赛,为了避免与外星人撞击,这艘太空船将有三条航道改变。在任何时候,外星人只能占据两条赛道,玩家应该可以驾驶自由赛道。一旦这些想法得出结论,我们可以继续进行硬件和编程。
电路原理图 这款Arduino游戏的电路非常简单,我们只需要将诺基亚5110液晶显示模块和操纵杆与Arduino连接起来。完整的电路图如下所示
诺基亚5110液晶显示器可以在3.3V电压下工作,操纵杆模块可以工作在5V电压下,因此请确保只连接3.3V的LCD,因为5V会永久损坏。 LCD通过SPI协议与Arduino通信,操纵杆只读取ADC读取电压变化。连接设置将如下所示
编程Arduino太空竞赛游戏 游戏的完整程序可以在本页末尾找到;您可以直接在您的Arduino IDE上使用它并将其上传到您的开发板。
和往常一样,我们通过添加我们的库头文件来开始我们的程序,我们需要三个用于此项目的库,其中SPI库默认添加到您的IDE中。另外两个库必须从Adafruit Github页面下载。如果您不确定如何添加库,请按照前提条件部分中提到的LCD接口教程进行操作。 - #include <SPI.h> //SPI librarey for Communication
- #include <Adafruit_GFX.h> //Graphics lib for LCD
- #include <Adafruit_PCD8544.h> //Nokia 5110 LCD library
复制代码
如果您已经按照教程,您应该知道可以在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
复制代码
在setup函数中,我们只需以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
- }
复制代码
一旦屏幕被清除,我们跳进loop函数,在那里我们显示游戏屏幕。游戏画面不过是显示游戏的基本框架以及分数和速度等级。我们已经使用线条功能绘制三条线作为边界,右边我们显示文本得分和速度,就像旧复古手持游戏设备一样。 - 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轴移动时会增加和减少。我们使用这些值来确定用户是想要移动到左边还是右边。 - //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如下所示,它与player_car函数非常相似,但在这里我们有两个参数。一种是将敌人放在轨道上,另一种是将敌人移向底部。 - 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 Space Racer游戏工作过程 在确认了硬件和程序后,只需构建电路并将代码上传到Arduino开发板即可。你应该注意到游戏开始如下所示
通过向左或向右移动使用操纵杆逃脱敌方飞船。 为了避免每个敌人,你会得到你的分数增加1。 当比分变高时,比赛的速度也会增加,也就是说,每得到10分,速度就会增加10毫秒。 你可以继续前进,在这个游戏的基础上引入新的关卡或者每一个硬件改动来控制它,而不是使用加速度计运动。 创造力是唯一的限制。
希望你了解这个项目并且喜欢制作它。 如果您在开展此项工作时遇到任何问题,请随时在下面进行回复!
代码 本文使用的完整代码如下:
main.txt
(5.36 KB, 下载次数: 162)
|