SNACK STC89C52 (已修复BUG版)
思路:
通过结构体设置x,y坐标,对点阵进行定点处理。只需对每个点进行扫描,利用人眼的延时性即可显示snack;
还有比较关键的就是模仿,只控制第一个点,随后几个分别模仿前一个点的运动轨迹即可实现连贯跟随。:)
自定义游戏规则:
不能穿墙(考虑到界面比较小,颜色比较单一,穿墙后容易分辨不了蛇的头和尾)。 撞到自己后重新开局,头只能向三个方向移动。以snake的长度定胜负。
撞到自己重新开局
花了一个下午搞的,有不足之处请直接评论 : )
/*************************
April 10 stc89c52 snake
made by Rays
*************************/
#include<reg51.h>
#include<stdlib.h>
#include<intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
sbit k1=P3^1; //up
sbit k2=P3^0; //down
sbit k3=P3^2; //left
sbit k4=P3^3; //right
uchar xz[]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff};
uchar yz[]={0x00,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff};
uchar len,flag,x0,y0,r,p,f;
void send(uchar dat);
void keyboard();
struct point
{
uchar x,y;
}s[40];
void int0()
{
len=3;
s[0].x=3,s[0].y=1;
s[1].x=2,s[1].y=1;
s[2].x=1,s[2].y=1;
flag=0;//模仿标志
p=1; //随机数产生标志
f=1;
r=0; //结果标志
}
void delay(uint c) //c=1,1ms
{
uint a,b,t;
for(t=0;t<c;t++)
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
void show(uchar x,uchar y)
{
send(xz[x]);
P0=yz[y];
}
void main()
{
uchar i,tmpx,tmpy,x1,y1;
int0();
while(1){
tmpx=s[0].x;
tmpy=s[0].y;
keyboard();
if(s[0].x==s[1].x&&s[0].y==s[1].y)
{
s[0].x=tmpx;
s[0].y=tmpy;
flag=0;
}
if(s[0].x==x0 && s[0].y==y0)
{
if(len<40) len++;
if(s[len-2].x==s[len-3].x)
{
if(s[len-2].x<s[0].x) s[len-1].x=s[len-2].x-1;
else s[len-1].x=s[len-2].x+1;
s[len-1].y=s[len-2].y;
}
if(s[len-2].y==s[len-3].y)
{
if(s[len-2].y<s[0].y) s[len-1].y=s[len-2].y-1;
else s[len-1].y=s[len-2].y+1;
s[len-1].x=s[len-2].y;
}
p=1;
}
x1=x0,y1=y0;
while(p){ //产生随机数
f=1;
x0=rand()%9;
y0=rand()%9;
for(i=0;i<len;i++)
if(s[i].x==x0 && s[i].y==y0) f=0;
if(f &&(x0>=1&&x0<=8)&&(y0>=1&&y0<=8))
if(x1!=x0||y1!=y0) p=0;
}
if(flag){
for(i=len-1;i>=2;i--) //模仿
{
s[i].x=s[i-1].x;
s[i].y=s[i-1].y;
}
s[1].x=tmpx;
s[1].y=tmpy;
flag=0;
}
s[len].x=x0,s[len].y=y0;
for(i=0;i<len;i++) show(s[i].y,s[i].x);
show(0,9); //除阴影点
show(s[len].y,s[len].x);
show(0,9);
r=0; //初始化结果
for(i=1;i<len;i++) //判断是否撞到自己
if(s[0].x==s[i].x &&s[0].y==s[i].y) r=1;
if(r)
{
show(9,0);
delay(500);
int0(); //撞到自己重新开局
}
}
}
void send(uchar dat)
{
uchar a;
SRCLK=0;
RCLK=0;
for(a=0;a<8;a++)
{
SER=dat>>7;
dat<<=1;
SRCLK=1;
_nop_();
_nop_();
SRCLK=0;
}
RCLK=1;
_nop_();
_nop_();
RCLK=0;
}
void keyboard()
{
if(k1==0) //up
{
delay(2);
if(k1==0)
{
if(s[0].y<8) {s[0].y++;
//else s[0].y=1;
flag=1;}
}
while(!k1);
}
if(k2==0) //down
{
delay(2);
if(k2==0)
{
if(s[0].y>1) {s[0].y--;
//else s[0].y=8;
flag=1;}
}
while(!k2);
}
if(k3==0) //left
{
delay(2);
if(k3==0)
{
if(s[0].x>1) {s[0].x--;
//else s[0].x=8;
flag=1;}
}
while(!k3);
}
if(k4==0) //right
{
delay(2);
if(k4==0)
{
if(s[0].x<8) {s[0].x++;
//else s[0].x=1;
flag=1;}
}
while(!k4);
}
}
这篇博客介绍了使用STC89C52单片机编写贪吃蛇游戏的过程,重点在于通过结构体管理坐标,并利用人眼延时性实现点阵显示。游戏规则包括不能穿墙以及撞到自己后需重新开始,蛇头只能向三个方向移动。作者邀请读者指出可能存在的不足。
3332

被折叠的 条评论
为什么被折叠?



