冰楓論壇

 找回密碼
 立即註冊
ads_sugarbook
搜索
查看: 494|回覆: 0
打印 上一主題 下一主題

[討論] STC90C52RC製作俄羅斯方塊遊戲

[複製鏈接]

2609

主題

0

好友

945

積分

高級會員

Rank: 4

UID
373967
帖子
7423
主題
2609
精華
0
積分
945
楓幣
1101
威望
925
存款
26000
贊助金額
0
推廣
0
GP
1205
閱讀權限
50
在線時間
407 小時
註冊時間
2023-1-12
最後登入
2024-5-2

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-6 06:47:08 |只看該作者 |倒序瀏覽
以下是一個使用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製作俄羅斯方塊遊戲的程式碼,涵蓋了遊戲的初始化、顯示、控制、碰撞檢測、消除行、計分等基本功能,可以進行遊戲的正常運行。
收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1骰子
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們職位招聘本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-5-2 15:45

回頂部