点阵版俄罗斯方块

我们使用上次制作的点阵屏,开发一个俄罗斯方块的游戏。 


单片机的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

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
先来看看演示视频吧! 1、STC89C52RC作为整个控制电路的核心。 2、8X8单色点阵LG12088BH-W 主要参数 Ø驱动电流:20±5mA Ø颜色:红色 Ø规格:8×8黑底 Ø数量:2 信号源:由译码器提供16行扫描信号,由锁存器提供8位 显示信号和驱动电流。 功能:提供8×16个像素点的显示屏,为游戏提供必要的 图形显示模块。 3、3.4-to-16 Line Decoder 信号源:P2低四位(P1.0至P1.3),使能E1接P2.7,E2接地 功能:为8×16点阵提供16行低电平扫描信号。 4、四位八段共阳数码管LG5641BH 主要参数: Ø驱动电流:10mA左右 信号源:用两块锁存器分别控制位选信号和段选信号。 功能:为游戏板提供必要的分数显示模块。 5、同向锁存器SN74HC573AN 关键参数 Ø真值表: Ø驱动性:可驱动数码管和点阵正常点亮 Ø数量:3块 (1)作为点阵显示信号输送和驱动的锁存器(一块) 信号源:单片机P3I/O 功能:给点阵送显示信号并提供驱动电流。(LE接地) (2)作为P0口拓展和数码管位选、段选信号输送以及驱动 电流提供锁存器(两块)。 信号源:单片机P0口(已上拉10K电阻)。两个锁存控制端接在单片机P2口。 功能:为数码管送入段选信号和位选信号,提供电流驱动 6、按钮 一个自锁开关:用作整个游戏板的开关(带发光二极管)。 六个按键:一个用作复位键,其余五个用作人为控制输入 信号源:人为击按。 功能:Start/Suspend键:游戏开始和暂停控制 Up键:控制形状逆时针旋转 Left和Right键:控制形状左右移动一格 Down键:控制形状快速下降 最后再附上一个Protues仿真时候的截图:
51单片机俄罗斯方块程序LED点阵是一种基于51单片机控制的LED点阵显示器,用于实现俄罗斯方块游戏的显示和操作。 这个程序的实现主要包括以下几个方面: 1. 硬件连接:将51单片机的IO口通过适当的电路连接到LED点阵的行列控制引脚,以实现对点阵的控制。 2. 初始化:在程序开始时,需要对LED点阵进行初始化。这包括设置行列引脚的输入输出模式、设置刷新频率等。 3. 俄罗斯方块的显示:通过在点阵上分别亮起不同的LED点来显示俄罗斯方块的各个方块。可以通过定义一个数组,保存不同形状的方块在点阵上的显示方式,根据方块的位置和形状,通过控制点阵的引脚亮灭来实现。 4. 俄罗斯方块的控制:通过按键输入控制俄罗斯方块的移动、旋转等操作。可以通过读取按键的状态,判断用户输入,然后调用相应的函数来实现方块的移动、旋转等操作。 5. 游戏的逻辑控制:通过不断刷新LED点阵的显示,更新方块的位置和形状,并检测和处理碰撞等情况,实现俄罗斯方块游戏的进行。可以通过定时中断来控制刷新频率,从而实现游戏的流畅进行。 总之,51单片机俄罗斯方块程序LED点阵是一项基于51单片机和LED点阵的工程项目,通过提供适当的硬件连接和软件实现来实现俄罗斯方块游戏在LED点阵上的显示和操作。这样的程序既可以用于娱乐,也可以作为学习和研究的项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值