概述
我们使用上次制作的点阵屏,开发一个俄罗斯方块的游戏。
单片机的P1接屏的接口,P3.2-->P3.5接矩阵独立键盘
一、演示视频地址,http://v.youku.com/v_show/id_XNjkxOTU3NTM2.html
二、源代码
1. Tetris.h
#ifndef __TETRIS_H__
#define __TETRIS_H__
void delay_ms( unsigned char n);
void Tetris_Init();
void Tetris_Refresh();
void Tetris_Move( signed char dy);
void Tetris_Rotate();
#endif
2. Tetris.c
#include <stdlib.h>
#include "Tetris.h"
#include "RGBDZh.h"
static unsigned int code blocks[7][5] =
{
{ 0x0001, 0x6600, 0x0000, 0x0000, 0x0000},
{ 0x0002, 0x2222, 0x0f00, 0x0000, 0x0000},
{ 0x0002, 0xc600, 0x2640, 0x0000, 0x0000},
{ 0x0002, 0x6c00, 0x4620, 0x0000, 0x0000},
{ 0x0004, 0x4460, 0x02e0, 0x6220, 0x0740},
{ 0x0004, 0x2260, 0x0e20, 0x6440, 0x4700},
{ 0x0004, 0x2620, 0x0720, 0x2320, 0x2700}
};
static unsigned char code colors[6] = { RED, GREEN, BLUE, YELLOW, PURPLE, LBLUE};
static unsigned char xdata block_id = 0;
static unsigned char xdata rotate_id = 0;
static unsigned char xdata color_id = 0;
static signed char xdata pos_x = 0;
static signed char xdata pos_y = 0;
unsigned char xdata over = 0;
static unsigned char xdata mutex = 0;
// 毫秒级延时
void delay_ms( unsigned char n)
{
unsigned char i;
while( n --)
for( i = 0; i < 120; i ++);
}
void Tetris_ShowBlock( signed char x, signed char y, unsigned char r)
{
unsigned int b = blocks[block_id][r];
signed char i, j;
for( i = x; i < x + 4; i ++)
{
if( i < 0 || i >= PIXEL_COL_COUNT)
continue;
for( j = y; j < y + 4; j ++)
{
if( j < 0 || j >= PIXEL_ROW_COUNT)
continue;
if(((( b >> ( 4 * ( 3 - i + x))) & 0xf) >> ( 3 - j + y)) & 0x1)
Lcd_SetPixel( i, j, colors[color_id]);
}
}
}
void Tetris_Init()
{
block_id = rand() % 7;
rotate_id = rand() % blocks[block_id][0] + 1;
color_id = rand() % 6;
pos_x = PIXEL_COL_COUNT - 4;
pos_y = ( PIXEL_ROW_COUNT - 4) / 2;
over = 0;
mutex = 0;
Lcd_Clear();
Tetris_ShowBlock( pos_x, pos_y, rotate_id);
}
void Tetris_ClearBlock( signed char x, signed char y, unsigned char r)
{
unsigned int b = blocks[block_id][r];
signed char i, j;
for( i = x; i < x + 4; i ++)
{
if( i < 0 || i >= PIXEL_COL_COUNT)
continue;
for( j = y; j < y + 4; j ++)
{
if( j < 0 || j >= PIXEL_ROW_COUNT)
continue;
if(((( b >> ( 4 * ( 3 - i + x))) & 0xf) >> ( 3 - j + y)) & 0x1)
Lcd_SetPixel( i, j, NONE);
}
}
}
unsigned char Tetris_Check( signed char x, signed char y, unsigned char r)
{
unsigned int b = blocks[block_id][r];
signed char i, j;
for( i = x; i < x + 4; i ++)
for( j = y; j < y + 4; j ++)
if(((( b >> ( 4 * ( 3 - i + x))) & 0xf) >> ( 3 - j + y)) & 0x1)
if( i < 0 || i >= PIXEL_COL_COUNT || j < 0 || j >= PIXEL_ROW_COUNT)
return 0;
else if( Lcd_GetPixel( i, j) != NONE)
return 0;
return 1;
}
void Tetris_DeleteRow()
{
signed char x, y, i;
for( x = PIXEL_COL_COUNT - 1; x >= 0; x --)
{
for( y = 0; y < PIXEL_ROW_COUNT; y ++)
if( Lcd_GetPixel( x, y) == NONE)
break;
if( y < PIXEL_ROW_COUNT)
continue;
for( y = 0; y < PIXEL_ROW_COUNT; y ++)
{
Lcd_SetPixel( x, y, NONE);
delay_ms( 100);
}
for( i = x; i < PIXEL_COL_COUNT - 1; i ++)
for( y = 0; y < PIXEL_ROW_COUNT; y ++)
Lcd_SetPixel( i, y, Lcd_GetPixel( i + 1, y));
for( y = 0; y < PIXEL_ROW_COUNT; y ++)
Lcd_SetPixel( PIXEL_COL_COUNT - 1, y, NONE);
}
}
void Tetris_Refresh()
{
unsigned char move_flag = 0;
if( mutex == 1)
return;
mutex = 1;
// 清除方块
Tetris_ClearBlock( pos_x, pos_y, rotate_id);
// 向下移动
if( Tetris_Check( pos_x - 1, pos_y, rotate_id))
pos_x --;
else
move_flag = 1;
// 显示方块
Tetris_ShowBlock( pos_x, pos_y, rotate_id);
// 未落到底
if( !move_flag)
{
mutex = 0;
return;
}
// 消除完整行
Tetris_DeleteRow();
// 生成新方块
block_id = rand() % 7;
rotate_id = rand() % blocks[block_id][0] + 1;
color_id = rand() % 6;
pos_x = PIXEL_COL_COUNT - 4;
pos_y = ( PIXEL_ROW_COUNT - 4) / 2;
if( !Tetris_Check( pos_x, pos_y, rotate_id))
{
over = 1;
mutex = 0;
return;
}
Tetris_ShowBlock( pos_x, pos_y, rotate_id);
mutex = 0;
}
void Tetris_Move( signed char dy)
{
if( mutex == 1)
return;
mutex = 1;
// 清除方块
Tetris_ClearBlock( pos_x, pos_y, rotate_id);
// 左右移动
if( Tetris_Check( pos_x, pos_y + dy, rotate_id))
pos_y += dy;
// 显示方块
Tetris_ShowBlock( pos_x, pos_y, rotate_id);
mutex = 0;
}
void Tetris_Rotate()
{
if( mutex == 1)
return;
mutex = 1;
// 清除方块
Tetris_ClearBlock( pos_x, pos_y, rotate_id);
// 旋转
if( Tetris_Check( pos_x, pos_y, rotate_id % blocks[block_id][0] + 1))
rotate_id = rotate_id % blocks[block_id][0] + 1;
// 显示方块
Tetris_ShowBlock( pos_x, pos_y, rotate_id);
mutex = 0;
}
3. main.c
#include "RGBDZh.h"
#include "Tetris.h"
// 按键定义
sbit key_left = P3^2; // 左
sbit key_right = P3^3; // 右
sbit key_rotate = P3^5; // 变
extern unsigned char xdata over;
int main()
{
// T0设置, 定时1ms
TMOD &= 0xfc;
TMOD |= 0x01;
TH0 = 0xfc;
TL0 = 0x66;
TR0 = 1;
PT0 = 1;// 提高优先级
ET0 = 1;
// T1设置, 定时50ms
TMOD &= 0xcf;
TMOD |= 0x10;
TH1 = 0x4c;
TL1 = 0x00;
TR1 = 1;
ET1 = 1;
EA = 1;
Lcd_Init();
Tetris_Init();
while(1)
{
if( over == 1)
{
Lcd_Init();
Tetris_Init();
continue;
}
if( key_left == 0)
{
// 左
delay_ms( 10);
if( key_left == 0)
{
Tetris_Move( -1);
while( !key_left);
}
}
if( key_right == 0)
{
// 右
delay_ms( 10);
if( key_right == 0)
{
Tetris_Move( 1);
while( !key_right);
}
}
if( key_rotate == 0)
{
// 变
delay_ms( 10);
if( key_rotate == 0)
{
Tetris_Rotate();
while( !key_rotate);
}
}
}
return 0;
}
void disp() interrupt 1
{
TH0 = 0xfc;
TL0 = 0x66;
Lcd_Refresh();
}
void down() interrupt 3
{
static unsigned char n500ms = 0;
TH1 = 0x4c;
TL1 = 0x00;
n500ms ++;
if( n500ms >= 10)
{
// 500ms
Tetris_Refresh();
n500ms = 0;
}
}
4. RGBDZh.h和RGBDZh.c见之前的文章
请移步www.yintju03.com/blog
最后
以上就是甜美面包为你收集整理的点阵版俄罗斯方块的全部内容,希望文章能够帮你解决点阵版俄罗斯方块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复