大连林海 发表于 2015-11-1 09:21:20

Arduino贪吃蛇

本帖最后由 大连林海 于 2015-11-1 09:25 编辑

器材准备:

DFRobot Leonardo & Xbee R3

IO 传感器扩展板 V7.1

跳动的心 可编程8x8点阵模块

JoyStick摇杆(Arduino兼容)

作品特性描述:
* 吃到食物蛇身变长。
* 食物不会出现在蛇身上。
* 蛇每吃5个食物,移动速度增加一次。
* 场地无边界。
* 修复所有漏洞。
* 一键重置游戏。
* 增加摇杆控制。
* 增加手动加速功能。
* 摇杆实时高精度识别,加入防误触机制。


附上视频
http://v.youku.com/v_show/id_XMTM3MjU1MDcwMA==.html


代码如下:/*
*name:   贪吃蛇
*version:3.6 <NO BUG Version>
*Author:   Apple tec.<godfights@163.com>
*Date:   2015-10-23
*Description:BiColor IIC点阵
*note:   ©2015 Apple tec.All Rights
*                  Designed by LJ
*/
/*==================================================================================贪吃蛇=================================================================================================================*/
#include <Wire.h>                                                       // I2C链接库
#include "Adafruit_LEDBackpack.h"                                       // 点阵驱动库
#include "Adafruit_GFX.h"                                             // Arduino图形库

Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();               // 设置I2C点阵型号

static const uint8_t __attribute__ ((progmem)) X [] = { B01000010, B01000010, B00100100, B00011000, B00011000, B00100100, B01000010, B01000010 };   // 字母 X 的logo代码,其实就是一个一个点的量灭组成的

int speedS = 8;                                                         // 贪吃蛇的初始速度
int socre;                                                            // 游戏得分
int xValue;                                                             // JoyStick-X
int yValue;                                                             // JoyStick-Y
int zPin = 4;                                                         // JoyStick-Z
int Enabled;                                                            // 重启游戏使能
int FX, FY;                                                             // 食物的坐标
int SX, SY;                                                             // 蛇头的坐标
int KEY, K;                                                             // 当前按键码和实际按键码
char s = {};                                                       // 蛇身体坐标集合,一共64个点,二维坐标128个元素 其中0没有用到 故为129个元素
/***************************************************************************************************************************************************************************************************************/

void setup() {

/*
pinMode(A2, OUTPUT);            // 让A2 A3输出A2高电平 A3 低电平来达到VCC GND的目的20ma的输出能力足够点阵使用了
pinMode(A3, OUTPUT);            // 在此模式下需将显示方向设置为 3
digitalWrite(A2, HIGH);
digitalWrite(A3, LOW);
*/

pinMode(zPin, INPUT);

RANDOM();                         // 获取一个随机食物坐标
K = 0;                            // 初始化按键码,实际上就是行进方向 方向初始化为0 即在首次操作摇杆前 蛇不移动
s = 2;                         // x3
s = 2;                         // y3
s = 1;                         // x2
s = 2;                         // y2
s = 0;                         // x1
s = 2;                         // y1 初始化蛇的身体坐标      
socre = 0;                        // 游戏起始得分

matrix.begin(0x70);               // 设定IIC屏幕地址
matrix.clear();                   // 屏幕清屏
matrix.writeDisplay();            // 屏幕显示
matrix.setRotation(1);            // 设置屏幕显示方向0向左显示 1向上显示 2向右显示 3向下显示 默认值为0 若输入错误值4 显示方向保持默认0
matrix.clear();

Logo();                           // 绘制开机Logo

matrix.writeDisplay();
delay(1000);

matrix.setTextWrap(false);               // 设置字体平滑模式
matrix.setTextSize(1);                   // 设置字号
matrix.setTextColor(LED_GREEN);          // 设定LED颜色,0表示熄灭~

for (int8_t x = 7; x >= -70; x--) {      // for (int8_t x = -75; x <= 7; x++) {} 向右滚屏
    matrix.clear();
    matrix.setCursor(x, 1);                // setCursor(int16_t x, int16_t y)
    matrix.print( "READY!!! G0 " );
    matrix.writeDisplay();
    delay(70);
}
// 循环绘制文字,获得滚动效果

matrix.clear();
for(int i = 1; i <= 6; i += 2)                      // 从蛇头开始绘制三个点 s, s, s为x坐标 s, s, s为y坐标 蛇身排序: {s,s}{s,s}{s,s} (右侧为蛇头)
{
    matrix.drawPixel(s, s, LED_RED);      // drawPixel(int16_t x, int16_t y, uint16_t color)
}
matrix.writeDisplay();
delay(400);
}
// 循环绘制蛇的身体,实际上就是3个点咯~
/***************************************************************************************************************************************************************************************************************/

