0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Arduino和图形LCD创建体面的游戏

科技观察员 来源:circuitdigest 作者:阿斯文斯·拉吉 2022-11-15 17:29 次阅读

编程一直很有趣,使用Arduino等开发平台变得更好。几乎每个程序员都会尝试使用他们学习/练习的语言开发某种游戏。这有助于他们以有趣而富有成效的方式调整他们的编程技能。自从我接触到Arduino以来,我一直是它的忠实粉丝,并且一直想尝试一些很酷的东西,当我发现像诺基亚5110这样的图形LCD和Arduino可以变得多么酷时,我开发游戏的想法开始了。这是一种有趣的方式,可以调整一些编程技能,同时又能获得乐趣,所以尽管你们可能也对开发游戏感兴趣。因此,在本教程中,我们将学习如何使用 Arduino 和图形 LCD 创建体面的游戏。

游戏计划:

在我们开始之前,计划你的游戏的实际运作方式是非常重要的。我选择了诺基亚5110图形LCD和操纵杆作为我的硬件选择。我假设在本教程中您也选择了相同的内容。由于诺基亚5110没有太多空间,因此我们将整个游戏计划在显示器的84 * 48像素分辨率内。

pYYBAGNzXAeAaWyjAACRpsduyjE213.jpg

在这个空间内,我们必须紧密地适应游戏区域和记分板区域,该区域将显示分数等内容。了解放置东西的像素位置非常重要,以跟踪像素位置并在屏幕上更新它们。

一旦确定了游戏屏幕外观,我们就必须决定游戏中的角色。对于我的游戏,我们只有两个,玩家角色是一艘宇宙飞船,一个是敌人角色,它应该看起来像一艘外星飞船。诺基亚LCD可以显示位图图像,所以我决定使用该选项来显示我的宇宙飞船和敌人。

因此,我们将有一艘宇宙飞船正在穿越外星人的宇宙飞船,这艘宇宙飞船将有三条车道可以改变,以避免与外星人撞击。在任何时候,外星人只能占据两条轨道,玩家应该能够开车穿过自由轨道。一旦这些想法结束,我们就可以继续硬件,然后进行编程。

电路图:

这款Arduino游戏的电路非常简单;我们只需要将诺基亚5110 LCD模块和操纵杆与Arduino连接即可。完整的电路图如下所示

poYBAGNzXBCAWjw_AAFiPzpKMrg196.jpg

诺基亚 5110 LCD 与 3.3V 配合使用,操纵杆模块使用 5V 工作,因此请确保仅使用 3.3V 连接 LCD,因为 5V 可能会永久损坏它。LCD通过SPI协议与Arduino通信,操纵杆仅读取ADC以读取电压变化。连接设置如下所示

poYBAGNzXBKATHMkAADQf6qxo8c323.jpg

先决条件:

在我们深入研究编程部分之前,重要的是你们使用显示模块和操纵杆很方便,因此您可以使用以下教程来了解有关它们的更多信息,然后回到这里以确保事情按照我们需要的方式工作!

为太空竞赛游戏编程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板即可。您应该注意到游戏开始,如下所示

pYYBAGNzXBWAVm8mAACzuuYSUsA314.jpg

使用操纵杆通过向左或向右移动来逃离敌舰。为了避开每个敌人,你的分数会增加一个。当分数变高时,游戏的速度也会增加,也就是说,每获得 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
    lcd
    +关注

    关注

    34

    文章

    4278

    浏览量

    164146
  • Arduino
    +关注

    关注

    184

    文章

    6428

    浏览量

    184852
