完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一直想把贪吃蛇游戏用点阵的方式显示出来,今天终于实现了,下面又我来详细介绍我是如何实现的吧哈哈哈
游戏的模块(不要当伸手党,多想问题) 游戏流程1.初始化2.进行游戏开始 游戏机制1.创造界面2.静态界面3.动态界面4.用户的交互设置5.游戏开始6.吃到食物7.死法 按键设置 进行中断定时 延时设置 点阵显示 #in#ifndef __CONFIG_H #define __CONFIG_H #include #include #include #include "delay.h" #include "key.h" #include "8x8lattice.h" #include "snake.h" #include "interrupt.h" typedef unsigned char uchar; typedef unsigned int uint; #define FOSC 12000000L #endif clude "config.h"//包含所有定义的头文件,可以调用所有的函数 void main() { static struct Food { unsigned char x; unsigned char y; 定义蛇的坐标 }food; struct Snake { char x[SNAKE_Max_Long]; char y[SNAKE_Max_Long];//用点阵表示蛇长 unsigned char Long; // 长度 unsigned char Life; // 生命 unsigned char Level; // 游戏等级 unsigned char Dir; // 方向 }snake; enum Dir{up, down, left, right}; //枚举按键方向 unsigned char DispRAM[8]={0}; // 蛇身子的缓存 unsigned char tCount;//移动次数 unsigned char keyValue=right;//初始方向 unsigned char speedLevel=25;//移动速度 extern uchar keyVal; //key函数中传来的方向 static void createFood() { unsigned char i; food.x = rand()%WIDTH; food.y = rand()%LENGTH;//创造食物 for(i=0; i if(food.x==snake.x && food.y==snake.y) createFood(); //食物与蛇重合,重画 } } static void initSnake() { unsigned char i; for(i=0; i snake.x=-1; snake.y=-1;//清空所有蛇的数据 } snake.Long=2; snake.Life=1; snake.Dir=right; snake.x[1]=0; snake.y[1]=2; snake.x[0]=1; snake.y[0]=2; createFood();//定义所有初始化的数据 } static void drawSnake() { unsigned char i=0; for(i=0; i<8; i++) DispRAM=0;清空缓存 for(i=0; i scanDisplay(DispRAM); drawPoint(food.x, food.y);//打印游戏画面 } static void runSnake() { unsigned char i; for(i=snake.Long; i>0; i--) { snake.y=snake.y[i-1]; snake.x=snake.x[i-1];//i大的地方为蛇头,使蛇移动 } switch(snake.Dir) { case up: snake.y[0]-=1; break; case down: snake.y[0]+=1; break; case left: snake.x[0]-=1; break; case right: snake.x[0]+=1; break; default: break;//将方向量转化为大致的坐标 } if(snake.x[0]==food.x && snake.y[0]==food.y) { snake.Long++; createFood();//吃到食物 } } static void changeDir(unsigned char key) { switch(key) { case up: if(snake.Dir != down) snake.Dir=up; break; case down: if(snake.Dir != up) snake.Dir=down; break; case left: if(snake.Dir != right) snake.Dir=left; break; case right: if(snake.Dir != left) snake.Dir=right; break;//不允许出现方向的突变 default: break; } } void startSnake() { uchar i=0; initSnake(); while(snake.Life) { changeDir(keyValue);//改变方向 if(tCount >= speedLevel)//停顿一段时间再走 { tCount=0; runSnake(); } if((snake.x[0]>(WIDTH-1)) || (snake.x[0]<0) || (snake.y[0]>(LENGTH-1)) || (snake.y[0]<0)) { snake.Life=0; snake.Level=1; speedLevel=25; keyVal=right; //设超出边界死 } for(i=4; i<=snake.Long; i++) { if(snake.x[i-1]==snake.x[0] && snake.y[i-1]==snake.y[0]) { snake.Life=0; snake.Level=1; speedLevel=25; keyVal=right; //自杀蛇死 } } if(snake.Long >= SNAKE_Max_Long)//蛇长到一定的程度从新来 { delayMs(500); initSnake();//新的等级 speedLevel-=5;//超过最大长度,加快停留时间 keyVal=right; if(++snake.Level > 5) { snake.Level=1; speedLevel=25; //到五级重启 } tCount=0; } drawSnake(); } } 延时模块自己写 按键函数 #include "config.h" extern enum Dir{up, down, left, right}; ***it keyUp = P3^0; ***it keyDown = P3^1; ***it keyLeft = P3^2; ***it keyRight = P3^3; uchar keyVal=right; uchar scanKey(void) { if(!keyUp) keyVal=up; if(!keyDown) keyVal=down; if(!keyLeft) keyVal=left; if(!keyRight) keyVal=right; return keyVal; }//将方向返回游戏中 中断处理:给蛇定时不能一直跑 #include "config.h" extern unsigned char tCount; //移动的次数 extern unsigned char keyValue; //方向 void initTimer0() { TMOD |= 0x01; TL0 = TIMER; TH0 = TIMER>>8; TR0 = 1; ET0 = 1; EA = 1; } void timer0Handle() interrupt 1 { TL0 = TIMER; TH0 = TIMER>>8; keyValue=scanKey(); tCount++; } 外部的显示//595 和p0实现 #ifndef __8X8LATTICE_H #define __8X8LATTICE_H #include #include ***it DS = P3^4; ***it SH_CP = P3^6; ***it ST_CP = P3^5 void hc595Write(unsigned char writeVal); void drawPoint(unsigned char x, unsigned char y); void scanDisplay(unsigned char *pbuff);// #endif 显示函数 #include "8x8lattice.h" extern unsigned char ledwei[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//低电平有效 void hc595Write(unsigned char writeVal) { unsigned char i; ST_CP=0; for(i=0; i<8; i++) { SH_CP=0; DS=writeVal>>7; writeVal<<=1;//输入数据 SH_CP=1; } ST_CP=1;//保持数据 } void drawPoint(unsigned char x, unsigned char y) { hc595Write(0x00);//消隐 hc595Write(1< P0=ledwei[y];//画点 } void scanDisplay(unsigned char *pbuff) { unsigned char i=0; hc595Write(0x00); for(i=0; i<8; i++) { hc595Write(pbuff);//画蛇用点集 hc595Write(0x00); P0=ledwei; hc595Write(0x00); } } 仿真的话p0口加上拉电阻 595没啥好说的中间DS是8位的串行数据线。 |
|
相关推荐
|
|
644 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1819 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1262 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
1136 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1357 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12028 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 12:29 , Processed in 0.539818 second(s), Total 42, Slave 35 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号