void RANDOM() {
A:   
FX = random(0, 7);
FY = random(0, 7);

for(int i = 1; i <= 6 + 2 * socre; i+= 2)            // 防止食物出现在蛇身上
{
    if( FX == s and FY == s)
      goto A;                              
}
}
// 随机食物获取函数
/***************************************************************************************************************************************************************************************************************/

void myDelay( int Time) {                           // 在蛇移动的延时期间 我们要做一些事情 比如食物的闪烁和摇杆方向的读取

for(int t = 1; t <= Time; t++)
{
    matrix.drawPixel(FX, FY, LED_GREEN);
    matrix.writeDisplay();
    delay(50);
    matrix.drawPixel(FX, FY, 0);
    matrix.writeDisplay();
    delay(50);
    joyStick();                                        // 读取摇杆方向      
}
}
// 这个是演示函数,实际上通过不断闪现食物来完成延迟,这样既可以做到精确延时,也可以让食物不断闪动,来让大家不断的看到~
/***************************************************************************************************************************************************************************************************************/

void Endelay( unsigned long duration) {                // 字幕滚动的延时期间 我们也要做一些事情 比如判断中央键是否被按下 按下则重置游戏

unsigned long Start = millis();
while(millis() - Start <= duration) {
    if(digitalRead(zPin) == LOW) {
      delay(20);
      if(digitalRead(zPin) == LOW) {
      Enabled = 1;
      }
      }
    }
}
// 重启游戏专用延时函数
/***************************************************************************************************************************************************************************************************************/

void Logo() {

matrix.drawPixel(6, 0, LED_YELLOW);          // X 右边笔画的动画
matrix.writeDisplay();
delay(35);
for ( int x = 1; x <= 6; x++) {               
    matrix.drawPixel(7-x, x, LED_YELLOW);
    matrix.writeDisplay();
    delay(35);
    }
matrix.drawPixel(1, 7, LED_YELLOW);
matrix.writeDisplay();
delay(35);

matrix.drawPixel(1, 0, LED_YELLOW);          // X 左边笔画的动画
matrix.writeDisplay();
delay(35);
for ( int x = 1; x <= 6; x++) {            
    matrix.drawPixel(x, x, LED_YELLOW);
    matrix.writeDisplay();
    delay(35);
    }
matrix.drawPixel(6, 7, LED_YELLOW);
matrix.writeDisplay();
delay(35);

for (int x = 1; x <= 45; x++) {                         // logo闪烁
    matrix.clear();
    matrix.writeDisplay();
    delay(x);
    matrix.drawBitmap(0, 0, X, 8, 8, LED_YELLOW);       // drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
    matrix.writeDisplay();
    delay(x);
    }
}
// Logo绘制函数,看不懂可以跳过~~~不过还是蛮简单的,仔细看下就明白了~
/***************************************************************************************************************************************************************************************************************/

void joyStick() {

xValue = analogRead(A0);                           // JoyStick-X   最左值为0 最右值为1023 中间值为515
yValue = analogRead(A1);                           // JoyStick-Y   最下值为0 最上值为1023 中间值为510

if(yValue == 1023 && KEY != 5) {
    K = 8;
    }
else if(yValue == 0 && KEY != 8) {
    K = 5;
    }
else if(xValue == 0 && KEY != 6 && K != 0) {         // 首次操作摇杆前 不能向左移动蛇
    K = 4;
    }
else if(xValue == 1023 && KEY != 4) {
    K = 6;
    }

if(digitalRead(zPin) == LOW)                         // 当按下中央键后 速度变为 2松开后 速度恢复到当前值
    speedS = 2;
else
    speedS = 8 - socre / 5;
}
// 这里是在比对按键方向是否和目前蛇的行进方向相反,如果相反就放弃按键
/***************************************************************************************************************************************************************************************************************/

