Atmega16单片机贪吃蛇小游戏.docx

上传人:b****6 文档编号:3860516 上传时间:2022-11-25 格式:DOCX 页数:41 大小:196.09KB
下载 相关 举报
Atmega16单片机贪吃蛇小游戏.docx_第1页
第1页 / 共41页
Atmega16单片机贪吃蛇小游戏.docx_第2页
第2页 / 共41页
Atmega16单片机贪吃蛇小游戏.docx_第3页
第3页 / 共41页
Atmega16单片机贪吃蛇小游戏.docx_第4页
第4页 / 共41页
Atmega16单片机贪吃蛇小游戏.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

Atmega16单片机贪吃蛇小游戏.docx

《Atmega16单片机贪吃蛇小游戏.docx》由会员分享,可在线阅读,更多相关《Atmega16单片机贪吃蛇小游戏.docx(41页珍藏版)》请在冰豆网上搜索。

Atmega16单片机贪吃蛇小游戏.docx

Atmega16单片机贪吃蛇小游戏

Atmega16单片机贪吃蛇小游戏

程序原创,好用!

缺少财富值的可以私信我,我发给你。

代码中有qq

代码基于Atmega16芯片,晶振采用8M,LCD12864采用并行通信,四个独立按键,以下是相关的原理图。

控制贪吃蛇前进的核心思路是:

点亮头部,熄灭尾部。

关于蛇身子的点可以采用一个数组来存储。

把数组变成一个循环队列,前进头部数据入队,尾部数据出队,这种方法控制起来简单一些,但是比较消耗内存(嗯,有点奢侈)单片机RAM仅1k,蛇的最大长度500左右。

另外我们可以只存下蛇身子的拐点,记录下拐点的方向,就可以得出蛇身子位置信息。

(本代码采用此种记录方式)。

现在举例说明一下数据的值,如图所示表示一条蛇,2表示蛇头,1表示蛇尾

structsnake_type//定义一个砖块的结构体每次只写八位数据

{

unsignedcharx_head;//头x坐标0~63

unsignedchary_head;//头y坐标0~63(为偶数)

unsignedchardirec_head;//头前进的方向

unsignedcharx_end;//尾x坐标0~63

unsignedchary_end;//尾y坐标0~63

unsignedchardirec_end;//尾前进的方向

}snake;

则数据值如下:

snake.x_head=1;snake.y_head=4;snake.direc_head=2;

Snake.x_end=2;snake.y_end=0;snake.direc_end=1;

三大重要函数,这三个函数与硬件打交道,为上层游戏编写提供了便利。

snake_data_add()点亮两个像素点

snake_data_dele()熄灭两个像素点

snake_read_data()读取像素点是否已经点亮

简单演示一下效果

行了,不多说了,上干货吧!

******************************************************************************************************************************************

Main.c

******************************************************************************************************************************************

#include

#include

#defineuintunsignedint

#defineucharunsignedchar

#include"12864_bing_xing.h"

#include"game.h"

#include"key.h"

 

voiddelay_nms(uintnms)

