使用 Rust 開發一個貪喫蛇遊戲
貪喫蛇是一款經典的電子遊戲,深受一代又一代玩家的喜愛。這是一款簡單的遊戲,玩家在遊戲中控制一條蛇,當它喫東西時,它會變得越來越長,並試圖避免與牆壁或自己的身體相撞。在這篇文章中,我們將探索如何在 Rust 中使用 ncurses 庫創建一個貪喫蛇遊戲。
ncurses 是什麼?
ncurses 是一個用於在終端中創建基於文本的用戶界面 (gui) 的庫。它提供了一組功能,用於在屏幕上繪製字符和顏色、讀取鍵盤輸入和管理終端顯示。ncurses 可用於大多數類 unix 系統,包括 Linux 和 macOS。
創建項目
創建一個新的 Rust 項目:
cargo new snake --bin
接下來,將 ncurses 庫添加到 Cargo.toml 文件中:
[dependencies]
ncurses = "5.100.0"
現在,運行 cargo build 以下載 ncurses 庫並構建項目。
繪製蛇
爲了在屏幕上繪製蛇,我們將創建一個結構體來表示蛇的身體。我們將使用 LinkedList 來存儲蛇身體的每個部分的座標。
在 src/main.rs 中寫入如下代碼:
use std::collections::LinkedList;
struct Snake {
body: LinkedList<(i32, i32)>,
}
我們還將創建一個函數來在屏幕上繪製蛇。這個函數將遍歷蛇身體的每個部分,並在相應的位置繪製一個角色。
use ncurses::*;
fn draw_snake(snake: &Snake) {
for &(x, y) in &snake.body {
mvaddch(x, y, '@' as u32);
}
}
這裏,mvaddch 是一個 ncurses 庫函數,它將光標移動到指定位置,並將指定的字符添加到屏幕上。@字符用來表示蛇的身體。
移動蛇
爲了移動蛇,我們將在 snake 結構體中添加一個方向字段,表示蛇移動的方向。我們還將添加 move_forward 方法,該方法基於當前方向更新蛇身體每個部分的座標。
#[derive(Clone, Copy, PartialEq)]
enum Direction {
Left,
Right,
Up,
Down,
}
struct Snake {
body: LinkedList<(i32, i32)>,
direction: Direction,
}
impl Snake {
fn move_forward(&mut self) {
let (mut x, mut y) = *self.body.front().unwrap();
match self.direction {
Direction::Left => y -= 1,
Direction::Right => y += 1,
Direction::Up => x -= 1,
Direction::Down => x += 1,
}
self.body.push_front((x, y));
self.body.pop_back();
}
}
這裏,self.body.front().unwrap() 獲取蛇身體前部的座標。然後我們根據當前方向更新座標,並將新座標添加到身體前部,並刪除身體後部的座標。
接下來,我們將添加一個函數來處理鍵盤輸入,這個函數將根據方向鍵更新蛇的方向。
fn handle_input(snake: &mut Snake) {
let input = getch();
match input {
// 'a' 鍵
97 => {
snake.direction = Direction::Left
},
// 'd' 鍵
100 => {
snake.direction = Direction::Right
},
// 'w' 鍵
119 => {
snake.direction = Direction::Up
},
// 's' 鍵
115 => {
snake.direction = Direction::Down
},
_ => (),
}
}
這裏,getch 是一個 ncurses 庫函數,它等待鍵盤輸入並返回相應的鍵代碼。KEY_* 常量表示方向鍵。
貪喫蛇喫食物
impl Snake {
......
fn eat_food(&mut self, food: &mut Vec<(i32, i32)>) {
for (i, v) in food.clone().iter().enumerate() {
let head = *self.body.front().unwrap();
if head.0 == v.0 && head.1 == v.1 {
self.body.push_back(head);
food.remove(i);
break;
}
}
}
}
當貪喫蛇的頭部座標與食物座標一致時,貪喫蛇變長,即列表加一。同時刪除該食物。
創造遊戲循環
最後,我們將創建更新遊戲狀態並重新繪製屏幕的遊戲循環。
fn main() {
initscr();
noecho();
cbreak();
curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE);
// 貪喫蛇初始化
let mut snake = Snake {
body: LinkedList::from_iter(vec![(10, 10), (10, 9), (10, 8)]),
direction: Direction::Right,
};
// 食物初始化
let mut food = vec![(13, 13), (16, 8), (5, 20), (9, 30), (11, 40)];
loop {
clear();
draw_snake(&snake);
draw_food(&food);
handle_input(&mut snake);
snake.move_forward();
snake.eat_food(&mut food);
refresh();
napms(100);
}
// endwin();
}
這裏,initscr 函數用於初始化 ncurses 庫,noecho 函數用於禁用鍵回顯,cbreak 函數用於將終端設置爲 cbreak 模式,curs_set 函數用於設置光標可見性。
在遊戲循環中,我們首先使用 clear 清除屏幕,並使用我們之前定義的函數繪製貪喫蛇,然後處理輸入,移動貪喫蛇。Refresh 用於更新屏幕,napms 在繼續之前等待指定的毫秒數。
最後,我們使用 endwin 清理 ncurses 庫。
運行
執行 cargo build 後,進入 snake/target/debug 目錄,執行命令:
./snake
在鍵盤上按 w、s、a、d 健就可以上下左右移動貪喫蛇並可以貪喫食物了。
如圖:
總結
在這篇文章中,我們探討了如何在 Rust 中使用 ncurses 庫創建一個簡單的貪喫蛇遊戲。我們介紹了在屏幕上繪圖、處理輸入和創建遊戲循環的基礎知識。你現在應該對如何在 Rust 中使用 ncurses 庫創建簡單的 TUI 遊戲有了基本的瞭解。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/5UIMFFf67rAyfJQjq1sC2w