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

📄 main.c

📁 一款用51单片机写的俄罗斯方块游戏完整项目下载
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
本项目专门为本站的51 PIC AVR 多功能学习开发板而写,仅供参考,请勿做商业用途,欢迎转载但要保留本站信息
                                  志博电子专注于8位单片机开发板设计和教学  
                                      让人耳目一心的经济又豪华型开发板
                                                性价比最高 
                                                 仅售378! 
欢迎访问我们的网站 www.elecmcu.com                                              
*/
#include"reg52.h"                    //包含常用的特殊寄存器所在的地址 库函数 KEIL 提供
#define uchar unsigned char          //将常用的数据类型定义
#define uint  unsigned int           //将常用的数据类型定义
#define bmp_2  1                     //定义黑白位图为1位
#define bmp_16  4                    //定义16位彩色位图为4位
#define bmp_256  8                   //定义256色彩色位图为一个字节(8位)
extern void draw_bmp(uint x,uint y,uchar *p,uchar type);//声明外部函数draw_bmp在别的文件已经定义过,在本文件中将要凋用到
extern void clean_rec(uint x,uint y,uint w,uint h,uchar color,uchar mode);//声明外部函数draw_bmp在别的文件已经定义过,在本文件中将要凋用到
extern code uchar qq_ico[5000];    //声明外部数组test_y_d在别的文件已经定义过,在本文件中将要凋用到    已经在FONT。H中定义过
extern  code   uchar  test_y_z[1000];//声明外部数组test_y_z在别的文件已经定义过,在本文件中将要凋用到  已经在FONT。H中定义过
extern  code   uchar  test_y_w[8000];//声明外部数组test_y_w在别的文件已经定义过,在本文件中将要凋用到  已经在FONT。H中定义过
extern code uchar  face[6000];
extern code unsigned char els[16][2];//已经在FONT。H中定义过。定义一个16*16黑白点阵所对应的实体象素数据  为各种方快的基本元素
xdata  char ext_els_temp[14][21]={0};//定义一个14*21 个字节也就是本游戏的行数和列数 是否有小方块的中间交换数据 为堆满一行 清全屏并将所有被清数据的行上所有数据下移一行
xdata uint score=0;                  //全局变量为目前的得分 分数 堆满一行自动加一
xdata uchar ext_color=0x88;          //方块颜色    
xdata  char ext_els[14][21]={0};     //定义一个14*21 个字节也就是本游戏的行数和列数 是否有小方块的实际数据 为堆满一行 清全屏并将所有被清数据的行上所有数据下移一行
/*
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},

};
*/
//以上数据为对应本游戏中所有方块的占用情况(调试游戏的各种情况中 测试时使用)虽然凌乱但为调试方便,不删除。
xdata unsigned char ext_all[8000]; //定义本局游戏所对应的所有坐标点的象素数据 在清全屏 重画全屏 中使用到
xdata unsigned char els_16_r[1000];//目前方块4*4个小方块所对应的象素 使用频繁每次移动均调用
xdata unsigned char els_16_t[1000];//目前方块4*4个小方块所对应的 处理中间象素 
xdata unsigned char els_type=1;    //当前方块4*4 小方块的类型序号
xdata unsigned char els_next=0;    //当前方块4*4 小方块的变形序号
xdata unsigned char cut_pix[4][4]; //当前方块在全局背景中所覆盖掉的背景4*4小方块数据情况
xdata  char abs_x=5;               //刚出来的4*4方块所在的X坐标
xdata  char abs_y=0;               //刚出来的4*4方块所在的Y坐标
xdata down_lab=0;                  //一个标志在一个函数中使用,本来可以做为一个形式参数,函数体可根据本数据做不同的处理。但函数已经下完。为不做大的改动,无奈,做了个全局变量。
xdata uchar gameover=0;            //游戏结束标志 结束后置1
extern  void delay10ms(void);      //一个软件延迟小函数的声名在IIC。C中有定义过
extern void display_char(uint x,uint y,uchar *charr,uchar back_color,uchar front_color);//自定义打印函数可以在电视上和PC上的指定行显示一个长字符串
extern void display_dig(uint num,uint x,uint y,uchar f_color,uchar b_color);//在屏幕上的任意象素位置显示一个 变量数据 0-65536