{

uinti,j;

for(i=0;i

for(j=0;j<1141;j++);

}

voidscan_deal(void)

{

//返回值:

0不可移动

//1可以移动

//2吃到苹果

switch(move_forward())

{

case0:

show_picture(game_over);//死亡,游戏结束

break;

case2:

//可以在此嵌入计分数据代码并减小times的值可以提高难度的功能

appel_add(suiji_data);//产生苹果,游戏继续

break;

default:

break;

}

}

voidmain(void)

{

uchari=0,b=8;

lcd_init();

lcd_delay_nms(10);

display();//画空图

snake_init();

snake_data_add(0,0);

snake_data_dele(0,0);

while

(1)

{

snake_move_scan(100);//多次扫描按键,

scan_deal();

}

}

******************************************************************************************************************************************

12864_bing_xing.h

******************************************************************************************************************************************

/******************************************************************************/

/*Name:

LCD12864(St7920/St7921)*/

/**/

/*Designedby:

Date:

2016/5/9*/

/*开发环境:

ICCAVR*/

/*QQ:

1460467003飘*/

/******************************************************************************/

#defineset_bit(register1,bits)(register1|=(1<<(bits)))

#defineclr_bit(register1,bits)(register1&=~(1<<(bits)))

#defineget_bit(register1,bits)(register1&=(1<<(bits)))

#definelcd_clr0x01

#definelcd_rs_hset_bit(PORTA,0)

#definelcd_rs_lclr_bit(PORTA,0)

#definelcd_rw_hset_bit(PORTA,1)

#definelcd_rw_lclr_bit(PORTA,1)

#definelcd_en_hset_bit(PORTA,2)

#definelcd_en_lclr_bit(PORTA,2)

#definelcd_data_iPINB

#definelcd_data_oPORTB

#include"picture_library.h"

voidlcd_delay_nms(uintnms)

{

uinti,j;

for(i=0;i

for(j=0;j<113;j++);//更改数值,增加稳定性

}

//读状态

voidlcd_check_busy(void)

{

DDRB=0X00;

lcd_data_o=0xFF;

//lcd_delay_nms

(1);

lcd_rs_l;

lcd_rw_h;

lcd_en_l;

lcd_en_h;

while(lcd_data_i&0X80);//检测忙信号

lcd_en_l;

DDRB=0XFF;

lcd_data_o=0xff;

//lcd_delay_nms

(1);

}

//1表示数据0表示命令

voidlcd_write_data(ucharon_data,uchardata)//发送指令或数据

{

lcd_check_busy();

if(on_data)

lcd_rs_h;

else

lcd_rs_l;

lcd_rw_l;

lcd_data_o=data;

lcd_delay_nms

(2);//等待当前工作完成

lcd_en_h;

lcd_delay_nms

(2);//等待当前工作完成

lcd_en_l;

}

//读数据

ucharlcd_read_data(void)

{

uchardata;

lcd_check_busy();

lcd_data_o=0xFF;

DDRB=0X00;

lcd_rs_h;

lcd_rw_h;

lcd_en_h;

lcd_delay_nms

(1);

data=lcd_data_i;

lcd_en_l;

return(data);

}

/*

以屏幕的左上角为原点,X左——右增大0——7两个字节为单位

Y上——下增大0——63位为单位

*/

voidlcd_set_xy(ucharx,uchary)

{

if(y>31)

{

lcd_write_data(0,0x80+y-32);//y轴

lcd_write_data(0,0x88+x);//x轴

}

else

{

lcd_write_data(0,0x80+y);//y轴

lcd_write_data(0,0x80+x);//x轴

}

}

voidlcd_init(void)//LCM初始化

{

DDRA|=0X7;PORTA|=0X07;

DDRB=0XFF;PORTB=0XFF;

set_bit(DDRC,0);set_bit(PORTC,0);//并行模式

lcd_write_data(0,0x30);//八位数据端口,进入基本指令集

lcd_write_data(0,0x01);//显示清屏

lcd_write_data(0,0x06);//光标自增,画面不动

lcd_write_data(0,0x0c);//整体显示,游标关,不反白

}

//写内存,为空

voiddisplay(void)//图形方式12864显示字模逐行式顺向

{

unsignedchari,j;

lcd_write_data(0,0x34);//图形方式

for(i=0;i<32;i++)

{

lcd_write_data(0,0x80+i);//Y

lcd_write_data(0,0x80);//X

for(j=0;j<16;j++)

{

lcd_write_data(1,0x00);

}

}

for(i=0;i<32;i++)

{

lcd_write_data(0,0x80+i);//Y

lcd_write_data(0,0x88);//X

for(j=0;j<16;j++)

{

lcd_write_data(1,0x00);

}

}

//lcd_write_data(0,0x80+22);

//lcd_write_data(0,0x88);

//for(j=0;j<16;j++)

//lcd_write_data(1,0xff);

lcd_write_data(0,0x36);

}

//显示图片,逐行式顺向

voidshow_picture(constunsignedchartu[])

{

unsignedchari,j;uintk=0;

lcd_write_data(0,0x34);//图形方式

for(i=0;i<32;i++)

{

lcd_write_data(0,0x80+i);//Y

lcd_write_data(0,0x80);//X

for(j=0;j<16;j++)

{

lcd_write_data(1,tu[k]);

k++;

}

}

for(i=0;i<32;i++)

{

lcd_write_data(0,0x80+i);//Y

lcd_write_data(0,0x88);//X

for(j=0;j<16;j++)

{

lcd_write_data(1,tu[k]);

k++;

}

}

lcd_write_data(0,0x36);

}

 

/*

voidLCDClear(void)//清屏

{

lcd_write_data(0,0x01);//显示清屏

}

voidLCDFlash(void)//闪烁效果

{

lcd_write_data(0,0x08);//显示清屏

lcd_delay_nms(4);

lcd_write_data(0,0x0c);//显示开及光标设置

lcd_delay_nms(4);

lcd_write_data(0,0x08);//显示清屏

lcd_delay_nms(4);

lcd_write_data(0,0x0c);//显示开及光标设置

lcd_delay_nms(4);

lcd_write_data(0,0x08);//显示清屏

lcd_delay_nms(4);

}

 

voidlcd_draw_jpg(void)

{

lcd_write_data(0,0x34);//绘图模式设置

lcd_set_xy(0,34);//设置坐标xy

lcd_write_data(1,0xff);//高八位

lcd_write_data(1,0xf1);//低八位

lcd_write_data(0,0x36);

}

*/

/*

并行通信开始信号代码发送数据:

0XFA

发送命令:

0XF8

接收数据:

0XFE

指令代码进入基本指令集0x30

清屏0x01

光标右移0x06

显示打开游标关游标位置关0x0c

进入扩充指令集设定状态、关闭显示0X34

开启绘图显示0x36

配置lcd必须先进入相关的指令集

设置地址先垂直后水平读写都会改变AC的值

显示图片之前必须对对所有的GDRAM赋值,否则乱码

据网友说,读取数据只支持并行通信,试了多次,感觉网友说的没有错

读取数据之前必须空读一次

*/

******************************************************************************************************************************************

game.h

******************************************************************************************************************************************

/******************************************************************************/

//Name:

游戏主函数*/*/

/*Designedby:

Date:

2016/5/25*/

/*开发环境:

ICCAVR*/

/*QQ:

1460467003飘*/

/******************************************************************************/

//坐标点设定方块的左上方点

//方向参考屏幕正放

structsnake_type//定义一个砖块的结构体每次只写八位数据

{

unsignedcharx_head;//头x坐标0~63

unsignedchary_head;//头y坐标0~63

unsignedchardirec_head;//头前进的方向

unsignedcharx_end;//尾x坐标0~63

unsignedchary_end;//尾y坐标0~63

unsignedchardirec_end;//尾前进的方向

}snake;

//随机数据的缓存指针

unsignedintsuiji_num=0;

#defineDOT_NUMBER_MAX40

//x0~63两位为单位y(偶数)0~63

//点亮坐标对应的像素点

voidsnake_data_add(ucharx,uchary)

{

uchardata_h,data_l;

switch(x&0x07)

{

case0:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h|0xc0);

//lcd_write_data(1,data_l|(data<<6));

break;

}

case1:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h|0x30);

//lcd_write_data(1,data_l|(data<<6));

break;

}

case2:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h|0x0c);

//lcd_write_data(1,data_l|(data<<6));

break;

}

case3:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h|0x03);

//lcd_write_data(1,data_l|(data<<6));

break;

}

case4:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0xc0);

break;

}

case5:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x30);

break;

}

case6:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x0c);

break;

}

case7:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x03);

break;

}

default:

break;

}

}

//x0~63两位为单位y(偶数)0~63

//熄灭坐标对应的像素点

voidsnake_data_dele(ucharx,uchary)

{

uchardata_h,data_l;

switch(x&0x07)

{

case0:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h&0x3f);

//lcd_write_data(1,data_l&(~(data<<6)));

break;

}

case1:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h&0xcf);

//lcd_write_data(1,data_l&(~(data<<6)));

break;

}

case2:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h&0xf3);

//lcd_write_data(1,data_l&(~(data<<6)));

break;

}

case3:

{

lcd_set_xy(x>>3,y);

lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data();

lcd_set_xy(x>>3,y);

lcd_write_data(1,data_h&0xfc);

//lcd_write_data(1,data_l&(~(data<<6)));

break;

}

case4:

{

lcd_set_xy(x>

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1