rust语言写的贪吃蛇游戏(代码片段)

福大大架构师每日一题 福大大架构师每日一题     2022-12-08     471

关键词:

首先新建工程,然后用vscode打开,命令如下:

cargo new snake --bin

文件结构如下:

Cargo.Toml文件内容如下:

[package]
name = "snake"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.4.6"
piston_window="0.74.0"
[profile.release]
opt-level = 0
lto = true
codegen-units = 1
panic = "abort"

src/draw.rs文件内容如下:

use piston_window::types::Color;
use piston_window::rectangle, Context, G2d;
const BLOCK_SIZE: f64 = 25.0;
pub fn to_coord(game_coord: i32) -> f64 
    (game_coord as f64) * BLOCK_SIZE

pub fn to_coord_u32(game_coord: i32) -> u32 
    to_coord(game_coord) as u32

pub fn draw_block(color: Color, x: i32, y: i32, con: &Context, g: &mut G2d) 
    let gui_x = to_coord(x);
    let gui_y = to_coord(y);
    rectangle(
        color,
        [gui_x, gui_y, BLOCK_SIZE, BLOCK_SIZE],
        con.transform,
        g,
    );

pub fn draw_rectangle(
    color: Color,
    x: i32,
    y: i32,
    width: i32,
    height: i32,
    con: &Context,
    g: &mut G2d,
) 
    let x = to_coord(x);
    let y = to_coord(y);
    rectangle(
        color,
        [
            x,
            y,
            BLOCK_SIZE * (width as f64),
            BLOCK_SIZE * (height as f64),
        ],
        con.transform,
        g,
    );


game.rs文件内容如下:

use crate::draw::draw_block, draw_rectangle;
use piston_window::types::Color;
use piston_window::*;
use rand::thread_rng, Rng;
use crate::snake::Direction, Snake;
const FOOD_COLOR: Color = [0.80, 0.00, 0.00, 1.0];
const BORDER_COLOR: Color = [0.80, 0.00, 0.00, 1.0];
const GAMEOVER_COLOR: Color = [0.90, 0.00, 0.00, 0.5];
const MOVING_PERIOD: f64 = 0.1;
const RESTART_TIME: f64 = 1.0;

pub struct Game 
    snake: Snake,
    food_exists: bool,
    food_x: i32,
    food_y: i32,
    width: i32,
    height: i32,
    game_over: bool,
    waiting_time: f64,

impl Game 
    pub fn new(width: i32, height: i32) -> Game 
        Game 
            snake: Snake::new(2, 2),
            food_exists: true,
            food_x: 6,
            food_y: 4,
            width,
            height,
            game_over: false,
            waiting_time: 0.0,
        
    
    pub fn key_pressed(&mut self, key: Key) 
        if self.game_over 
            return;
        
        let dir = match key 
            Key::Up => Some(Direction::Up),
            Key::Down => Some(Direction::Down),
            Key::Left => Some(Direction::Left),
            Key::Right => Some(Direction::Right),
            _ => None,
        ;
        if dir.unwrap() == self.snake.head_direction().opposite() 
            return;
        
        self.update_snake(dir);
    
    pub fn draw(&self, con: &Context, g: &mut G2d) 
        self.snake.draw(con, g);
        if self.food_exists 
            draw_block(FOOD_COLOR, self.food_x, self.food_y, con, g);
        
        draw_rectangle(BORDER_COLOR, 0, 0, self.width, 1, con, g);
        draw_rectangle(BORDER_COLOR, 0, self.height - 1, self.width, 1, con, g);
        draw_rectangle(BORDER_COLOR, 0, 0, 1, self.height, con, g);
        draw_rectangle(BORDER_COLOR, self.width - 1, 0, 1, self.height, con, g);
        if self.game_over 
            draw_rectangle(GAMEOVER_COLOR, 0, 0, self.width, self.height, con, g);
        
    
    pub fn update(&mut self, delta_time: f64) 
        self.waiting_time += delta_time;
        if self.game_over 
            if self.waiting_time > RESTART_TIME 
                self.restart();
            
            return;
        
        if !self.food_exists 
            self.add_food();
        
        if self.waiting_time > MOVING_PERIOD 
            self.update_snake(None);
        
    
    fn check_eating(&mut self) 
        let (head_x, head_y): (i32, i32) = self.snake.head_position();
        if self.food_exists && self.food_x == head_x && self.food_y == head_y 
            self.food_exists = false;
            self.snake.restore_tail();
        
    
    fn check_if_snake_alive(&self, dir: Option<Direction>) -> bool 
        let (next_x, next_y) = self.snake.next_head(dir);
        if self.snake.overlap_tail(next_x, next_y) 
            return false;
        
        next_x > 0 && next_y > 0 && next_x < self.width - 1 && next_y < self.height - 1
    
    fn add_food(&mut self) 
        let mut rng = thread_rng();
        let mut new_x = rng.gen_range(1, self.width - 1);
        let mut new_y = rng.gen_range(1, self.width - 1);
        while self.snake.overlap_tail(new_x, new_y) 
            new_x = rng.gen_range(1, self.width - 1);
            new_y = rng.gen_range(1, self.width - 1);
        
        self.food_x = new_x;
        self.food_y = new_y;
        self.food_exists = true;
    
    fn update_snake(&mut self, dir: Option<Direction>) 
        if self.check_if_snake_alive(dir) 
            self.snake.move_forward(dir);
            self.check_eating();
         else 
            self.game_over = true;
        
        self.waiting_time = 0.0;
    
    fn restart(&mut self) 
        self.snake = Snake::new(2, 2);
        self.waiting_time = 0.0;
        self.food_exists = true;
        self.food_x = 6;
        self.food_y = 4;
        self.game_over = false;
    


