我是靠谱客的博主 甜美面包,最近开发中收集的这篇文章主要介绍点阵版俄罗斯方块,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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


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

最后

以上就是甜美面包为你收集整理的点阵版俄罗斯方块的全部内容,希望文章能够帮你解决点阵版俄罗斯方块所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部