#include <reg52.h>
#include <intrins.h>
sbit DATA_PIN = P1^0;
sbit CLOCK_PIN = P1^1;
sbit LATCH_PIN = P1^2;
sbit KEY_LEFT = P3^1;
sbit KEY_RIGHT = P3^4;
sbit KEY_ROT = P3^5;
sbit KEY_DOWN = P3^6;
#define MAP_WIDTH 8
#define MAP_HEIGHT 8
#define FALL_DELAY 500
unsigned char game_map[MAP_HEIGHT] = {0};
unsigned char display_buffer[MAP_HEIGHT] = {0};
struct
{
unsigned char type;
unsigned char rotation;
char x;
char y;
} current_block;
unsigned int fall_timer = 0;
unsigned int game_speed = FALL_DELAY;
bit game_over = 0;
unsigned int score = 0;
unsigned char code SHAPES[7][4][4] = {
{{0x0F, 0x00, 0x00, 0x00},
{0x04, 0x04, 0x04, 0x04},
{0x0F, 0x00, 0x00, 0x00},
{0x04, 0x04, 0x04, 0x04}},
{{0x0E, 0x04, 0x00, 0x00},
{0x04, 0x06, 0x04, 0x00},
{0x04, 0x0E, 0x00, 0x00},
{0x04, 0x0C, 0x04, 0x00}},
{{0x08, 0x0C, 0x00, 0x00},
{0x06, 0x04, 0x04, 0x00},
{0x0C, 0x08, 0x00, 0x00},
{0x04, 0x04, 0x06, 0x00}},
{{0x04, 0x0C, 0x00, 0x00},
{0x04, 0x04, 0x06, 0x00},
{0x0C, 0x04, 0x00, 0x00},
{0x06, 0x04, 0x04, 0x00}},
{{0x06, 0x06, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x00}},
{{0x06, 0x0C, 0x00, 0x00},
{0x04, 0x06, 0x02, 0x00},
{0x06, 0x0C, 0x00, 0x00},
{0x04, 0x06, 0x02, 0x00}},
{{0x0C, 0x06, 0x00, 0x00},
{0x02, 0x06, 0x04, 0x00},
{0x0C, 0x06, 0x00, 0x00},
{0x02, 0x06, 0x04, 0x00}}
};
void send_byte(unsigned char dat)
{
unsigned char i;
for(i=0; i<8; i++)
{
DATA_PIN = dat & 0x80;
CLOCK_PIN = 1;
_nop_();_nop_();
CLOCK_PIN = 0;
dat <<= 1;
}
}
void refresh_display()
{
static unsigned char row = 0;
LATCH_PIN = 0;
send_byte(~display_buffer[row]);
send_byte(1 << row);
LATCH_PIN = 1;
row = (row + 1) % MAP_HEIGHT;
}
void timer1_init()
{
TMOD = 0x11;
TH1 = 0xFC;
TL1 = 0x18;
ET1 = 1;
TR1 = 1;
EA = 1;
}
bit check_collision()
{
unsigned char i, j;
unsigned char shape_data;
for(i=0; i<4; i++)
{
if(current_block.y + i >= MAP_HEIGHT)
return 1;
shape_data = SHAPES[current_block.type][current_block.rotation][i];
for(j=0; j<4; j++)
{
if(shape_data & (0x08 >> j))
{
int map_x = current_block.x + j;
int map_y = current_block.y + i;
if(map_x < 0 || map_x >= MAP_WIDTH)
return 1;
if(map_y >= MAP_HEIGHT)
return 1;
if(map_y >= 0 && (game_map[map_y] & (0x80 >> map_x)))
return 1;
}
}
}
return 0;
}
void new_block()
{
current_block.type = rand() % 7;
current_block.rotation = 0;
current_block.x = 3;
current_block.y = 0;
if(check_collision())
{
game_over = 1;
}
}
void fix_block()
{
unsigned char i, j,shape_data;
for(i=0; i<4; i++)
{
if(current_block.y + i < 0) continue;
shape_data = SHAPES[current_block.type][current_block.rotation][i];
for(j=0; j<4; j++)
{
if(shape_data & (0x08 >> j))
{
int map_x = current_block.x + j;
int map_y = current_block.y + i;
if(map_x >=0 && map_x < MAP_WIDTH && map_y >=0 && map_y < MAP_HEIGHT)
{
game_map[map_y] |= (0x80 >> map_x);
}
}
}
}
}
void clear_lines()
{
unsigned char y, y2,x;
bit full_line;
for(y=0; y<MAP_HEIGHT; y++)
{
full_line = 1;
for( x=0; x<MAP_WIDTH; x++)
{
if(!(game_map[y] & (0x80 >> x)))
{
full_line = 0;
break;
}
}
if(full_line) {
score += 10;
if(game_speed > 100) game_speed -= 10;
for(y2=y; y2>0; y2--)
{
game_map[y2] = game_map[y2-1];
}
game_map[0] = 0;
}
}
}
void update_display()
{
unsigned char i, j,x,y,shape_data;
for(i=0; i<MAP_HEIGHT; i++)
{
display_buffer[i] = game_map[i];
}
for(i=0; i<4; i++)
{
y = current_block.y + i;
if(y >= MAP_HEIGHT || y < 0) continue;
shape_data = SHAPES[current_block.type][current_block.rotation][i];
for(j=0; j<4; j++)
{
x = current_block.x + j;
if(x >=0 && x < MAP_WIDTH && (shape_data & (0x08 >> j)))
{
display_buffer[y] |= (0x80 >> x);
}
}
}
}
void move_block(char dx, char dy) {
current_block.x += dx;
current_block.y += dy;
if(check_collision())
{
current_block.x -= dx;
current_block.y -= dy;
if(dy > 0)
{
fix_block();
clear_lines();
new_block();
}
}
}
void rotate_block()
{
unsigned char old_rotation;
old_rotation = current_block.rotation;
current_block.rotation = (current_block.rotation + 1) % 4;
if(check_collision())
{
current_block.rotation = old_rotation;
}
}
void scan_keys() {
static bit key_flag = 0;
if(!key_flag) {
if(!KEY_LEFT) {
move_block(-1, 0);
key_flag = 1;
}
else if(!KEY_RIGHT) {
move_block(1, 0);
key_flag = 1;
}
else if(!KEY_DOWN) {
move_block(0, 1);
key_flag = 1;
}
else if(!KEY_ROT) {
rotate_block();
key_flag = 1;
}
}
else {
if(KEY_LEFT && KEY_RIGHT && KEY_DOWN && KEY_ROT) {
key_flag = 0;
}
}
}
void els()
{
unsigned char i;
timer1_init();
new_block();
scan_keys();
while(1)
{
if(game_over)
{
for( i=0; i<MAP_HEIGHT; i++)
{
display_buffer[i] = (i % 2) ? 0xFF : 0x00;
}
continue;
}
if(fall_timer >= game_speed)
{
move_block(0, 1);
fall_timer = 0;
}
scan_keys();
update_display();
}
}
void timer1_isr() interrupt 1
{
TH1 = 0xFC;
TL1 = 0x18;
refresh_display();
fall_timer++;
}程序一直在扫描矩阵
最新发布