main.rs文件内容如下:

extern crate piston_window;
extern crate rand;
mod draw;
mod game;
mod snake;
use draw::to_coord_u32;
use game::Game;
use piston_window::types::Color;
use piston_window::*;
const BACK_COLOR: Color = [0.5, 0.5, 0.5, 1.0];
fn main() 
    //https://magiclen.org/rust-compile-optimize/
    let (width, height) = (30, 30);
    let mut window: PistonWindow =
        WindowSettings::new("Snake", [to_coord_u32(width), to_coord_u32(height)])
            .exit_on_esc(true)
            .build()
            .unwrap();
    let mut game = Game::new(width, height);
    while let Some(event) = window.next() 
        if let Some(Button::Keyboard(key)) = event.press_args() 
            game.key_pressed(key);
        
        window.draw_2d(&event, |c, g| 
            clear(BACK_COLOR, g);
            game.draw(&c, g);
        );
        event.update(|arg| 
            game.update(arg.dt);
        );
    


snake.rs文件内容如下:

use piston_window::types::Color;
use piston_window::Context, G2d;
use std::collections::LinkedList;

use crate::draw::draw_block;
const SNAKE_COLOR: Color = [0.00, 0.80, 0.00, 1.0];
#[derive(Copy, Clone, PartialEq)]
pub enum Direction 
    Up,
    Down,
    Left,
    Right,

impl Direction 
    pub fn opposite(&self) -> Direction 
        match *self 
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
            Direction::Left => Direction::Right,
            Direction::Right => Direction::Left,
        
    

#[derive(Debug, Clone)]
struct Block 
    x: i32,
    y: i32,

pub struct Snake 
    direction: Direction,
    body: LinkedList<Block>,
    tail: Option<Block>,

impl Snake 
    pub fn new(x: i32, y: i32) -> Snake 
        let mut body: LinkedList<Block> = LinkedList::new();
        body.push_back(Block  x: x + 2, y );
        body.push_back(Block  x: x + 1, y );
        body.push_back(Block  x, y );
        Snake 
            direction: Direction::Right,
            body,
            tail: None,
        
    
    pub fn draw(&self, con: &Context, g: &mut G2d) 
        for block in &self.body 
            draw_block(SNAKE_COLOR, block.x, block.y, con, g);
        
    
    pub fn head_position(&self) -> (i32, i32) 
        let head_block = self.body.front().unwrap();
        (head_block.x, head_block.y)
    
    pub fn move_forward(&mut self, dir: Option<Direction>) 
        match dir 
            Some(d) => self.direction = d,
            None => (),
        
        let (last_x, last_y): (i32, i32) = self.head_position();
        let new_block = match selfc语言之贪吃蛇(ncurses)(代码片段)

声明:以下内容可能会引起某些读者不适,请小心阅读.有些内容并没有详细介绍,可能简单理解也是错误的,但是这都是为了尽量简单。前言:代码是很久之前写的,属于边想边写的那种,很混乱。推荐材料:NCURSESProgrammingHOWTO贪吃... 查看详情

贪吃蛇(c语言实现)(代码片段)

文章目录游戏说明游戏效果展示游戏代码游戏代码详解游戏框架构建隐藏光标光标跳转初始化界面颜色设置初始化蛇随机生成食物打印蛇与覆盖蛇移动蛇游戏主体逻辑函数执行按键判断得分与结束从文件读取最高分更新最高分到... 查看详情

c语言实现《贪吃蛇》小游戏,代码分享+思路注释(代码片段)

...模式、赏金模式、挑战模式等多种玩法。本次我们将用C语言编写贪吃蛇游戏,效果如图所示:用游戏把子上下左右控制蛇的 查看详情

javascrip写的贪吃蛇

...好像就如同helloworld一样,简单又有代表性,以前我学习c语言的时候,第一个做的趣味小游戏也是贪吃蛇---------------------------------1//贪吃蛇的食物模块2(function(){3varelements=[]4//创建一个食物的构造函数5functionFood(x,y,width,height,color){6... 查看详情

c语言实现经典贪吃蛇游戏(代码片段)

