DSP上的贪吃蛇游戏

程序员是值得尊敬的,程序员的双手是魔术师的双手,他们把枯燥无味的代码变成了丰富多彩的软件……

最近蛮无聊的,在实验室发现一个12864,哦哈哈,正好可以拿来写点小游戏玩,于是便萌生了用评估板写一些小游戏的想法,让我想想,神马贪吃蛇、拼图、坦克大战……,好多的说,昨天没事,就写了一个,虽然可能还有许多小问题,但是可以确定的是可以玩,…^-^

首先来一张硬件连接的照片,拿手机照的,效果不大好,话说我有一个无线模块的,没有用上,在实验室呢

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

下面再来一张游戏开始的画面

最后是游戏中的画面

下面是程序源码,因为时间短,也没有太多关心,所以程序并没有进行过优化,还有很大的改进余地,包括算法也不是精心设计的,程序健壮性可能还有些弱,至于12864的程序,可以参看相关的文档,都有相关的实例,那个很无聊。

12864使用的是串口,所以有些慢 

 

/*****************************************************************************
 * NewProject.c
 *****************************************************************************/
#include 
#include 
#include 
#include 
#include 
#include <12864.c>
struct	SnakePoint
{
	char	Number;
	char	SnakeX;
	char	SnakeY;
	char	SnakeD;
};
char	windows[64][128];
void	initwindows(int *pRand);
int		testkey(void);
int		Forword(struct SnakePoint *pstart,int *pspeed,int rands);
void	DrawWindows(int x);
void	DrawInit12864(void);
void	DrawTo12864(int flag,int x,int y);

char	x,y,direction[2],x0,y0;
int		dx,dy;
struct	SnakePoint *pStart,*pEnd;