收藏 人收藏

    评论

    相关推荐

    请问怎么实现arduino图形界面编程?

    arduino图形界面编程,比如很简单的例子,我用c++编程个程序界面,然后通过点击图形界面的按钮实现arduino控制相关动作,比如说led灯亮,电机旋转! 求大神指教,或推荐相
    发表于 05-22 03:58

    图形LCD在嵌入式应用程序有什么应用?

    重量轻,携带方便,价格低廉,质量可靠。他们消耗很小的功率且更容易被眼睛接受。因为LCD不使用荧光粉及与大部分旧的CRT显示器相关的老化图像。彩色图形LCD(GLCDs)正越来越多地用于便携式应用,如手机,电子
    发表于 04-07 07:41

    使用arduino pro micro制作一个游戏控制器

    描述基于 Arduino 的 DIY 游戏控制器 | Arduino PS2 游戏控制器大家好,玩游戏总是很有趣,但是用自己的 DIY 自定
    发表于 09-01 06:38

    Arduino教程_Arduino图形化编程教程_ArduBlock

    Arduino教程_Arduino图形化编程软件_ArduBlock
    发表于 09-25 09:22 0次下载
    <b class='flag-5'>Arduino</b>教程_<b class='flag-5'>Arduino</b><b class='flag-5'>图形</b>化编程教程_ArduBlock

    LCD图形生成工具

    LCD图形生成工具
    发表于 12-01 16:44 13次下载

    ARDUINO LCD

    ARDUINO LCD
    发表于 01-22 17:33 13次下载

    如何使用Arduino制作Buzz Wire游戏

    Arduino 在构建爱好项目和游戏方面非常受欢迎,我们之前使用 Arduino 构建过贪吃蛇游戏、乒乓球游戏、太空竞赛
    的头像 发表于 08-17 16:50 1663次阅读
    如何使用<b class='flag-5'>Arduino</b>制作Buzz Wire<b class='flag-5'>游戏</b>

    使用Arduino创建

    电子发烧友网站提供《使用Arduino创建库.zip》资料免费下载
    发表于 11-08 14:37 0次下载
    使用<b class='flag-5'>Arduino</b><b class='flag-5'>创建</b>库

    arduino创建一个游戏控制器

    电子发烧友网站提供《用arduino创建一个游戏控制器.zip》资料免费下载
    发表于 11-10 11:21 1次下载
    用<b class='flag-5'>arduino</b><b class='flag-5'>创建</b>一个<b class='flag-5'>游戏</b>控制器

    TinkerCad电路上的Arduino LCD游戏

    电子发烧友网站提供《TinkerCad电路上的Arduino LCD游戏.zip》资料免费下载
    发表于 11-11 11:21 4次下载
    TinkerCad电路上的<b class='flag-5'>Arduino</b> <b class='flag-5'>LCD</b><b class='flag-5'>游戏</b>

    Arduino Esplora LCD屏幕实施的生命游戏交互式实施

    电子发烧友网站提供《为Arduino Esplora LCD屏幕实施的生命游戏交互式实施.zip》资料免费下载
    发表于 11-16 10:08 0次下载
    为<b class='flag-5'>Arduino</b> Esplora <b class='flag-5'>LCD</b>屏幕实施的生命<b class='flag-5'>游戏</b>交互式实施

    Arduino井字游戏和熄灯游戏开源分享

    电子发烧友网站提供《Arduino井字游戏和熄灯游戏开源分享.zip》资料免费下载
    发表于 11-24 11:34 0次下载
    <b class='flag-5'>Arduino</b>井字<b class='flag-5'>游戏</b>和熄灯<b class='flag-5'>游戏</b>开源分享

    Arduino微控制器使用而创建的Connect 4游戏

    电子发烧友网站提供《与Arduino微控制器使用而创建的Connect 4游戏.zip》资料免费下载
    发表于 11-24 14:41 0次下载
    与<b class='flag-5'>Arduino</b>微控制器使用而<b class='flag-5'>创建</b>的Connect 4<b class='flag-5'>游戏</b>

    基于ArduinoLCD上的小游戏

    方案介绍所需的部件如上图所示。从没有电源的Arduino开始。请勿插入USB电缆。这将在以后的步骤中进行编程和尝试游戏。连接 使用长连接线将Arduino上的5V信号连接到面包板顶部红色行的最左
    发表于 12-30 14:31 1次下载

    使用Arduino驱动LCD的DIY指南

    利用Arduino驱动LCD显示屏 目的本教程描述了如何使用Arduino驱动LCD显示屏。
    的头像 发表于 02-24 09:51 3768次阅读
    使用<b class='flag-5'>Arduino</b>驱动<b class='flag-5'>LCD</b>的DIY指南