code uchar zifu[]="SCORE:";                         
code uchar qq[]="QQ:157773991";    //俺的QQ号所对应的字符串 在画屏幕时使用
code uchar http[]="elecmcu.com"; //本站网址所对应的字符串 在画屏幕时使用

code uchar mcu []="MCU:STC89C516"; //打印所使用的单片机型号
code uchar frq[]= "FRQ: 24 MHZ  "; //打印单片机的工作时钟
code uchar ram[]= "RAM: 32 KB   "; //打印单片机使用的外部RAM
code uchar rom[]= "ROM: 64 KB   "; //打印单片机使用的内部ROM
code uchar game_over_c[]="GAME OVER !";

code uchar els_p[7][4][4][4]=      //声明一个4维数组 用来存放俄罗斯方块的各种类型的各种变形所对应的小方块影射数据
{                                  //第一维为方块类型 第二维为方块的变形序列号 第三维行号 第4维列号
  {
    {
     0x00,0x00,0x00,0x00,          //口口口口
     0x00,0x00,0x00,0x00,          //口口口口
     0x00,0x00,0x00,0x00,          //口口口口
     0xff,0xff,0xff,0xff,          //志志志志
    },
    {
     0xff,0x00,0x00,0x00,         //博口口口
     0xff,0x00,0x00,0x00,         //博口口口
     0xff,0x00,0x00,0x00,         //博口口口
     0xff,0x00,0x00,0x00,         //博口口口
    },
    {
     0x00,0x00,0x00,0x00,         //口口口口
     0x00,0x00,0x00,0x00,         //口口口口
     0x00,0x00,0x00,0x00,         //口口口口
     0xff,0xff,0xff,0xff,         //电电电电
    },
    {
     0xff,0x00,0x00,0x00,        //子口口口
     0xff,0x00,0x00,0x00,        //子口口口
     0xff,0x00,0x00,0x00,        //子口口口
     0xff,0x00,0x00,0x00,        //子口口口
    },
  },
  ////////////////////////////////////////////////////000000000
  {
    {
     0x00,0x00,0x00,0x00,       //口口口口
     0x00,0x00,0x00,0x00,       //口口口口
     0x00,0xff,0x00,0x00,       //口志口口
     0xff,0xff,0xff,0x00,       //志志志口
    },
    {
     0x00,0x00,0x00,0x00,       //口口口口
     0xff,0x00,0x00,0x00,       //博口口口
     0xff,0xff,0x00,0x00,       //博博口口
     0xff,0x00,0x00,0x00,       //博口口口
    },
    {
     0x00,0x00,0x00,0x00,       //口口口口
     0x00,0x00,0x00,0x00,       //口口口口
     0xff,0xff,0xff,0x00,       //电电电口
     0x00,0xff,0x00,0x00,       //口电口口
    },
    {
     0x00,0x00,0x00,0x00,       //口口口口
     0x00,0xff,0x00,0x00,       //口子口口
     0xff,0xff,0x00,0x00,       //子子口口
     0x00,0xff,0x00,0x00,       //口子口口
    },
  },
  ////////////////////////////////////////////////111111111111
    {
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0xff,0x00,0x00,     //志志口口
     0xff,0xff,0x00,0x00,     //志志口口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0xff,0x00,0x00,     //博博口口
     0xff,0xff,0x00,0x00,     //博博口口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0xff,0x00,0x00,     //电电口口
     0xff,0xff,0x00,0x00,     //电电口口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0xff,0x00,0x00,     //子子口口
     0xff,0xff,0x00,0x00,     //子子口口
    },
  },
  /////////////////////////////////2222222222
    {
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0xff,0xff,0x00,     //口志志口
     0x00,0xff,0x00,0x00,     //口志口口
     0xff,0xff,0x00,0x00,     //志志口口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0x00,0x00,0x00,     //博口口口
     0xff,0xff,0xff,0x00,     //博博博口
     0x00,0x00,0xff,0x00,     //口口播口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0xff,0xff,0x00,0x00,     //电电口口
     0x00,0xff,0x00,0x00,     //口电口口
     0x00,0xff,0xff,0x00,     //口电电口
    },
    {
     0x00,0x00,0x00,0x00,     //口口口口
     0x00,0x00,0xff,0x00,     //口口子口
     0xff,0xff,0xff,0x00,     //子子子口
     0xff,0x00,0x00,0x00,     //子口口口
    },
  },
  //////////////////////////333333333
    {
    {
     0x00,0x00,0x00,0x00,    //口口口口
     0xff,0x00,0x00,0x00,    //志口口口
     0xff,0x00,0x00,0x00,    //志口口口
     0xff,0x00,0x00,0x00,    //志口口口
    },
    {
     0x00,0x00,0x00,0x00,    //口口口口
     0x00,0x00,0x00,0x00,    //口口口口
     0x00,0x00,0x00,0x00,    //口口口口
     0xff,0xff,0xff,0x00,    //博博博口
    },
    {
     0x00,0x00,0x00,0x00,    //口口口口
     0xff,0x00,0x00,0x00,    //电口口口
     0xff,0x00,0x00,0x00,    //电口口口
     0xff,0x00,0x00,0x00,    //电口口口
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口
     0x00,0x00,0x00,0x00,   //子口口口
     0x00,0x00,0x00,0x00,   //子口口口
     0xff,0xff,0xff,0x00,   //子口口口
    },
  },
  /////////////////////////444444444444
      {
    {
     0x00,0x00,0x00,0x00,   //口口口口 
     0xff,0x00,0x00,0x00,   //志口口口
     0xff,0x00,0x00,0x00,   //志口口口
     0xff,0xff,0x00,0x00,   //志志口口
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口 
     0x00,0x00,0x00,0x00,   //口口口口 
     0xff,0xff,0xff,0x00,   //博博博口 
     0xff,0x00,0x00,0x00,   //博口口口 
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口 
     0xff,0xff,0x00,0x00,   //电电口口 
     0x00,0xff,0x00,0x00,   //口电口口 
     0x00,0xff,0x00,0x00,   //口电口口 
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口 
     0x00,0x00,0x00,0x00,   //口口口口 
     0x00,0x00,0xff,0x00,   //口口子口 
     0xff,0xff,0xff,0x00,   //子子子口 
    },
  },
  /////////////////////////555555555555555
      {
    {
     0x00,0x00,0x00,0x00,   //口口口口
     0x00,0x00,0x00,0x00,   //口口口口
     0xff,0xff,0xff,0x00,   //志志志口
     0xff,0x00,0xff,0x00,   //志口志口
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口
     0xff,0xff,0x00,0x00,   //博博口口
     0x00,0xff,0x00,0x00,   //口博口口
     0xff,0xff,0x00,0x00,   //博博口口
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口
     0x00,0x00,0x00,0x00,   //口口口口
     0xff,0x00,0xff,0x00,   //电口电口
     0xff,0xff,0xff,0x00,   //电电电口
    },
    {
     0x00,0x00,0x00,0x00,   //口口口口
     0xff,0xff,0x00,0x00,   //子子口口
     0xff,0x00,0x00,0x00,   //子口口口
     0xff,0xff,0x00,0x00,   //子子口口
    },
  },
  /////////////////////////6666666
 };
 /********************************************************************

函 数 名:un_pix()
功 能:   将当前方块和背景方块结合成一个4*4方块阵列
说 明:
调 用:     down() right() left()
入口参数:无
返 回 值:无
设 计:志博51 AVR PIC 开发板  日 期:2007年11月13日
变 更 日 期:
变 更 备 注:
***********************************************************************/
void un_pix(void)          
{
  uchar a=0;               
  uchar b=0;
  for(a=0;a<4;a++)
   for(b=0;b<4;b++)
    if((els_p[els_type][els_next][a][b]!=0)&&(cut_pix[a][b]==0))
	 cut_pix[a][b]=0xff;          //将背景方块加到当前方块中,和背景溶为一体
}
 /********************************************************************

函 数 名:cut_p()
功 能:     取得当前方块覆盖背景方块情况
说 明:
调 用:     down() right() left()
入口参数: 当前绝对坐标  X Y
返 回 值: 无
设 计:    志博51 AVR PIC 开发板  日 期:2007年11月13日
变 更 日 期:
变 更 备 注:
***********************************************************************/
void cut_p(char x,char y)  
{
uchar a;
uchar b;
uchar c;
for(a=0;a<4;a++)
 for(b=0;b<4;b++)
 {
  c=ext_els[x+a][y+b];
  if((x+a)>13)
  c=0x00;
  cut_pix[b][a]=c;
 }
}
 /********************************************************************

函 数 名:make_els_temp()
功 能:   将方块的占用映射形式(4*4)变为(64*64)实际象素BMP形式
说 明:
调 用:     change()
入口参数: 
返 回 值: 无
设 计:    志博51 AVR PIC 开发板  日 期:2007年11月13日
变 更 日 期:
变 更 备 注:
***********************************************************************/
void make_els_temp(void)//
{
  uchar i=0;
  uchar j=0;
  uchar temp1=0;
  uchar temp2=0;
  uchar temp3=0;
  uchar k=0;
  uchar *p;
  uint m=0;
   p=els_16_r;
   *p=0x00;
   *(p+1)=64;
   *(p+2)=0x00;
   *(p+3)=64;
   *(p+4)=0x88;
   *(p+5)=0xff;
   p=p+6;
  for(i=0;i<4;i++)
  {
    for(temp1=0;temp1<16;temp1++)
	  {
	    for(temp2=0;temp2<4;temp2++)
		   for(temp3=0;temp3<2;temp3++)
		   {
		         if(els_p[els_type][els_next][i][temp2])
			 //if(cut_pix[i][temp2])
			 *p=els[temp1][temp3];
                         else
			 *p=0x00;
			 p++;
		   }
	  }
   }    
}
 /********************************************************************

函 数 名:cur_with()
功 能:   获得当前方块的有效宽度
说 明:
调 用:     with()
入口参数: 
返 回 值: 前方块的有效宽度
设 计:    志博51 AVR PIC 开发板  日 期:2007年11月13日
变 更 日 期:
变 更 备 注:
***********************************************************************/
uchar cur_with(void)//
{
   int a=0;
   int b=0;
   for(b=3;b>=0;b--)
    for(a=3;a>=0;a--)
	{
	 if(els_p[els_type][els_next][a][b])
	  return ((b+1));
	}
}  
uchar with(void)//根据当前方块的位置取得将要画方块的实际宽度(防止跨界)
{
   int a=0;
   int b=0;
   for(b=3;b>=0;b--)
    for(a=3;a>=0;a--)
	{
	 if(cut_pix[a][b])
	 {
	  if((abs_x+4)<14)
          return 4;
	  return ((b+1));
	 }
	  if((a==0)&&(b==0)&&(down_lab))
	  {
	  down_lab=0;
	  return (cur_with());
	  }////不够简洁要重写
	  else if((a==0)&&(b==0))
	  return 1;
	}
	  
}
  
void make_els_cut(void)//将方块的占用映射形式(4*4)变为(64*64)实际象素BMP形式 
{
  uchar i=0;
  uchar j=0;
  uchar w=0;
  uchar temp1=0;
  uchar temp2=0;
  uchar temp3=0;
  uchar k=0;
  uchar *p;
  uint m=0;
  w=with();
   p=els_16_r;
   *p=0x00;
   *(p+1)=w*16;
   *(p+2)=0x00;

⌨️ 快捷键说明

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