void gameover() {                                    // 一旦执行到Gameover 程序停止 需要按下中央键后以重启游戏

Enabled = 0;
while(Enabled == 0) {

    for (int8_t x = 7; x >= -125 && Enabled == 0; x--) {
      matrix.clear();
      matrix.setCursor(x, 1);
      matrix.print( "GAME OVER YOUR SOCRE:" );
      matrix.writeDisplay();
      Endelay(70);
      }

    for (int8_t x = 7; x >= -39 && Enabled == 0; x--) {
      matrix.clear();
      matrix.setCursor(x, 1);
      matrix.print(socre);
      matrix.writeDisplay();
      Endelay(70);
      }
    }
    // GameOver函数,显示游戏结束和得分

    for(int i = 0; i < 129; i++) {
      s = 0;
      }

    K = 0;                  // 重置摇杆方向
    s = 2;
    s = 2;
    s = 1;
    s = 2;
    s = 0;
    s = 2;               // 重置蛇的坐标
    socre = 0;            // 重置游戏得分
}
/***************************************************************************************************************************************************************************************************************/

void loop() {

KEY = K;                                    // 蛇每移动一次 方向才能改变一次
matrix.clear();

if(KEY == 8)                                  // 蛇向上运动
{
    for(int i = 6 + 2 * socre; i > 3; i= i - 2)
    {
      s = s;
      s = s;
    }
    s = s - 1;
    if(s < 0)                              // 超出边框的从另一边继续出现
      s = 7;
}
else if(KEY == 5)                           // 蛇向下运动
{
    for(int i = 6 + 2 * socre; i > 3; i= i - 2)
    {
      s = s;
      s = s;
    }
    s = s + 1;
    if(s > 7)                              // 超出边框的从另一边继续出现
      s = 0;
}
else if(KEY == 4)                           // 蛇向左运动
{
    for(int i = 6 + 2 * socre; i > 3; i= i - 2)
    {
      s = s;
      s = s;
    }
    s = s - 1;
    if(s < 0)                              // 超出边框的从另一边继续出现
      s = 7;
}
else if(KEY == 6)                           // 蛇向右运动
{
    for(int i = 6 + 2 * socre; i > 3; i= i - 2)
    {
      s = s;
      s = s;
    }
    s = s + 1;
    if(s > 7)                              // 超出边框的从另一边继续出现
      s = 0;
}
// 根据按键来移动蛇的身体

for(int i = 1; i <= 6 + 2 * socre; i+= 2)   // 从蛇头开始绘制
{
    matrix.drawPixel(s, s, LED_RED);
}
matrix.writeDisplay();

myDelay(speedS);                              //()内为延时次数 延时一次为100ms实测200ms速度很合适 故将加速时速度设置为 2

SX = s;
SY = s;
// 获取蛇头的坐标

for(int i = 3; i <= 6 + 2 * socre; i+= 2)
{
    if( SX == s && SY == s)
      gameover();                              
}
// 判断蛇头是否碰到自己的身体,碰到就跳转到GameOver

if(SY == FY && SX == FX)
{
    socre ++;
    RANDOM();
    if( !(socre % 5)) {                     // 根据得分加快蛇的速度 每吃5个食物 速度快100ms
      speedS --;
      if(speedS < 2)                        // 速度下限为200ms 如果速度小于200ms 速度值仍为200ms
      speedS = 2;
      }
}
// 判断是否吃到了食物~吃到了就会加分和重新随机生成食物~
}

用到的库文件:







丄帝De咗臂 发表于 2015-11-1 11:49:30

不错啊,你做的么{:5_188:}

hnyzcj 发表于 2015-11-1 12:23:09

牛叉

大连林海 发表于 2015-11-1 16:42:41

丄帝De咗臂 发表于 2015-11-1 11:49
不错啊,你做的么

看那么长的代码 你懂得{:5_130:}

大连林海 发表于 2015-11-1 16:43:11

hnyzcj 发表于 2015-11-1 12:23
牛叉

看我能把用到的东西都列出来 哈哈

孙毅 发表于 2015-11-1 23:27:07

给跪了

大连林海 发表于 2015-11-2 07:49:08

孙毅 发表于 2015-11-1 23:27
给跪了

高手在民间是不是很厉害{:5_168:}

Jason_G 发表于 2015-11-7 22:39:16

有意思,喜欢!

Ash 发表于 2015-12-1 15:37:17

转载的项目还是要放一下原作者和链接啦~

lin 发表于 2016-8-18 09:04:51

挨炮科技的项目。。。

20060606 发表于 2020-8-16 05:20:02

您用的是什么LED模块

发表于 2022-4-17 09:17:12

《高手在民间》

发表于 2022-4-17 09:25:14

高手两个含义
一个是创客高手
还一个是游戏高手
页: [1]
查看完整版本: Arduino贪吃蛇