贪吃蛇是一款经典的电子游戏,深受一代又一代玩家的喜爱。这是一款简单的游戏,玩家在游戏中控制一条蛇,当它吃东西时,它会变得越来越长,并试图避免与墙壁或自己的身体相撞。在这篇文章中,我们将探索如何在Rust中使用ncurses库创建一个贪吃蛇游戏。
cargo new snake --bin接下来,将ncurses库添加到Cargo.toml文件中:
[dependencies] ncurses = "5.100.0"现在,运行cargo build以下载ncurses库并构建项目。
use std::collections::LinkedList; struct Snake { body: LinkedList<(i32, i32)>, }我们还将创建一个函数来在屏幕上绘制蛇。这个函数将遍历蛇身体的每个部分,并在相应的位置绘制一个角色。
use ncurses::*; # 堆代码 duidaima.com fn draw_snake(snake: &Snake) { for &(x, y) in &snake.body { mvaddch(x, y, '@' as u32); } }这里,mvaddch是一个ncurses库函数,它将光标移动到指定位置,并将指定的字符添加到屏幕上。@字符用来表示蛇的身体。
#[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); // 堆代码 duidaima.com // 贪吃蛇初始化 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在继续之前等待指定的毫秒数。
./snake在键盘上按w、s、a、d健就可以上下左右移动贪吃蛇并可以贪吃食物了。