原文链接:C语言贪吃蛇游戏文章目录一、说明二、效果2.1欢迎界面2.2游戏规则2.3得分排行2.4退出游戏2.5游戏界面2.6游戏结束三、源码3.1cmd.h3.2cmd.c3.3io.h3.4io.c3.5model.h3.6service.h3.7service.c3.8ui.h3.9ui.c3.10utils.h3.11utils.c3.12main.c一、说... 查看详情

html5+css+js贪吃蛇demo(代码片段)

我写博客的主要目的就是温习所学的知识,自己以前写的游戏当然不能放过!这款网页版贪吃蛇是大一下册学习网页前端时老师教我们写的,由于那个时候初学网页前端,所以这款游戏是纯原生JavaScript写的,没有使用JQuery。重... 查看详情

贪吃蛇二代——穿墙版(c语言实现)(代码片段)

文章目录游戏说明游戏效果展示游戏代码游戏代码详解游戏框架构建初始化界面隐藏光标光标跳转颜色设置初始化蛇随机生成食物打印蛇与覆盖蛇移动蛇游戏主体逻辑函数执行按键判断得分与结束从文件读取最高分更新最高分到... 查看详情

一条贪吃蛇的使命——零基础入门贪吃蛇游戏(代码片段)

零基础入门贪吃蛇游戏贪吃蛇是一款最常见、最经典、最受欢迎的小游戏之一。本篇文章带你零基础实现贪吃蛇游戏,一条蛇的使命从这里开始。1、游戏描述????贪吃蛇是一款非常经典的休闲类游戏。在一块固定大小的区域内,... 查看详情

c语言项目:贪吃蛇游戏(双人模式),详细思路+源码分享(代码片段)

每天一个C语言小项目,提升你的编程能力!贪吃蛇游戏大家都玩过,它的玩法也很简单:用游戏按键上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长&#x... 查看详情

一条贪吃蛇的使命——零基础入门贪吃蛇游戏(附演示地址)(代码片段)

零基础入门贪吃蛇游戏贪吃蛇是一款最常见、最经典、最受欢迎的小游戏之一。本篇文章带你零基础实现贪吃蛇游戏,一条蛇的使命从这里开始。演示地址:贪吃蛇演示,可能会提示危险操作,请忽略,放心访问。1、游戏描述??... 查看详情

汇编语言贪吃蛇游戏(代码片段)

...  废话就不多说了,之前那个贪吃蛇(【汇编语言】贪吃蛇游戏(一))使用的是阻塞式的16号中断。所以产生的现象就是,按键盘蛇才走,不按键盘蛇不走。就像魂斗罗那样子。这显然是不行的ÿ... 查看详情

c语言贪吃蛇(代码片段)

基于C语言编写的贪吃蛇开发环境:VS2019这是一个基于C语言链表开发的贪吃蛇游戏其实贪吃蛇游戏要解决的主要问题就是1、这个游戏的基本组成元素和架构2、如何初始化贪吃蛇并正常行走3、如何判断事件发生代码中运用到... 查看详情

自制贪吃蛇游戏中的几个“大坑”(代码片段)

  贪吃蛇游戏已经告一段落了,在完成这个游戏的过程中,我遭遇了许多“坎坷”和“挫折”,下面就几个让我印象深刻的“挫折”做一个具体的讲解,以此来为这个贪吃蛇项目画上一个完整句号。(包括打包这个游戏时遇到... 查看详情

c语言零基础项目:贪吃蛇!详细思路+源码分享(代码片段)

每天一个C语言小项目,提升你的编程能力!贪吃蛇游戏大家应该都不陌生了,要说没玩过的话,可能你是15后吧?贪吃蛇游戏最初为单机模式,后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。... 查看详情

汇编语言贪吃蛇游戏(代码片段)

  最近刚学完汇编,于是准备做个小游戏练练手。就瞅准了最最最老生常谈的贪吃蛇。  首先贪吃蛇必须是用户让蛇改变方向,蛇就得改变方向,吃到东西蛇会变长。  但我们不太可能一次性就做出来这么多功... 查看详情

gui简单实战——贪吃蛇(代码片段)

将前面学到的GUI基础知识完成实战,完成一个简单的贪吃蛇项目项目功能用键盘上下左右实现贪吃蛇的自动移动贪吃蛇吃到食物后,长度加一,分数加一贪吃蛇吃到自己的身体,则游戏结束按空格键实现游戏的暂停和继续效果截... 查看详情

linux环境下,基于ncurse图形库贪吃蛇小游戏(上)(代码片段)

...e图形库的贪吃蛇小游戏这个小游戏的意义?这个小游戏对C语言基础、数据结构链表基础、C变量、流程控制、函数、指针、结构体等有一个很好的知识汇总学习。也是对Linux基础操作的一个简单学习。linux环境下代码如何编写,... 查看详情

linux环境下,基于ncurse图形库贪吃蛇小游戏(上)(代码片段)

...e图形库的贪吃蛇小游戏这个小游戏的意义?这个小游戏对C语言基础、数据结构链表基础、C变量、流程控制、函数、指针、结构体等有一个很好的知识汇总学习。也是对Linux基础操作的一个简单学习。linux环境下代码如何编写,... 查看详情