- UID
- 373967
- 帖子
- 8822
- 主題
- 2609
- 精華
- 0
- 積分
- 994
- 楓幣
- 0
- 威望
- 971
- 存款
- 34510
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 50
- 在線時間
- 452 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-11-12
|
ATmega8L 貪食蛇遊戲程式碼。
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
// 定義顯示器引腳
#define DISPLAY_PORT PORTB
#define DISPLAY_DDR DDRB
// 定義按鈕引腳
#define BUTTON_PIN PINC
#define BUTTON_DDR DDRC
#define BUTTON_LEFT PC0
#define BUTTON_RIGHT PC1
#define BUTTON_UP PC2
#define BUTTON_DOWN PC3
// 定義蛇和食物
#define MAX_SNAKE_LENGTH 16
struct snake_t {
uint8_t x[MAX_SNAKE_LENGTH];
uint8_t y[MAX_SNAKE_LENGTH];
uint8_t length;
uint8_t direction;
};
struct food_t {
uint8_t x;
uint8_t y;
};
// 定義遊戲狀態
#define GAME_STATE_PLAYING 0
#define GAME_STATE_GAMEOVER 1
uint8_t game_state = GAME_STATE_PLAYING;
// 定義計時器
volatile uint32_t timer = 0;
// 7段顯示器字型
uint8_t font[] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
};
// 初始化顯示器
void setup_display()
{
// 設置顯示器引腳為輸出
DISPLAY_DDR = 0xFF;
}
// 顯示一個數字
void display_number(uint8_t number)
{
// 設置顯示器引腳狀態
DISPLAY_PORT = font[number % 10];
// 等待一段時間,以避免閃爍
_delay_ms(2);
// 關閉顯示器
DISPLAY_PORT = 0x00;
}
// 初始化按鈕
void setup_buttons()
{
// 設置按鈕引腳為輸入,啟用內部上拉電阻
BUTTON_DDR &= ~(1 << BUTTON_LEFT) & ~(1 << BUTTON_RIGHT) & ~(1
<< BUTTON_UP) & ~(1 << BUTTON_DOWN);
BUTTON_PIN |= (1 << BUTTON_LEFT) | (1 << BUTTON_RIGHT) | (1 << BUTTON_UP) | (1 << BUTTON_DOWN);
}
// 檢查按鈕狀態
uint8_t check_button(uint8_t button)
{
return !(BUTTON_PIN & (1 << button));
}
// 初始化計時器
void setup_timer()
{
// 設置計時器0為CTC模式,64分頻
TCCR0 |= (1 << WGM01) | (1 << CS01) | (1 << CS00);
// 設置計時器比較值
OCR0 = 250;
// 啟用計時器比較中斷
TIMSK |= (1 << OCIE0);
}
// 計時器中斷處理
ISR(TIMER0_COMP_vect)
{
// 每4ms增加計時器
timer += 4;
}
// 初始化蛇
void init_snake(struct snake_t* snake)
{
// 蛇的初始長度為3,初始位置為(4, 4)
snake->length = 3;
snake->direction = 0;
snake->x[0] = 4;
snake->y[0] = 4;
snake->x[1] = 3;
snake->y[1] = 4;
snake->x[2] = 2;
snake->y[2] = 4;
}
// 顯示蛇
void display_snake(struct snake_t* snake)
{
for (uint8_t i = 0; i < snake->length; i++) {
// 計算在顯示器上的位置
uint8_t x = snake->x[i] + 1;
uint8_t y = snake->y[i] + 1;
// 設置顯示器引腳狀態
DISPLAY_PORT = 1 << x;
_delay_ms(2);
DISPLAY_PORT = 1 << y;
_delay_ms(2);
}
}
// 移動蛇
void move_snake(struct snake_t* snake, struct food_t* food)
{
// 計算新的頭部位置
uint8_t new_x = snake->x[0];
uint8_t new_y = snake->y[0];
switch (snake->direction) {
case 0: // 向右移動
new_x++;
break;
case 1: // 向上移動
new_y--;
break;
case 2: // 向左移動
new_x--;
break;
case 3: // 向下移動
new_y++;
break;
}
// 檢查是否吃到食物
if (new_x == food->x && new_y == food->y) {
// 食物位置改變
food->x = rand() % 6 + 1;
food->y = rand() % 6 + 1;
// 蛇長度增加
snake->length++;
// 檢查是否達到最大長度
if (snake->length > MAX_SNAKE_LENGTH
// 遊戲結束
game_over();
return;
}
}
// 移動蛇的身體
for (uint8_t i = snake->length - 1; i > 0; i--) {
snake->x[i] = snake->x[i - 1];
snake->y[i] = snake->y[i - 1];
}
// 移動蛇的頭部
snake->x[0] = new_x;
snake->y[0] = new_y;
// 檢查是否碰到自己
for (uint8_t i = 1; i < snake->length; i++) {
if (snake->x[0] == snake->x[i] && snake->y[0] == snake->y[i]) {
// 遊戲結束
game_over();
return;
}
}
}
// 初始化食物
void init_food(struct food_t* food)
{
// 隨機選擇食物位置
food->x = rand() % 6 + 1;
food->y = rand() % 6 + 1;
}
// 顯示食物
void display_food(struct food_t* food)
{
// 計算在顯示器上的位置
uint8_t x = food->x + 1;
uint8_t y = food->y + 1;
// 設置顯示器引腳狀態
DISPLAY_PORT = 1 << x;
_delay_ms(2);
DISPLAY_PORT = 1 << y;
_delay_ms(2);
}
// 初始化遊戲
void init_game()
{
// 初始化隨機數生成器
srand(timer);
// 初始化按鈕和顯示器
setup_io();
// 初始化計時器
setup_timer();
// 初始化蛇和食物
init_snake(&snake);
init_food(&food);
}
// 遊戲主循環
void game_loop()
{
while (1) {
// 檢查按鈕狀態,改變蛇的方向
if (check_button(BUTTON_LEFT)) {
snake.direction = 2;
} else if (check_button(BUTTON_RIGHT)) {
snake.direction = 0;
} else if (check_button(BUTTON_UP)) {
snake.direction = 1;
} else if (check_button(BUTTON_DOWN)) {
snake.direction = 3;
}
// 移動蛇和顯示
move_snake(&snake, &food);
display_snake(&snake);
display_food(&food);
// 等待一段時間
_delay_ms(250);
}
}
int main(void)
{
// 初始化遊戲
init_game();
kotlin
Copy code
// 遊戲主循環
game_loop();
return 0;
}
其中,這個程式碼的核心是 move_snake 函數,它接收蛇和食物的指針,檢查蛇是否碰到邊界或食物,更新蛇的位置,並檢查蛇是否碰到自己。其他函數,如 init_snake、init_food、display_snake 和 display_food,用於初始化蛇和食物,以及在顯示器上顯示它們。 |
|