单片机控制点阵俄罗斯方块的程序源码
来源:互联网 发布:linux查看运行内存大小 编辑:程序博客网 时间:2024/05/18 16:39
主函数
#include<reg52.h>
#include "boxfunction.h"
#define uchar unsigned char
#define uint unsigned int
sbit swit = P1^0;
sbit left = P1^1;
sbit right = P1^2;
sbit down = P1^3;
sbit reset = P1^4;
sbit led = P1^7;
sbit led1 = P1^6;
sbit led2 = P1^5;
uchar arry[33];
uchar tmp[33];
char stat = 0;
char key1;
char key2;
char key_for_extern;
char flag = 0;
int seed1,seed2;
//********************************************************8888
//*************************************************************
unsigned char code table_num[] = {
0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,//0
0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,//1
0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,//2
0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,//3
0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,//4
0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,//5
0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,//6
0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,//7
0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,//8
0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,//9
};
unsigned char code tabe_start[] = {
0x01,0x00,0x01,0x00,0x7F,0xFC,0x03,0x80,
0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,
0x0F,0xE0,0x00,0x40,0x00,0x80,0xFF,0xFE,
0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,//李",0
0x10,0x40,0x10,0x40,0x2F,0xFE,0x40,0x40,
0x97,0xFC,0x14,0xA4,0x24,0xA4,0x67,0xFC,
0xA0,0x00,0x2F,0xFE,0x20,0x40,0x20,0x24,
0x25,0x22,0x25,0x0A,0x29,0x08,0x20,0xF8,//德",1
0x00,0x00,0x07,0xFC,0xFC,0x04,0x24,0xA4,
0x21,0x10,0x22,0x08,0x20,0x40,0xF8,0x40,
0x27,0xFC,0x20,0x40,0x20,0xE0,0x39,0x50,
0xE2,0x48,0x4C,0x46,0x00,0x40,0x00,0x40,//琛",2
0x01,0x00,0x02,0x00,0x04,0x00,0x1F,0xF0,
0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,
0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,//自",3
0x00,0x40,0x00,0x40,0x7C,0x40,0x00,0x40,
0x01,0xFC,0x00,0x44,0xFE,0x44,0x20,0x44,
0x20,0x44,0x20,0x84,0x48,0x84,0x44,0x84,
0xFD,0x04,0x45,0x04,0x02,0x28,0x04,0x10,//动",4
0x08,0x80,0x08,0x80,0x08,0x84,0x10,0x88,
0x10,0x90,0x30,0xA0,0x30,0xC0,0x50,0x80,
0x91,0x80,0x12,0x80,0x14,0x80,0x10,0x82,
0x10,0x82,0x10,0x82,0x10,0x7E,0x10,0x00,//化",5
0x00,0x00,0x00,0x00,0x7F,0xFC,0x44,0x44,
0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
0x48,0x44,0x48,0x3C,0x50,0x04,0x60,0x04,
0x40,0x04,0x7F,0xFC,0x40,0x04,0x00,0x00,//四",6
0x00,0x80,0x00,0x80,0xF8,0xBE,0x22,0x88,
0x22,0x88,0x22,0x88,0x22,0x88,0xFA,0xBE,
0x22,0x88,0x24,0x88,0x20,0x88,0x39,0x08,
0xE1,0x08,0x42,0x3E,0x04,0x00,0x08,0x00,//班",7
};
//******************************用于测试led***********************************
void init_arry()
{
int i;
for(i=0; i<=32; i++)
arry[i]=0x00;
//arry[30] = 0xff;
//arry[16] = 0xf8;
arry[32] = 0xff;//人为加一个底行 不作为显示,仅作为下落判断依据
draw_line(arry);
}
void init_timer()
{
TMOD = 0X01;
TH0 = (65535-10000)/256;
TL0 = (65535-10000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
char keyscan()
{
int i;
P1 = P1|0x1f;
for(i=2;i>0;i--);
if(swit == 0)
{
if(stat <= 2)
{
stat ++;
// led = ~led;
}
return 1;
}
else if(left == 0)
{
if(stat <= 2)
{
stat ++;
}
return 2;
}
else if(right == 0)
{
if(stat <= 2)
{
stat ++;
}
return 3;
}
else if(down == 0)
{
if(stat <= 2)
{
stat ++;
}
return 4;
}
else if(reset == 0)
{
if(stat <= 2)
{
stat ++;
}
return 5;
}
else
{
stat = 0;
return 0;
}
}
/*
typedef struct{
unsigned char x;
unsigned char y;
unsigned char shap;
unsigned char mode;
unsigned int tpbox;
unsigned int box_new;
*/
void delay_ms()
{
int x,y;
for(x=2;x>0;x--)
for(y=110;y>0;y--);
}
/*void start()
{
char j,k,*temp;
int i;
for(i=0; i<=8*32; i+=2)
{
temp = &tabe_start[i];
for(k=0; k<2; k++)
{
for(j=0; j<6; j++)
{
display(temp);
}
}
}
}*/
void init()
{
porta = 0x00;
portd = 0x00;
init_arry();
}
uint deal_to_key;
void main()
{
uint deal;
box b;
uint time=2;
init();
box_init(&b,seed1%7,seed2%4);
init_timer();
while(1)
{
// start();
while(deal != 1)
{
deal = box_drop_down(&b,time,arry,tmp); //方块下降函数
box_init(&b,seed1%7,seed2%4);
//led = 0;
}
init();
time=2;
deal = 0;
}
}
void timer() interrupt 1 //10ms *******************************中断一次,用于键盘检测***********************************************
{
TH0 = (65535-10000)/256;
TL0 = (65535-10000)%256;
seed1++;
seed2+=3;
if(seed1 == 100)
seed1 = 0;
if(seed2 == 100)
seed2 = 0;
EA = 0;
key1 = keyscan();
if(stat == 1)
{
key2 = key1; //key2为第一次的保存值
//led = 0;
}
else if(stat == 2)
{
if(key2 == key1)
{
//led = 0;
stat++;
}
else
stat = 0;
}
else if(stat == 3)
{
flag = 1; //确定有按键按下,等待按键弹起,状态始终保持为3,直到按键弹起,状态归零,标志位清零
}
if(flag==1 && swit==1 && left==1 && right==1 && down==1 && reset==1)
{
flag = 0;
//led = 0;
stat = 0;
key_for_extern = key2;//给按键赋值 付的是第一次保存下来的数值
}
EA = 1;
}
功能模块:
#include "boxfunction.h"
#include<reg52.h>
sbit en1 = P2^3;
sbit en2 = P2^7;
sbit led = P1^7;
void test()
{
P1 = 0xf0;
}
void delay(unsigned int x)
{
unsigned int y,z;
for(y=x ;y>0 ;y--)
for(z=110 ;z>0 ; z--);
}
//*******************************显示数组内容***********************************
void display(uchar* arry)
{
int i;
for(i=0; i<16; i++)
{
P2 = 0X00;
if(i<8)
{
P2 = (P2|i)|0x08;
}
else
P2 = (P2|(i<<4))|0x80;
portd = arry[2*i];
porta = arry[2*i+1];
delay(1);
}
}
//***************************************************************************
//********************************用于存储方块状态***************************
unsigned int box_read_data(unsigned char tpmode,unsigned char tpshape)
{
unsigned int tpbox;
switch(tpmode)
{
case 0: switch(tpshape)
{
case 0: tpbox=0xf000;break;
case 1: tpbox=0x8888;break;
case 2: tpbox=0xf000;break;
case 3: tpbox=0x8888;break;
default:;
}break;
case 1: switch(tpshape)
{
case 0: tpbox=0xe800;break;
case 1: tpbox=0xc440;break;
case 2: tpbox=0x2e00;break;
case 3: tpbox=0x88c0;break;
default:;
}break;
case 2: switch(tpshape)
{
case 0: tpbox=0xe200;break;
case 1: tpbox=0x44c0;break;
case 2: tpbox=0x8e00;break;
case 3: tpbox=0xc880;break;
default:;
}break;
case 3: switch(tpshape)
{
case 0: tpbox=0xcc00;break;
case 1: tpbox=0xcc00;break;
case 2: tpbox=0xcc00;break;
case 3: tpbox=0xcc00;break;
default:;
}break;
case 4: switch(tpshape)
{
case 0: tpbox=0xc600;break;
case 1: tpbox=0x4c80;break;
case 2: tpbox=0xc600;break;
case 3: tpbox=0x4c80;break;
default:;
}break;
case 5: switch(tpshape)
{
case 0: tpbox=0x6c00;break;
case 1: tpbox=0x8c40;break;
case 2: tpbox=0x6c00;break;
case 3: tpbox=0x8c40;break;
default:;
}break;
case 6: switch(tpshape)
{
case 0: tpbox=0x4e00;break;
case 1: tpbox=0x8c80;break;
case 2: tpbox=0xe400;break;
case 3: tpbox=0x4c40;break;
default:;
}break;
default:;
}
return(tpbox);
}//方块缓存数据函数(输入方块类型和形状即可获得方块缓存数据)
//***************************************************************************************
//**************************************读取方块到显示数组*******************************
void write_box_to_arry(unsigned char position_x,unsigned char position_y,unsigned int tpbox_new,unsigned int tpbox_old,unsigned char *arry)
{
char i;
unsigned int temp,temp_y;
//删除旧的方块
temp = tpbox_old;
temp_y = position_y;
for(i=3;i>=0;i--)
{
arry[2*temp_y + i*2] = ( arry[2*temp_y + i*2] & (~ (((temp&0x000f)<<4) >> position_x)) ); //需要保证只修改方块所经过的列 而不会影响到此行其他位置
temp = temp>>4;
}
temp = tpbox_new;
temp_y = position_y;
for(i=3;i>=0;i--)
{
arry[2*(temp_y+i)] = arry[2*(temp_y+i)] | ( ((temp&0x000f)<<4) >> position_x );
temp = temp>>4;
}
}
void delet_box_from_arry(unsigned char position_x,unsigned char position_y,unsigned int tpbox_old,unsigned char *arry)
{
char i;
unsigned int temp,temp_y;
//删除旧的方块
temp = tpbox_old;
temp_y = position_y;
for(i=3;i>=0;i--)
{
arry[2*temp_y + i*2] = ( arry[2*temp_y + i*2] & (~ (((temp&0x000f)<<4) >> position_x)) ); //需要保证只修改方块所经过的列 而不会影响到此行其他位置
temp = temp>>4;
}
}
//*********************************************擦除某一行******************************
void line_cleared(char line,unsigned char *arry)
{
arry[line*2] = 0x00;
}
//**************************************检查是否可以继续下降***************************
/*char box_enable_drop_down(unsigned char *arry, box *b)
{
char i;
unsigned char temp;
unsigned char reg[4];
temp = b->tpbox;
for(i=3; i>=0; i--)//当前位置的
{
// arry[2*(b.y+i)] = arry[2*(b.y+i)] & (~((temp&0x000f)<<4) >> b.x);
reg[i] = (((temp&0x000f)<<4) >> b->x); //reg[i]相当于方块的数据
temp = temp >> 4;
}
for(i=3; i>=0; i--)
{
if( ( reg[i] & (arry[(b->y+i+1)*2]) ) != 0x00 )//阻塞 方块的上一行和真实显示数组中方块位置的下一行 相与 全为0 则无阻塞
return 0;
}
return 1;
}*/
char box_enable_drop_down(unsigned char *arry, box *b)
{
char i;
unsigned int temp;
unsigned char reg;
temp = b->tpbox;
for(i=3; i>=0; i--)//当前位置的
{
// arry[2*(b.y+i)] = arry[2*(b.y+i)] & (~((temp&0x000f)<<4) >> b.x);
reg = (((temp&0x000f)<<4) >> b->x); //reg[i]相当于方块的数据
temp = temp >> 4;
if( ( reg & (arry[(b->y+i+1)*2]) ) != 0x00 )//阻塞 方块的上一行和真实显示数组中方块位置的下一行 相与 全为0 则无阻塞
{
return 0;
}
}
return 1;
}
/**************************************************************
此处出现一个大bug,表现在有的方块下落时会正常卡住,有的卡不住。由于有些可以正常卡住,基本确定主要程序没有大问题,
初步估计char box_enable_drop_down(unsigned char *arry, box *b) 函数中卡值的if语句出错。 根据出错统计规律,有两行的子模
出问题,三行以上的就没问题。检测if语句没错, 问题出在temp类型定义为char 产生了丢位。
*************************************************************/
//***************************************初始化方块************************************
void box_init(box *b, char mod ,char sha)
{
b->x = 4;
b->y = 0;
b->mode = mod;
b->shap = sha;
b->tpbox = box_read_data(b->mode,b->shap);
}
//****************************************画线*************************************
void draw_line(unsigned char *arry) //先赋值给缓存数组 此处运行效率不高 但是和后面 更新显示数组有耦合 有待改进
{
int i;
for(i=0; i<32; i+=2)
arry[i+1] = arry[i+1] | 0x80;
}
//**************************************下降*******************************************
void arry_to_tmp(unsigned char *arry,unsigned char *tmp)
{
int i;
for(i=0;i<33;i++)
tmp[i] = arry[i];
arry[32] = 0xff;
}
/*
typedef struct{
unsigned char x;
unsigned char y;
unsigned char shap;
unsigned char mode;
unsigned int tpbox;
unsigned int box_new;
}box;
*/
/*char box_enable_move_left(box* b,unsigned char *arry)
{
int i,j;
unsigned int temp;
unsigned char reg,tmp;
temp = b->tpbox;
j = b->y * 2;
for(i=3; i>=0; i--)
{
reg =( ((temp&0x000f)<<4) >> b->x);
tmp = ( ( ( reg | arry[j + i] ) & ((0x80>>(b->x - 1)) ) | 0xf0>>b->x));
if( (tmp == (0x80>>(b->x - 1)) ) || (tmp&0x80 == 0x80) )
return 0;
temp = temp >>4;
}
return 1;
}*/
//*************************删除满行***************************************
char delet_full_line(unsigned char *arry)
{
char i=0,j=30,k;
while(i<=4 && j>=2) //
{
if(arry[j] == 0xff)
{
for(k=j;k>=2;k-=2)
{
*(arry+k) = *(arry+k-2);
}
arry[0] = 0x00;
i++;
j = 30;
}
else
j = j-2;
}
return i;
}
/**************************************全局变量***********************************************88
来源: main.c
作用函数 : char keyfunc(box* b,char key) 用来赋值
char box_drop_down(box *b,unsigned int time,unsigned char *arry,unsigned char *tmp) 用来检测
传来的全局变量 当按键reset按下赋值1,传值到box_drop_down ,使跳出循环 ,游戏复位
************************************************************************************************/
extern unsigned int deal_to_key;//main.c
char keyfunc(box* b,char key)//定义结构体指针函数中应出现相应的赋值 这样编译才能通过
{
//led = 0;
char down = 0;
switch(key)
{
case 1:{
b->shap++; //按键1 shap自增 旋转但是形状不变
if(b->shap == 4)
b->shap = 0;
b->box_new = box_read_data(b->mode,b->shap);
}break;
case 2:{
b->x--;
}break;
case 3:{
b->x++;
}break;
case 4:{
down = 1;
return down;//产生快速下降标志 使time加快
}break;
case 5:{
deal_to_key = 1;
}break;
}
}
extern char key_for_extern;
char box_drop_down(box *b,unsigned int time,unsigned char *arry,unsigned char *tmp)
{
char i,j,k,temp_time,first_time,t; //temp_time用于加速 first_time用于保存参数time的值
b->box_new = b->tpbox;
b->y = 0;//y从第0行开始下降 每次走一个
first_time = time;
t = first_time;
for(i=0; i<19; i++)
{
if(deal_to_key == 1)//复位键按下 游戏结束
{
deal_to_key = 0;
return 1;
}
for(k=0; k<10; k++)//每下降到新的一层 都有十次改变的机会。
{
temp_time = keyfunc(b,key_for_extern); //查看按键的值 更新方块状态
key_for_extern = 0;
/* if(temp_time == 0)//加速判断
t = first_time;
else
t = temp_time;*/
delet_box_from_arry(b->x, b->y, b->tpbox,arry);//清除记录数组中的内容,防止下落时留下尾巴
write_box_to_arry(b->x, b->y, b->box_new, b->tpbox, arry);//写入新的数据
arry_to_tmp(arry,tmp);
for(j=0; j<t; j++)//循环显示同一个数组 达到下落时暂停的效果 通过改变time值来改变方块下降速度
{
display(tmp);
}
delet_box_from_arry(b->x, b->y, b->tpbox,arry);//清除记录数组中的内容,防止下落时留下尾巴
delet_box_from_arry(b->x, b->y, b->tpbox,tmp);//清除显示数组中的内容
b->tpbox = b->box_new;//显示完毕后 新方块的数据编程旧方块
}
//arry_to_tmp(arry,tmp);
if(box_enable_drop_down(tmp, b) == 1)//如果可以继续下降则下降
{
b->y++;
}
else //如果有阻塞 将方块重新写到最后的位置 更新显示数组
{
write_box_to_arry(b->x, b->y, b->box_new, b->tpbox, arry);
delet_full_line(arry);
if(tmp[0] != 0x00) //最顶层一行不为空 游戏结束
{
return 1;
}
arry_to_tmp(arry,tmp);
return 0;
}
}
return 0;
}
- 单片机控制点阵俄罗斯方块的程序源码
- PIC单片机控制LED点阵显示屏
- c#实现的俄罗斯方块程序(源码)
- 点阵版俄罗斯方块
- 基于AT89S52单片机的可控点阵
- 单片机控制点阵字符显示及字模提取原理
- 51单片机控制步进电机的程序
- 单片机控制直流电机的VHDL程序
- 一个俄罗斯方块的源码
- 俄罗斯方块的源码实现
- 俄罗斯方块的源码实现
- 51单片机8*8点阵LED显示原理及程序
- 51单片机8*8点阵LED显示原理及程序
- MAX7219多级联串行控制多个点阵/数码管的详解(附源码)
- 51单片机点阵解析
- 图形界面的俄罗斯方块 c源码
- c++写的俄罗斯方块源码
- 带AI的俄罗斯方块源码
- Number Steps 1391
- Gerrit 添加一个已经有的git工程到gerrit服务器
- java笔试题(引自传智播客)-上
- django开发环境搭建(参考流程)
- 对compatible参数的理解【待完成】
- 单片机控制点阵俄罗斯方块的程序源码
- 统计单行或多行Gridview某列的总数
- 使用jqMobi开发app基础:注销页面的实现
- Python-Project Euler 39
- iOS中UIImage转换为NSData 方法
- 如何在CSDN博客添加链接
- linux中dir命令参数应用
- Java 访问带有密码的 Mysql数据库
- 四、中英翻译、歌词、藏头诗、智能聊天