0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何利用星火一號(hào)開發(fā)板制作貪吃蛇小游戲?

冬至子 ? 來源:BURRIEROW ? 作者:BURRIEROW ? 2023-08-28 17:04 ? 次閱讀

剛拿到星火一號(hào)板子想搞事情,逛論壇發(fā)現(xiàn) @zym_0208 發(fā)布了一個(gè)貪吃蛇的demo,于是下載下來玩了一下發(fā)現(xiàn)有些許bug,于是我在他的基礎(chǔ)上修改了一半,且把邏輯優(yōu)化了一下

工程中使用到的devices

上下左右四個(gè)按鈕,以及LCD屏幕

獲取pin
#define PIN_KEY0 GET_PIN(C, 0)
#define PIN_KEY1 GET_PIN(C, 1)
#define PIN_KEY2 GET_PIN(C, 4)
#define PIN_KEY3 GET_PIN(C, 5)
#define PIN_LED_R GET_PIN(F, 12)
在main函數(shù)中設(shè)置pin模式,綁定觸發(fā)模式,事件,使能中斷
rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY3, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(PIN_KEY0, PIN_IRQ_MODE_FALLING, keyDown, (void*)3);
rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING, keyDown, (void*)2);
rt_pin_attach_irq(PIN_KEY2, PIN_IRQ_MODE_FALLING, keyDown, (void*)4);
rt_pin_attach_irq(PIN_KEY3, PIN_IRQ_MODE_FALLING, keyDown, (void*)1);
rt_pin_irq_enable(PIN_KEY0, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY2, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY3, PIN_IRQ_ENABLE);

貪吃蛇的游戲設(shè)置

圖案屬性,雖然lcd屏幕的顯示上限很高,但是本工程只用簡單的字符打印代替圖案,所有字符都是16*16的正方形,所以下面所有東西的位置(x,y)都是16的倍數(shù),如果想要更高端的顯示,可以去了解一下lvgl

蛇的屬性:

struct {
int speed;
int len;
int x[SNAKESIZE];
int y[SNAKESIZE];
}snake;

食物屬性:

struct {
int x;
int y;
}food;

游戲邏輯
蛇碰到墻會(huì)GAMEOVER
蛇頭碰到蛇身會(huì)GAMEOVER
蛇頭碰到食物會(huì)變長一個(gè)單位
沒有操作時(shí)蛇會(huì)延記錄的方向移動(dòng)一個(gè)單位,我設(shè)置為300ms的delay
GAMEOVER后會(huì)顯示分?jǐn)?shù)

具體實(shí)現(xiàn)

每一個(gè)循環(huán),不管有沒有吃東西,直接增加蛇長度,也就是在移動(dòng)方向上頭前面加一個(gè)頭(抽象說法),再把蛇身體數(shù)組集體往前移一格,把原來的尾巴設(shè)為“ ”,然后再進(jìn)行判斷有沒有吃到東西。

lcd_show_string(snake.x[0], snake.y[0],16,"@");
lcd_show_string(snake.x[snake.len - 1], snake.y[snake.len - 1],16," ");
int tailx = snake.x[snake.len-1];
int taily = snake.y[snake.len-1];
for(int i = snake.len - 1; i > 0; i--){
snake.x[i] = snake.x[i-1];
snake.y[i] = snake.y[i-1];
}

吃到東西了,那就把尾巴再生成出來,同時(shí)搞個(gè)循環(huán)生成食物,這里的邏輯就是食物不能生在邊框,也不能生在蛇已有的身體上,就這么一直生下去直到生成合法食物。

//新生成一個(gè)合法食物
while (1)
{
int sameRegion = 0;
food.x = rand() % (MAPWIDTH/16)*16+16 ;
food.y = rand() % (MAPHEIGHT/16)*16 + 16;
//生成的食物橫坐標(biāo)的奇偶必須和初試時(shí)蛇頭所在坐標(biāo)的奇偶一致,因?yàn)橐粋€(gè)字符占兩個(gè)字節(jié)位置,不一致
//會(huì)導(dǎo)致吃食物的時(shí)候只吃到一半
//檢查是否食物生成到邊上
if(food.x % 2 == 0 && food.x>16 && food.x16 &&food.y {
//檢查是否食物與蛇身體重合
for (int i = 0; i < snake.len; i++)
{
if (snake.x[i] == food.x && snake.y[i] == food.y)
{
sameRegion = 1;
break;
}
}
}
else {
sameRegion = 1;
}
if(!sameRegion){
break;
}
}
沒吃到東西就無事發(fā)生,因?yàn)槲覀円呀?jīng)在一開始把尾巴設(shè)空過了

