Arduino+OLED 简易贪吃蛇教程
本帖最后由 韋編弎絕 于 2014-8-9 19:13 编辑第一版实现了基本功能,操作上下左右按键实现蛇的移动,吃到食物增长。但没有实现碰壁、碰己的监测,食物固定不随机生成。
=========================准备=========================
一、所需硬件
1. Arduino Nano1个;
2. 0.96寸OLED (SPI接口) 1个;
3. 10*10*5mm 轻触开关4个。
二、所需软件
1. U8glib库;
2. Arduino 1.0.5 IDE。
三、硬件连接
1. OLED
arduino OLED
D9 > MOSI
D10 > SCK
D11 > DC
D12 > CS
D13 > RES
2. 轻触开关
arduino button
D2 > DOWN下
D3 > RIGHT 右
D4 > LEFT 左
D5 > UP 上
=======================必备知识=======================
arduino Nano,OLED等的介绍不再赘述,网上很多,看一下贪食蛇游戏所需的 u8glib 库提供的方法,标题中未加参数,仅作简单介绍,详情请查看https://code.google.com/p/u8glib/wiki/userreference。
对u8glib熟悉的看官可以忽略~~~。
引入u8glib的库之后,需要建立一个对象,并定义好引脚。
U8GLIB_SSD1306_128X64 u8g(10, 9, 12, 11, 13); //SCK = 10, MOSI = 9 , CS = 12, A0 = 11, RES = 13
1.u8g.drawBitmapP();
1)方法定义 void U8GLIB::drawBitmapP(u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap) 2)功能
显示一个位图
3)参数
x:位图左上角的横坐标
y:位图左上角的纵坐标
cnt:在水平方向上的位图的字节数。该位图的宽度是cnt* 8(1字节=8位)
h:位图的高
*bitmap:位图对象
4)例子const uint8_t rook_bitmap[] U8G_PROGMEM = {
0x00, // 00000000
0x55, // 01010101
0x7f, // 01111111
0x3e, // 00111110
0x3e, // 00111110
0x3e, // 00111110
0x3e, // 00111110
0x7f // 01111111
};
...
u8g.drawBitmapP(0,0, 1, 8, rook_bitmap);
2.u8g.drawFrame();
1)方法定义void U8GLIB::drawFrame(u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) 2)功能
此函数是一个画方框的方法。
3)参数
x:方框左上角点的横坐标
y:方框左上角点的纵坐标
w:方框的宽
h:方框的高
4)例子u8g.drawFrame(10, 12, 30, 20); // 方框的长宽包括了边框所在的像素点
3.u8g.setFont();
1)方法定义U8GLIB::setFont(const u8g_fntpgm_uint8_t *font)
2)功能
设置要显示字符的字体。
3)参数
*font:字体样式。u8glib提供的字体样式https://code.google.com/p/u8glib/wiki/fontsize
4.u8g.drawStr();
1)方法定义u8g_uint_t U8GLIB::drawStr(u8g_uint_t x, u8g_uint_t y, const char *s) 2)功能
显示字符
3)参数
x:字符左下角的横坐标
y:字符左下角的纵坐标
*s:要显示的字符
4)例子U8GLIB u8g(...)
...
u8g.setFont(u8g_font_osb18);
u8g.drawStr(0, 20, "ABC");
5.u8g.setPrintPos();
1)方法定义void U8GLIB::setPrintPos(u8g_uint_t x, u8g_uint_t y) 2)功能
设置下文中print()的显示位置
3)参数
x:横坐标
y:纵坐标
6.u8g.print();
1)方法定义U8GLIB::print(...) 2)功能
打印要显示的字符,包括变量值、字符串等。使用前需要使用setPrintPos()函数设置位置
7.u8g.firstPage();
1)方法定义void U8GLIB::firstPage(void) 2)功能
调用此过程,标志着图像循环的开始
8.u8g.nextPage();
1)方法定义uint8_t U8GLIB::nextPage(void) 2)功能
调用此过程,标志着图像循环的结束
若要使图像正常显示,u8glib库提供了如下的代码格式void loop() {
u8g.firstPage();
do {
//draw
}while(u8g.nextPage());
}
=========================教程========================
1.贪吃蛇算法
本贪吃蛇代码参考使用一下教程。
http://www.oschina.net/code/snippet_143423_4296
http://v.mybdqn.com/v_show/id_86.html
http://v.mybdqn.com/v_show/id_87.html
贪吃蛇会按照一定的间隔时间朝着一个方向移动,通过上下左右操作控制蛇移动方向。蛇的移动有两种算法可以使用。
1. 火车头拉着走。
2. 加头去尾。
相对来说用火车头拉的方式是比较流行也是初学者最好掌握的方式。首先确定一个蛇头的坐标,蛇头每移动一次,蛇头后的每一节为前一节的旧坐标。
2.定义结构体struct FOOD {
int x;
int y;
int yes;
};
FOOD food = {25, 30, 1};
struct SNAKE {
int x;
int y;
int node;
int dir;
int lefe;
};
SNAKE snake = {{9,5}, {30,30}, 2, RIGHT, 0};
3.组成贪吃蛇的单位//组成单位,4X4像素点的方块。
const uint8_t ele[] PROGMEM = {
0xf0, //B1111000
0xb0, //B1011000
0xd0, //B1101000
0xf0, //B1111000
};
//蛇
void element(int x, int y) {
u8g.drawBitmapP(x,y, 1,4, ele);
}
■ ■ ■ ■ □ □ □ □B111100000xF0
■ □ ■ ■ □ □ □ □B101100000xB0
■ ■ □ ■ □ □ □ □B110100000xD0
■ ■ ■ ■ □ □ □ □B111100000xF0
这样一个4*4的方块为组成蛇的一个单位。
4.游戏的主界面void UI() {
u8g.drawFrame(0,1, 102,62); //内边界
u8g.drawFrame(0,0, 102,64); //外边界
u8g.setFont(u8g_font_5x7); //设置字体
u8g.drawStr(104,12, "LEVEL"); //等级提示
u8g.drawStr(104,40, "SCORE"); //分数提示
}
5.按键的获取void setup() {
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
}
//按键判断
void key() {
if(LOW == digitalRead(2)) {
snake.dir = DOWN;
}
if(LOW == digitalRead(3)) {
snake.dir = RIGHT;
}
if(LOW == digitalRead(4)) {
snake.dir = LEFT;
}
if(LOW == digitalRead(5)) {
snake.dir = UP;
}
}
6.蛇的移动switch(snake.dir) {
case RIGHT:
snake.x += 4;
if(snake.x>=101) {
snake.x = 1;
} break;
case UP:
snake.y -= 4;
if(snake.y<=1) {
snake.y = 58;
} break;
case LEFT:
snake.x -= 4;
if(snake.x<=0) {
snake.x = 97;
} break;
case DOWN:
snake.y += 4;
if(snake.y>=62) {
snake.y = 2;
} break;
}
for(i=snake.node-1;i>0;i--) {
snake.x = snake.x;
snake.y = snake.y;
}
7.吃到食物
蛇头坐标与食物坐标相同,说明蛇吃到了食物。if((snake.x == food.x) && (snake.y == food.y)) {
snake.x = food.x;
snake.y = food.y;
snake.node++;
food.yes = 1;
score += 2;
level = score/10+1;
}
8.画出图像
在do-while循环中写入代码,画出整个界面u8g.firstPage();
do {
UI(); //画主界面
//画蛇
for(i=0; i<snake.node;i++) {
element(snake.x, snake.y);
}
//画食物
element(food.x, food.y);
//写分数
printScore(109, 22, level);
printScore(109, 50, score);
}while(u8g.nextPage());
本人能力有限,如有错误,还望看官海涵轻喷指正。本教程抛砖引玉希望大家DIY出更好的作品。
源文件: 很详细的教程,我喜欢 努力微笑 发表于 2014-8-4 07:30 static/image/common/back.gif
很详细的教程,我喜欢
:handshake谢谢~ 高阶U8GLIB库教程啊。 赞!赞!赞!赞! 附件 u8glib_arduino_v1.17.zip 最新的V1.17版本的库 6脚的oled没有cs接口能用这个程序吗?
請問有哪些要自己打的? 我執行程式有錯誤 很好,就喜欢详细的, 最近研究oled 中,貌似新的ug8lib库会编译错误 请教一下IIC的屏程序怎么改 详细的教程 非常详尽的教程!
页:
[1]