⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lostway.c

📁 单片机控制实现几个小游戏:贪吃蛇、俄罗斯方块、推箱子
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef __lostway_c_20080124_
#define __lostway_c_20080124_
#include "lostway.h"

void lostway(void)
{
	int8_t i,j,k,l,setoff_x,setoff_y;
	game_model=MODEL_OVER;
	LED_UEN_012;//显示器2初始化
	total_NO=0;	//初始化分数
	display_LED_total_NO();
	INTE=0;		//生成迷宫时,避免键盘打扰关闭中断,屏蔽这一句,可做为调试,用上下左右查地图的生成情况
	for(i=0;i<MAP_X;i++)		//初始化地图
		for(j=0;j<MAP_Y;j++)
			full_map[i][j]=0xff;//地图全为1
	for(i=0;i<MAP_X-1;i++)
		for(j=1;j<MAP_Y-1;j++,j++)
			full_map[i][j]=0x55;//地图隔行为01010101
	for(j=1;j<MAP_Y-1;j++,j++)full_map[MAP_X-1][j]=0xd5;//右边缘为两排11
	make_map();	//生成地图
	find_end();	//寻找合适的终点
	cur_map_x=1;//设置起点x
	cur_map_y=1;//设置起点y
	//在点阵上显示,而且显示为8x8的范围
	for(i=0;i<16;i++)displaybuffer_16mux16[i]=0;	//清空显示缓冲区
	setoff_x=screen_setoff_uint(cur_map_x);	//计算当前点在屏幕上的偏移
	setoff_y=screen_setoff_y_uint(cur_map_y);	//计算当前点在屏幕上的偏移
	//KEIL编译器在处理 for(i=y_begin,j=0;i<cur_map_y+setoff_y+5;i++,j++)  这个语句出现问题
	//调试时cur_map_y+setoff_y+5的值时正常 但是当i超过cur_map_y+setoff_y+5时无法退出
	//初步原因可能是因为子函数过多,导致编译器使用大量临时空间,导致空间错乱,处理方法:减少子函数和临时指针的数量,贪食蛇蛇身用指针指向暂时不用的地图空间
	for(i=(cur_map_y+setoff_y-3),j=0;i<(cur_map_y+setoff_y+5);i++,j++)
		for(k=(cur_map_x+setoff_x-3),l=0;k<(cur_map_x+setoff_x+5);k++,l++)
			if(get_map_point(k,i))displaybuffer_16mux16[j]|=mux_int[l];	//显示信息送入显缓区
	for(i=8;i<16;i++)displaybuffer_16mux16[i]&=0x0000;	//点阵上半屏不亮
	for(i=0;i<8;i++)displaybuffer_16mux16[i]&=0x00ff;	//点阵右下屏不亮
	for(i=0;i<16;i++)flash_displaybuffer[i]=0;	//清空闪烁缓冲区
	flash_displaybuffer[3-setoff_y]=mux_int[3-setoff_x];	//送闪烁光标位置,游戏中为人物
	flash_status=FLASH_NO_TIME;		//一直显示光标人物
	//在点阵上显示,而且显示为8x8的范围
	INTE=1;		//地图已生成开启键盘
	while(1)
		{
			if(cur_map_x==end_x&&cur_map_y==end_y){game_model=MODEL_WIN;break;}//如果到达终点则跳出
			if(total_NO==999){game_model=MODEL_OVER;break;}//如果步数大于999应该失败
		}
//退出游戏就胜利,未加入失败提示
//	make_sound();
//	main_display();
	display_cmd(DISPLAY_CMD_FLASH_CLOSE,NULL);//关闭光标
	Current_game=DEFAULTS;	//等待游戏选择
	stop_game=GANE_BEGIN;	//游戏不停止
	if(game_model==MODEL_OVER)
			display_cmd(DISPLAY_CMD_OVER,NULL);		//显示游戏失败
	else
			display_cmd(DISPLAY_CMD_WIN,NULL);		//显示游戏胜利
	LED_UEN_0123;//LED显示所有位
	keywords=0;
}


void lostway_key(void)
{
uint8_t i;
	switch(keywords)
		{
		case UP://MAP_Y-3=29
			if((!get_map_point_int(cur_map_x,cur_map_y+1))&&cur_map_y!=29)//如果可走
				{
					cur_map_y+=1;
					total_NO++;	//加分,还没显示
					lost_display_pr();
				}
			break;
		case DOWN :
			if((!get_map_point_int(cur_map_x,cur_map_y-1))&&cur_map_y!=1)//如果可走
				{
					cur_map_y-=1;
					total_NO++;
					lost_display_pr();
				}
			break;
		case LEFT:
			if((!get_map_point_int(cur_map_x-1,cur_map_y))&&cur_map_x!=1)
				{
					cur_map_x-=1;
					total_NO++;
					lost_display_pr();
				}
			break;
		case RIGHT:
			if((!get_map_point_int(cur_map_x+1,cur_map_y))&&cur_map_x!=29)//MAP_X_X-3=29
				{
					cur_map_x+=1;
					total_NO++;
					lost_display_pr();
				}
			break;
		case OK:
			//for(i=16;i<32;i++)displaybuffer_16mux16[i-16]=full_map[2][i]+256*full_map[3][i];
//			display_16mux16();
			break;
		default:
			break;
	}
	display_total_NO();
	keywords=rand();
//	display_LED_total_NO(total_NO);//显示分数
}

//偏移量计算,使得当前点,正常地在屏幕上移动
int8_t screen_setoff_uint(int8_t point_data)
{
if(point_data-3<0)return 3-point_data;	//当前点为屏幕左边,则偏移量为正
if(point_data+4>MAP_X_X-1)return MAP_X_X-point_data-5;//当前点为右屏幕,则偏移量为正
return 0;//若不在边缘,则不偏移当前点显在中间
}