void main( void )
{
	struct SnakePoint	snake[100];
	char flag;
	int 	i,j,speed,rands;
	
	rands=32657;
	direction[0]=direction[1]=2;
	speed=100000;
	*pPORTFIO_DIR=0x001f;
	ssync();
	*pPORTFIO=0x0001;	//拉高片选
	Init12864();

	for(i=0;i<300;i++)
	{
		snake[i].Number=i;
	}	//初始化
	snake[0].SnakeD=2;		//默认初始水平前进
	
	pStart=&snake[0];
	pEnd=&snake[0];			//为直线
	
	x=25;	//初始化位置
	y=25;
	x0=25;
	y0=35;
	
	
	*pPORTGIO_INEN=0x0F00;

	initwindows(&rands);	//按任意键继续界面
	do	//½øÈëÖ÷½çÃæ
	{
		flag=testkey();
		if(flag!=0)	//Óа´¼ü
		{
			rands=rands*rands+782;
			rands=rands>>2;	//取随机
			
			if( ( (direction[0]+flag)!=5) && (direction[0]!=flag) )	//只能向左或者右
			{
				direction[0]=flag;	//更新方向
				pStart->SnakeX=x;	
				pStart->SnakeY=y;
				pStart->SnakeD=flag;	//记录拐点坐标和方向
				
				pStart++;
				if(pStart->Number==299)
				{
					pStart=&snake[0];
				}
			}
		}			
		for(i=0;i>1;
		}
		else
		{
			dx=*pRand&0x0ff0ffff;
			dx=(dx%64);
			dy=*pRand&0x000fffff;
			dy=(dy%128);
			DrawWindows(1);	//画游戏画面
			break;
		}
	}
}
int	testkey(void)	//检测按键
{
	int iotest=*pPORTGIO & 0x0f00;
	if(iotest==0x0e00)
	{
		return 1;
	}
	if(iotest==0x0d00)
	{
		return 4;
	}
	if(iotest==0x0b00)
	{
		return 2;
	}
	if(iotest==0x0700)
	{
		return 3;
	}
	return 0;
}
int	Forword(struct SnakePoint *pstart,int *pspeed,int rands)	//前进一格
{
	switch(direction[0])
	{
		case 1:
			x=x-1;
			break;
		case 2:
			y=y-1;
			break;
		case 3:
			y=y+1;
			break;
		case 4:
			x=x+1;
			break;
	}		//更新头部坐标
	
	if(x<0 || x >63 || y<0 || y>127 ||(windows[x][y]!=0 && (x!=dx || y!=dy) ) )	//撞墙
	{
		DrawWindows(2);
		while(testkey()!=0)
		{
		}
		return 1;
	}

	windows[x][y]=0xff;
	DrawTo12864(1,x,y);
	/
	if(x!=dx || y!=dy)
	{		//没吃到
		if(pStart==pEnd)	
		{		//直线
			direction[1]=direction[0];
		}
		else
		{
			if(x0==pEnd->SnakeX && y0==pEnd->SnakeY)
			{		//到达拐点
				direction[1]=pEnd->SnakeD;	//更新尾部方向
				++pEnd;	//指向下一拐点
				if(pEnd->Number==299)
				{
					pEnd=pstart;
				}	//循环
			}
		}
		/
		windows[x0][y0]=0;	//清尾部
		DrawTo12864(0,x0,y0);
		switch(direction[1])
		{		//计算下一尾部坐标
			case 1:
				--x0;
				break;
			case 2:
				--y0;
				break;
			case 3:
				++y0;
				break;
			case 4:
				++x0;
				break;
		}
		///
	}
	else
	{	//吃到
		dx=rands&0x0ff0ffff;
		dx=(dx%64);
		dy=rands&0x000fffff;
		dy=(dy%128);
		windows[dx][dy]=0xff;	//设定新豆
		DrawTo12864(1,dx,dy);
		*pspeed=*pspeed-(*pspeed)/300;	//加速
	}
	return 0;
		
}
void	DrawWindows(int x)	//画出画面
{
	int i;
	char a[15]={"按任意键继续"};
	switch(x)
	{
		case 1:	//画不同界面
			for(i=25;i<35;i++)
			{
				windows[25][i]=0xff;
			}
			windows[dx][dy]=0xff;
			DrawInit12864();
			DrawTo12864(1,dx,dy);
			break;
		case 0:
			Lcdwrite(0x01,0xf8);
			Lcdwrite(0x91,0xf8);
			for(i=0;i<12;i++)
			{
				Lcdwrite(a[i],0xfa);
			}
			break;
		case 2:
			Lcdwrite(0x34,0xf8);
			break;
	}
		
}
void	DrawInit12864(void)	//画初始化界面
{
	Lcdwrite(0x01,0xf8);
	Lcdwrite(0x36,0xf8);
	Delay(50);	
	
	lcdclean();
	
	Lcdwrite(0x99,0xf8);
	Lcdwrite(0x81,0xf8);	//25行25列,长度10
	Lcdwrite(0x00,0xfa);
	Lcdwrite(0xff,0xfa);
	Lcdwrite(0xc0,0xfa);
	
}
void	DrawTo12864(int flag,int x,int y)	//将内存数据写入12864
{
	int wx=x%32+0x80;	//计算得到地址
	int wy=y/16,i;
	char tmp0,tmp1;
	if(x>31)
	{	//ÔÚÏ°ëÆÁ
		wy=0x88+wy;
	}
	else
	{
		wy=0x80+wy;
	}	//计算的到地址
	Lcdwrite(wx,0xf8);
	Lcdwrite(wy,0xf8);
	//写入地址
	tmp0=(y/16)*16;	//得到16的整数倍开始地址
	
	tmp1=0;
	for(i=0;i<8;i++)
	{
		tmp1=tmp1<<1;
		if(windows[x][tmp0]==0)
		{
			tmp1=tmp1&0xfe;
		}
		else
		{
			tmp1=tmp1|0x01;
		}
		tmp0++;
	}
	Lcdwrite(tmp1,0xfa);
	
	tmp1=0;
	for(i=0;i<8;i++)
	{
		tmp1=tmp1<<1;
		if(windows[x][tmp0]==0)
		{
			tmp1=tmp1&0xfe;
		}
		else
		{
			tmp1=tmp1|0x01;
		}
		tmp0++;
	}
	Lcdwrite(tmp1,0xfa);
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值