完整代碼
/*

Copyright (c) 2006-2021, RT-Thread Development Team

SPDX-License-Identifier: Apache-2.0

Change Logs:
Date Author Notes
2023-5-10 ShiHao first version
/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PIN_KEY0 GET_PIN(C, 0)
#define PIN_KEY1 GET_PIN(C, 1)
#define PIN_KEY2 GET_PIN(C, 4)
#define PIN_KEY3 GET_PIN(C, 5)
#define PIN_LED_R GET_PIN(F, 12)
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include
#define SNAKESIZE 100//蛇的身體最大節(jié)數(shù)
#define MAPWIDTH 240 //寬度
#define MAPHEIGHT 240//高度
volatile int key = 3;
int score = 0;
struct {
int x;
int y;
}food;
struct {
int speed;
int len;
int x[SNAKESIZE];
int y[SNAKESIZE];
}snake;
void drawMap()
{
//打印上下邊框
for (int i = 0; i <= MAPWIDTH/16+4; i++)
{
//將光標(biāo)移動(dòng)依次到(i,0)處打印上邊框
lcd_show_string(i
12,0,16,"#");
//將光標(biāo)移動(dòng)依次到(i,MAPHEIGHT)處打印下邊框
lcd_show_string(i*12,MAPHEIGHT-16,16,"#");
}
//打印左右邊框
for (int i = 1; i < MAPHEIGHT/16; i++)
{
//將光標(biāo)移動(dòng)依次到(0,i)處打印左邊框
lcd_show_string(0,i*16,16,"#");
//將光標(biāo)移動(dòng)依次到(MAPWIDTH, i)處打印左邊框
lcd_show_string(MAPHEIGHT-16,i*16,16,"#");
}
//隨機(jī)生成初始食物
while (1)
{
srand((unsigned int)time(NULL));
food.x = rand() % (MAPWIDTH/16)*16+16 ;
food.y = rand() % (MAPHEIGHT/16)*16+16;
if (food.x % 2 == 0){
if(food.x>16 && food.x16 &&food.y }
}
lcd_show_string(food.x, food.y,16,"*");
//初始化蛇的屬性
snake.len = 3;
snake.speed = 16;
//在屏幕中間生成蛇頭
snake.x[0] = 160;//x坐標(biāo)為偶數(shù)
snake.y[0] = 160;
//打印蛇頭
lcd_show_string(snake.x[0], snake.y[0],16,"@");
//生成初始的蛇身
for (int i = 1; i < snake.len; i++)
{
//蛇身的打印,縱坐標(biāo)不變,橫坐標(biāo)為上一節(jié)蛇身的坐標(biāo)值+16
snake.x[i] = (snake.x[i - 1] + 16);
snake.y[i] = snake.y[i - 1];
lcd_show_string(snake.x[i], snake.y[i],16,"#");
}
return;
}
void handleFood()
{
srand(time(RT_NULL));
lcd_show_string(snake.x[0], snake.y[0],16,"@");
lcd_show_string(snake.x[snake.len - 1], snake.y[snake.len - 1],16," ");
int tailx = snake.x[snake.len-1];
int taily = snake.y[snake.len-1];
for(int i = snake.len - 1; i > 0; i--){
snake.x[i] = snake.x[i-1];
snake.y[i] = snake.y[i-1];
}
if (snake.x[0] == food.x && snake.y[0] == food.y)//蛇頭碰到食物
{
snake.x[snake.len] = tailx;
snake.y[snake.len] = taily;
lcd_show_string(tailx, taily,16,"#");
snake.len++;//吃到食物,蛇身長度加1
score += 10;//每個(gè)食物得10分
//新生成一個(gè)合法食物
while (1)
{
int sameRegion = 0;
food.x = rand() % (MAPWIDTH/16)*16+16 ;
food.y = rand() % (MAPHEIGHT/16)*16 + 16;
//生成的食物橫坐標(biāo)的奇偶必須和初試時(shí)蛇頭所在坐標(biāo)的奇偶一致,因?yàn)橐粋€(gè)字符占兩個(gè)字節(jié)位置,不一致
//會(huì)導(dǎo)致吃食物的時(shí)候只吃到一半
//檢查是否食物生成到邊上
if(food.x % 2 == 0 && food.x>16 && food.x16 &&food.y {
//檢查是否食物與蛇身體重合
for (int i = 0; i < snake.len; i++)
{
if (snake.x[i] == food.x && snake.y[i] == food.y)
{
sameRegion = 1;
break;
}
}
}
else {
sameRegion = 1;
}
if(!sameRegion){
break;
}
}
lcd_show_string(food.x, food.y,16,"*");
}
rt_kprintf("new cycle!");
int pre_key = key ;//記錄前一個(gè)按鍵的方向
//判斷蛇頭應(yīng)該往哪個(gè)方向移動(dòng)
switch (pre_key)
{
case 3:
snake.x[0] -= snake.speed;//往左
break;
case 4:
snake.x[0] += snake.speed;//往右
break;
case 1:
snake.y[0]=snake.y[0]-snake.speed;//往上
break;
case 2:
snake.y[0]=snake.y[0]+snake.speed;//往下
break;
}
return;
}
void whereHead(){
rt_kprintf("x:%d ;",snake.x[0]);
rt_kprintf("y:%dn",snake.y[0]);
}
rt_bool_t snakeStatus()
{
whereHead();
//蛇頭碰到上下邊界,游戲結(jié)束
if (snake.y[0] <= 0|| snake.y[0] >= MAPHEIGHT-16)
return RT_ERROR;
//蛇頭碰到左右邊界,游戲結(jié)束
if (snake.x[0] <= 0 || snake.x[0] >= MAPWIDTH-16)
return RT_ERROR;
//蛇頭碰到蛇身,游戲結(jié)束
for (int i = 1; i < snake.len; i++)
{
if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
return RT_ERROR;
}
return RT_EOK;
}
void keyDown(void *args)
{
rt_kprintf("key %d rn",(int)args);
key = (int)args;
}
int main(void)
{
drawMap();
rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_KEY3, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(PIN_KEY0, PIN_IRQ_MODE_FALLING, keyDown, (void*)3);
rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING, keyDown, (void*)2);
rt_pin_attach_irq(PIN_KEY2, PIN_IRQ_MODE_FALLING, keyDown, (void*)4);
rt_pin_attach_irq(PIN_KEY3, PIN_IRQ_MODE_FALLING, keyDown, (void*)1);
rt_pin_irq_enable(PIN_KEY0, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY2, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_KEY3, PIN_IRQ_ENABLE);
while (1)
{
if (snakeStatus())
break;
handleFood();
rt_thread_mdelay(300);
}
lcd_show_string(MAPWIDTH / 2-32, MAPHEIGHT / 2,16,"Game Over!");
lcd_show_string(MAPWIDTH / 2-32, MAPHEIGHT / 2+16,16,"Score:");
lcd_show_num(MAPWIDTH / 2+16, MAPHEIGHT / 2+16,score,2, 16);
rt_thread_mdelay(5000);
return 0;
}

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • LCD屏
    +關(guān)注

    關(guān)注

    0

    文章

    120

    瀏覽量

    15271
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    566

    瀏覽量

    20384
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1239

    瀏覽量

    39430
  • LVGL
    +關(guān)注

    關(guān)注

    0

    文章

    79

    瀏覽量

    2735
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    用LabVIEW制作貪吃蛇小游戲的難度高么?大神們給點(diǎn)提示。

    用LabVIEW制作貪吃蛇小游戲的難度高么?大神們給點(diǎn)提示。
    發(fā)表于 11-19 17:02

    是否可以用msp430f5529制作貪吃蛇小游戲

    是否可以用msp430f5529制作貪吃蛇小游戲
    發(fā)表于 10-13 00:15

    【FPGA DEMO】Lab 9:貪吃蛇小游戲

    基于Perf-V開發(fā)板,實(shí)現(xiàn)貪吃蛇小游戲的設(shè)計(jì)。實(shí)驗(yàn)中用開發(fā)板上key1-key4按鍵來控制小蛇的移動(dòng),VGA設(shè)計(jì)該游戲的界面?;静襟E如上
    發(fā)表于 07-30 15:53

    種基于STM32的貪吃蛇小游戲開發(fā)方案

    基于STM32的貪吃蛇小游戲初學(xué)32個(gè)月,學(xué)的并不多,便想著做個(gè)貪吃蛇小游戲,因?yàn)橛?1單片
    發(fā)表于 08-04 08:23

    如何利用STM32制作貪吃蛇和推箱子游戲

    如何利用STM32制作貪吃蛇和推箱子游戲?
    發(fā)表于 09-27 08:07

    怎樣去開發(fā)種基于STM32的貪吃蛇小游戲

    怎樣去開發(fā)種基于STM32的貪吃蛇小游戲
    發(fā)表于 10-18 06:42

    利用LED矩陣、 鍵盤編寫個(gè)簡單的貪吃蛇游戲

    ** 貪吃蛇**By草木灰### 、實(shí)驗(yàn)內(nèi)容1、利用LED矩陣、 鍵盤編寫個(gè)簡單的貪吃蛇游戲
    發(fā)表于 12-15 09:20

    如何利用QT去制作個(gè)貪吃蛇小游戲

    如何利用QT去制作個(gè)貪吃蛇小游戲呢?并將其移植到嵌入式Linux平臺(tái)下呢?
    發(fā)表于 12-23 09:37

    如何利用單片機(jī)去實(shí)現(xiàn)個(gè)貪吃蛇小游戲

    如何利用單片機(jī)去實(shí)現(xiàn)個(gè)貪吃蛇小游戲呢?其代碼程序該怎樣去實(shí)現(xiàn)呢?
    發(fā)表于 01-20 07:15

    STM32+LCD實(shí)現(xiàn)簡單貪吃蛇小游戲的設(shè)計(jì)資料分享

    寒假放假回家,只能宅在家里,無聊之余,幸好帶了開發(fā)板回來,以前做項(xiàng)目都是在網(wǎng)上找相似或者有關(guān)聯(lián)的項(xiàng)目,把別人的代碼拿過來,修改修改,拼拼湊湊出自己項(xiàng)目,既然無聊就自己動(dòng)腦筋思考,自己動(dòng)手寫貪吃蛇的程序。下面是視頻效果: ST
    發(fā)表于 02-07 07:46

    基于stm32的貪吃蛇小游戲的設(shè)計(jì)資料分享

    指南者開發(fā)板上,使其能在觸摸屏上顯示,并且添加了暫停/繼續(xù)的觸摸按鍵以及簡單的游戲結(jié)束顯示,大體再現(xiàn)了貪吃蛇這款小游戲。、主要功能上圖是整
    發(fā)表于 02-21 07:27

    基于嵌入式linux開發(fā)板貪吃蛇游戲運(yùn)行

    如何在嵌入式linux開發(fā)板上運(yùn)行貪吃蛇游戲呢?本文以EasyARM-i.MX283A為硬件載體,簡述其運(yùn)行貪吃蛇小游戲的方法及步驟。
    的頭像 發(fā)表于 09-23 14:08 ?9589次閱讀

    STM32+LCD實(shí)現(xiàn)簡單的貪吃蛇小游戲

    寒假放假回家,只能宅在家里,無聊之余,幸好帶了開發(fā)板回來,以前做項(xiàng)目都是在網(wǎng)上找相似或者有關(guān)聯(lián)的項(xiàng)目,把別人的代碼拿過來,修改修改,拼拼湊湊出自己項(xiàng)目,既然無聊就自己動(dòng)腦筋思考,自己動(dòng)手寫貪吃蛇
    發(fā)表于 12-04 10:36 ?19次下載
    STM32+LCD實(shí)現(xiàn)簡單的<b class='flag-5'>貪吃蛇</b><b class='flag-5'>小游戲</b>

    基于stm32的貪吃蛇小游戲

    野火指南者開發(fā)板上,使其能在觸摸屏上顯示,并且添加了暫停/繼續(xù)的觸摸按鍵以及簡單的游戲結(jié)束顯示,大體再現(xiàn)了貪吃蛇這款小游戲、主要功能上圖
    發(fā)表于 12-24 19:32 ?21次下載
    基于stm32的<b class='flag-5'>貪吃蛇</b><b class='flag-5'>小游戲</b>

    基于STM32的貪吃蛇小游戲

    基于STM32的貪吃蛇小游戲初學(xué)32個(gè)月,學(xué)的并不多,便想著做個(gè)貪吃蛇小游戲,因?yàn)橛?1單片
    發(fā)表于 12-24 19:33 ?28次下載
    基于STM32的<b class='flag-5'>貪吃蛇</b><b class='flag-5'>小游戲</b>