int8_t screen_setoff_y_uint(int8_t point_data)
{
if(point_data-3<0)return 3-point_data;
if(point_data+4>MAP_Y-1)return MAP_Y-point_data-5;
return 0;
}

//偏移量计算,使得当前点,正常地在屏幕上移动
int8_t screen_setoff(int8_t point_data)
{
/*
PICC编译器和keilC51编译器在对 有无符号数据类型转化的不同之处
point_data 为无符号整形
C51对point_data-3处理最后的结果是
若point_data=1  point_data-3=256-(1-3)因为无符号整形的0-1=254
PICC对point_data-3处理最后的结果是
若point_data=1  point_data-3=0或者-2 编译器将其转化为有符号的数据类型
C51  if(point_data-3>MAP_X_X)return 3-point_data;
PICC  if(point_data-3<MAP_X_X)return 3-point_data;
上面两句代码在不同编译器下有一样的结果
*/
if(point_data-3<0)return 3-point_data;	//当前点为屏幕左边,则偏移量为正
if(point_data+4>MAP_X_X-1)return MAP_X_X-point_data-5;//当前点为右屏幕,则偏移量为正
return 0;//若不在边缘,则不偏移当前点显在中间
}

int8_t screen_setoff_y(int8_t point_data)
{
if(point_data-3<0)return 3-point_data;
if(point_data+4>MAP_Y-1)return MAP_Y-point_data-5;
return 0;
}

void lost_display_pr()
{
	int8_t i,j,k,l,setoff_x,setoff_y;
	for(i=0;i<16;i++)displaybuffer_16mux16[i]=0;	//清空显示缓冲区
	setoff_x=screen_setoff(cur_map_x);	//计算当前点在屏幕上的偏移
	setoff_y=screen_setoff_y(cur_map_y);	//计算当前点在屏幕上的偏移
	//KEIL编译器在处理 for(i=y_begin,j=0;i<cur_map_y+setoff_y+5;i++,j++)  这个语句出现问题
	//调试时cur_map_y+setoff_y+5的值时正常 但是当i超过cur_map_y+setoff_y+5时无法退出
	//初步原因可能是因为子函数过多,导致编译器使用大量临时空间,导致空间错乱,处理方法:减少子函数和临时指针的数量,贪食蛇蛇身用指针指向暂时不用的地图空间
	for(i=(cur_map_y+setoff_y-3),j=0;i<(cur_map_y+setoff_y+5);i++,j++)
		for(k=(cur_map_x+setoff_x-3),l=0;k<(cur_map_x+setoff_x+5);k++,l++)
			if(get_map_point_int(k,i))displaybuffer_16mux16[j]|=mux_int[l];	//显示信息送入显缓区
	for(i=8;i<16;i++)displaybuffer_16mux16[i]&=0x0000;	//点阵上半屏不亮
	for(i=0;i<8;i++)displaybuffer_16mux16[i]&=0x00ff;	//点阵右下屏不亮
	for(i=0;i<16;i++)flash_displaybuffer[i]=0;	
	flash_displaybuffer[3-setoff_y]=mux_int[3-setoff_x];	//送光标位置
}

void make_map(void)			//生成地图
{
     int8_t i,j,for_out;
     i=j=1;get_out=LOST;	//画地图初始化 从(1,1)点开始 不跳出循环
     while(1)
     {
        cur_map_x=i;cur_map_y=j;//送入一下点,准备生成新的树枝
        while(get_out)
            {
                make_way(cur_map_x,cur_map_y);//生成树枝
            }
        get_out=LOST;		//初始化下一次树枝生成
        for(i=1;i<MAP_X_X-2;i=i+2)
            {//寻找合适的点,可以树枝生成起始点的
                for(j=1;j<MAP_Y-2;j=j+2)
                    {	//如果到迷宫最后一个点,说明已经生成迷宫退出程序
						//如果该点仍有路可走,而且有路到该点,则跳出寻找,开始生成树枝
                        if((j>(MAP_Y-6))&&(i>(MAP_X_X-4)))return;
                        if((get_staute(i,j)!=15)&&!(get_map_point(i-1,j)&&get_map_point(i+1,j)&&get_map_point(i,j-1)&&get_map_point(i,j+1))){for_out=1;break;}
                     }
                if(for_out)break;	//跳出大循环
            }
        for_out=0;		//初始化大循环
     }
}

void make_way(uint8_t point_x,uint8_t point_y)
{
   	int8_t addx,addy;
	uint8_t staute;
	staute=get_staute(point_x,point_y);	//获得当前点四周的情况,是否有路可走
	addx=0;addy=0;						//偏移量初始为0
	switch(staute)						//屏蔽高四位
		{
			case NO_WAY:		//无路可走
				get_out=GETOUT;	//跳出树枝生成
				break;
			case UP_NO:			//仅有上方向可走,处理上
			   	addy=2;
				chang_map_point(point_x,point_y+1,WAY);
				break;
			case DOWN_NO:		//仅有下方向可走,处理下
				addy=-2;
				chang_map_point(point_x,point_y-1,WAY);
				break;
			case LEFT_NO:		//仅有左方向可走,处理左
			    addx=-2;
			    chang_map_point(point_x-1,point_y,WAY);
			    break;
			case RIGHT_NO:		//仅有右方向可走,处理右
			    addx=2;
			    chang_map_point(point_x+1,point_y,WAY);
			    break;
			case UP_DOWN:		//仅有上下方向可走,随机选择一个方向
				{if(rand()%2)
					{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -