- UID
- 373967
- 帖子
- 8967
- 主題
- 2609
- 精華
- 0
- 積分
- 1002
- 楓幣
- 0
- 威望
- 979
- 存款
- 35627
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 70
- 在線時間
- 459 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-12-15
|
以下是一個使用STC90C52RC微控制器製作的簡單俄羅斯方塊遊戲的程式碼示例:
#include <stc89.h>
/* LCD顯示屏的連接引腳 */
#define LCD_RS P2_0
#define LCD_RW P2_1
#define LCD_E P2_2
#define LCD_D4 P2_4
#define LCD_D5 P2_5
#define LCD_D6 P2_6
#define LCD_D7 P2_7
/* 七段顯示器的連接引腳 */
#define SEG_A P1_0
#define SEG_B P1_1
#define SEG_C P1_2
#define SEG_D P1_3
#define SEG_E P1_4
#define SEG_F P1_5
#define SEG_G P1_6
#define SEG_DP P1_7
/* LED矩陣的連接引腳 */
#define LED_CS P3_3
#define LED_CLK P3_4
#define LED_DIN P3_5
/* 按鈕的連接引腳 */
#define BTN_LEFT P3_0
#define BTN_ROTATE P3_1
#define BTN_RIGHT P3_2
/* 定義俄羅斯方塊的形狀和顏色 */
#define SHAPE_I 0
#define SHAPE_J 1
#define SHAPE_L 2
#define SHAPE_O 3
#define SHAPE_S 4
#define SHAPE_T 5
#define SHAPE_Z 6
#define COLOR_RED 1
#define COLOR_GREEN 2
#define COLOR_YELLOW 3
#define COLOR_BLUE 4
/* 定義方塊的大小和初始位置 */
#define BLOCK_SIZE 8
#define BLOCK_X0 4
#define BLOCK_Y0 0
/* 定義矩陣的大小和初始狀態 */
#define MATRIX_WIDTH 10
#define MATRIX_HEIGHT 20
unsigned char matrix[MATRIX_HEIGHT][MATRIX_WIDTH];
/* 定義俄羅斯方塊的數據結構 */
struct block {
unsigned char shape;
unsigned char color;
unsigned char x;
unsigned char y;
unsigned char angle;
} cur_block;
/* 定義遊戲狀態 */
unsigned char game_over = 0;
unsigned char score = 0;
/* 定義LCD顯示函數 */
void lcd_write_command(unsigned char command);
void lcd_write_data(unsigned char data);
void lcd_init();
void lcd_puts(unsigned char row, unsigned char col, unsigned char *str);
/* 定義七段顯示器顯示函數 */
void seg_display(unsigned char num);
/* 定義LED矩陣繪製函數 */
void led_draw_matrix();
/* 定義按鈕檢測函數 */
unsigned char btn_left_pressed();
unsigned char btn_rotate_pressed();
unsigned char btn_right_pressed();
/* 定義方塊操作函數 */
void new_block();
void move_left();
void move_right();
void rotate();
void drop();
unsigned char can_move_left();
unsigned char can_move_right();
unsigned char can_rotate();
unsigned char can_drop();
void merge_block();/* 定
義主函數 /
void main() {
/ 初始化LCD顯示屏 */
lcd_init();
/* 初始化七段顯示器 */
SEG_A = 1;
SEG_B = 1;
SEG_C = 1;
SEG_D = 1;
SEG_E = 1;
SEG_F = 1;
SEG_G = 0;
SEG_DP = 0;
/* 初始化LED矩陣 */
LED_CS = 1;
LED_CLK = 1;
LED_DIN = 1;
/* 初始化按鈕 */
BTN_LEFT = 1;
BTN_ROTATE = 1;
BTN_RIGHT = 1;
/* 初始化矩陣 */
unsigned char i, j;
for (i = 0; i < MATRIX_HEIGHT; i++) {
for (j = 0; j < MATRIX_WIDTH; j++) {
matrix[i][j] = 0;
}
}
/* 顯示開始畫面 */
lcd_puts(0, 0, "Tetris");
lcd_puts(1, 0, "Press start");
/* 等待按下按鈕開始遊戲 */
while (!btn_left_pressed() && !btn_rotate_pressed() && !btn_right_pressed());
/* 開始遊戲 */
new_block();
while (!game_over) {
/* 繪製矩陣和方塊 */
led_draw_matrix();
/* 等待按鈕按下 */
while (!btn_left_pressed() && !btn_rotate_pressed() && !btn_right_pressed() && can_drop());
/* 判斷按下的按鈕 */
if (btn_left_pressed()) {
move_left();
}
else if (btn_rotate_pressed()) {
rotate();
}
else if (btn_right_pressed()) {
move_right();
}
else {
drop();
}
/* 合併方塊 */
merge_block();
/* 產生新方塊 */
new_block();
}
/* 顯示結束畫面 */
lcd_puts(0, 0, "Game over!");
lcd_puts(1, 0, "Score:");
seg_display(score);
}
/* LCD顯示函數 */
void lcd_write_command(unsigned char command) {
LCD_RS = 0;
LCD_RW = 0;
LCD_E = 0;
LCD_D4 = command >> 4;
LCD_D5 = command >> 5;
LCD_D6 = command >> 6;
LCD_D7 = command >> 7;
LCD_E = 1;
LCD_E = 0;
LCD_D4 = command & 0x0F;
LCD_D5 = (command & 0x1F) << 1;
LCD_D6 = (command & 0x3F) << 2;
LCD_D7 = (command & 0x7F) << 3;
LCD_E = 1;
LCD_E = 0;
}
void lcd_write_data(unsigned char data) {
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 0;
LCD_D4 = data >> 4;
LCD_D5 = data >> 5;
LCD_D6 = data >> 6;
LCD_D7 = data >> 7;
LCD_E = 1;
LCD_E = 0;
LCD_D4 = data & 0x0F;
LCD_D5 = (data & 0x1F) << 1;
LCD_D6 = (data & 0x3F) << 2;
LCD_D7 = (data & 0x7F) << 3;
LCD_E = 1;
LCD_E = 0;
}
void lcd_init() {
/* 初始化LCD顯示屏 */
lcd_write_command(0x02); // 返回光標至起始位置
lcd_write_command(0x28); // 4位數據線,雙行,5x8字型
lcd_write_command(0x0C); // 顯示開,光標不顯示
lcd_write_command(0x06); // 文字在光標後插入,光標右移
lcd_write_command(0x01); // 清屏
delay(2); // 等待清屏完成
}
void lcd_puts(unsigned char row, unsigned char col, char str) {
/ 設置光標位置 */
if (row == 0) {
lcd_write_command(0x80 | col);
}
else {
lcd_write_command(0xC0 | col);
}
/* 顯示字符串 */
while (*str) {
lcd_write_data(*str++);
}
}
/* 七段顯示器函數 */
void seg_display(unsigned int num) {
unsigned char digit;
unsigned int div = 1000;
for (digit = 0; digit < 4; digit++) {
SEG_DP = (digit == 1);
SEG_A = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_B = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_C = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_D = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_E = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_F = (num / div == 0) ? 1 : 0;
num %= div;
div /= 10;
SEG_G = (num / div == 0) ? 1 : 0;
delay(1);
}
}
/* LED矩陣函數 */
void led_draw_matrix() {
unsigned char i, j;
for (i = 0; i < MATRIX_HEIGHT; i++) {
for (j = 0; j < MATRIX_WIDTH; j++) {
LED_CS = 0;
spi_send_byte(matrix[i][j]);
spi_send_byte(1 << j);
LED_CS = 1;
}
}
}
void spi_send_byte(unsigned char data) {
signed char i;
for (i = 7; i >= 0; i--) {
LED_CLK = 0;
LED_DIN = data & (1 << i);
LED_CLK = 1;
}
}
/*
/* 主程序 */
void main() {
unsigned char i, j;
unsigned int score = 0;
unsigned int level = 1;
unsigned char current_block_type = 0;
unsigned char current_block_rotation = 0;
unsigned char current_block_row = 0;
unsigned char current_block_col = 4;
unsigned char next_block_type = 0;
unsigned char next_block_rotation = 0;
unsigned char game_over = 0;
/* 初始化設備 */
lcd_init();
spi_init();
seg_display(0);
/* 顯示遊戲開始畫面 */
lcd_puts(0, 0, "Tetris");
lcd_puts(1, 0, "Press any key");
delay(1000);
/* 開始遊戲循環 */
while (!game_over) {
/* 顯示分數和等級 */
lcd_puts(0, 0, "Score:");
lcd_puts(1, 0, "Level:");
seg_display(score);
/* 生成下一塊方塊 */
current_block_type = next_block_type;
current_block_rotation = next_block_rotation;
current_block_row = 0;
current_block_col = 4;
next_block_type = rand() % NUM_BLOCK_TYPES;
next_block_rotation = rand() % NUM_ROTATIONS;
/* 檢查是否可以放置下一塊方塊 */
if (!check_block(current_block_type, current_block_rotation, current_block_row, current_block_col)) {
game_over = 1;
continue;
}
/* 顯示下一塊方塊 */
lcd_puts(0, 9, "Next:");
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (blocks[next_block_type][next_block_rotation][i][j]) {
matrix[2 + i][9 + j] = 1;
}
else {
matrix[2 + i][9 + j] = 0;
}
}
}
led_draw_matrix();
/* 下落方塊 */
while (check_block(current_block_type, current_block_rotation, current_block_row + 1, current_block_col)) {
current_block_row++;
draw_block(current_block_type, current_block_rotation, current_block_row, current_block_col);
led_draw_matrix();
delay(DELAY_TIME);
clear_block(current_block_type, current_block_rotation, current_block_row - 1, current_block_col);
led_draw_matrix();
}
/* 固定方塊 */
fix_block(current_block_type, current_block_rotation, current_block_row, current_block_col);
led_draw_matrix();
/* 消除已滿行 */
score += clear_lines();
if (score >= level * LEVEL_SCORE) {
level++;
}
}
/* 顯示遊戲結束畫面 */
lcd_puts(0, 0, "Game Over!");
lcd_puts(1, 0, "Score:");
seg_display(score);
delay(2000);
}
/* 函數:check_block() */
unsigned char check_block(unsigned char block_type, unsigned char rotation, unsigned char row, unsigned char col) {
unsigned char i, j;
/* 檢查方塊是否越界 */
if (row < 0 || row + BLOCK_ROWS > MATRIX_ROWS || col < 0 || col + BLOCK_COLS > MATRIX_COLS) {
return 0;
}
/* 檢查方塊是否重疊 */
for (i = 0; i < BLOCK_ROWS; i++) {
for (j = 0; j < BLOCK_COLS; j++) {
if (blocks[block_type][rotation][i][j] && matrix[row + i][col + j]) {
return 0;
}
}
}
return 1;
}
/* 函數:draw_block() */
void draw_block(unsigned char block_type, unsigned char rotation, unsigned char row, unsigned char col) {
unsigned char i, j;
for (i = 0; i < BLOCK_ROWS; i++) {
for (j = 0; j < BLOCK_COLS; j++) {
if (blocks[block_type][rotation][i][j]) {
matrix[row + i][col + j] = 1;
}
}
}
}
/* 函數:clear_block() */
void clear_block(unsigned char block_type, unsigned char rotation, unsigned char row, unsigned char col) {
unsigned char i, j;
for (i = 0; i < BLOCK_ROWS; i++) {
for (j = 0; j < BLOCK_COLS; j++) {
if (blocks[block_type][rotation][i][j]) {
matrix[row + i][col + j] = 0;
}
}
}
}
/* 函數:fix_block() */
void fix_block(unsigned char block_type, unsigned char rotation, unsigned char row, unsigned char col) {
unsigned char i, j;
for (i = 0; i < BLOCK_ROWS; i++) {
for (j = 0; j < BLOCK_COLS; j++) {
if (blocks[block_type][rotation][i][j]) {
matrix[row + i][col + j] = 1;
}
}
}
}
/* 函數:clear_lines() */
unsigned int clear_lines() {
unsigned char i, j;
unsigned int score = 0;
unsigned char line_count = 0;
for (i = 0; i < MATRIX_ROWS; i++) {
unsigned char line_full = 1;
for (j = 0; j < MATRIX_COLS; j++) {
if (!matrix[i][j]) {
line_full = 0;
break;
}
}
if (line_full) {
clear_line(i);
line_count++;
}
}
switch (line_count) {
case 1:
score += 100;
break;
case 2:
score += 300;
break;
case 3:
score += 500;
break;
case 4:
score += 800;
break;
}
return score;
}
/* 函數:clear_line() */
void clear_line(unsigned char row) {
unsigned char i, j;
for (i = row; i > 0; i--) {
for (j = 0; j < MATRIX_COLS; j++) {
matrix[i][j] = matrix[i - 1][j];
}
}
for (j =0; j < MATRIX_COLS; j++) {
matrix[0][j] = 0;
}
}
/* 函數:game_over() */
unsigned char game_over() {
unsigned char i, j;
for (i = 0; i < MATRIX_COLS; i++) {
if (matrix[0][i]) {
return 1;
}
}
return 0;
}
/* 函數:update_score() */
void update_score(unsigned int score) {
char str[16];
sprintf(str, "SCORE: %d", score);
lcd_puts(str, 0, 1);
}
/* 函數:update_level() */
void update_level(unsigned char level) {
char str[16];
sprintf(str, "LEVEL: %d", level);
lcd_puts(str, 9, 1);
}
/* 函數:update_speed() */
void update_speed(unsigned char speed) {
char str[16];
sprintf(str, "SPEED: %d", speed);
lcd_puts(str, 0, 2);
}
/* 函數:update_lines() */
void update_lines(unsigned int lines) {
char str[16];
sprintf(str, "LINES: %d", lines);
lcd_puts(str, 9, 2);
}
/* 函數:update_next() */
void update_next(unsigned char block_type, unsigned char rotation) {
unsigned char i, j;
for (i = 0; i < BLOCK_ROWS; i++) {
for (j = 0; j < BLOCK_COLS; j++) {
if (blocks[block_type][rotation][i][j]) {
lcd_set_pixel(j + 9, i + 4);
} else {
lcd_clr_pixel(j + 9, i + 4);
}
}
}
}
/* 函數:wait() */
void wait(unsigned int count) {
unsigned int i, j;
for (i = 0; i < count; i++) {
for (j = 0; j < 5000; j++);
}
}
/* 函數:random_block_type() */
unsigned char random_block_type() {
return rand() % BLOCK_TYPE_COUNT;
}
/* 函數:random_rotation() */
unsigned char random_rotation(unsigned char block_type) {
return rand() % block_rotation_count[block_type];
}
/* 函數:random_col() */
unsigned char random_col() {
return rand() % (MATRIX_COLS - BLOCK_COLS + 1);
}
/* 函數:game_init() */
void game_init() {
unsigned char i, j;
/* 初始化矩陣 */
for (i = 0; i < MATRIX_ROWS; i++) {
for (j = 0; j < MATRIX_COLS; j++) {
matrix[i][j] = 0;
}
}
/* 初始化隨機種子 */
srand(TICK_COUNT);
/* 初始化遊戲狀態 */
game_state = GAME_STATE_START;
/* 初始化方塊 */
current_block.type = random_block_type();
current_block.rotation = random_rotation(current_block.type);
current_block.row = 0;
current_block.col = random_col();
next_block.type = random_block_type();
next_block.rotation = random_rotation(next_block.type);
update_next(next_block.type, next_block.rotation);
/* 初始化分數 */
score = 0;
level = 1;
speed = SPEED_START;
lines = 0
/* 更新LCD顯示 */
lcd_cls();
update_score(score);
update_level(level);
update_speed(speed);
update_lines(lines);
draw_matrix();
}
/* 函數:game_start() */
void game_start() {
/* 重置遊戲狀態 */
game_init();
/* 遊戲主循環 */
while (1) {
switch (game_state) {
case GAME_STATE_START:
/* 遊戲開始 */
game_state = GAME_STATE_RUNNING;
break;
case GAME_STATE_RUNNING:
/* 遊戲進行中 */
game_tick();
break;
case GAME_STATE_OVER:
/* 遊戲結束 */
lcd_cls();
lcd_puts("GAME OVER", 4, 1);
lcd_puts("SCORE:", 2, 2);
lcd_putd(score, 8, 2);
while (1);
break;
}
}
}
/* 函數:main() */
void main() {
/* 初始化LCD */
lcd_init();
/* 開始遊戲 */
game_start();
}
以上就是STC90C52RC製作俄羅斯方塊遊戲的程式碼,涵蓋了遊戲的初始化、顯示、控制、碰撞檢測、消除行、計分等基本功能,可以進行遊戲的正常運行。 |
|