第13篇:综合实战——制作我的小游戏 Rust中文编程

第13篇:综合实战------制作我的小游戏

作者: 李金雨
联系方式: wbtm2718@qq.com
目标读者: Rust中文编程
核心理念: AI时代必须使用中文编程,母语编程阅读效率极高


1. 开篇引入

本课目标

  • 综合运用所学知识完成一个完整项目
  • 学习项目开发的基本流程
  • 掌握代码组织和文件管理
  • 理解数据持久化的方法
  • 培养解决问题的能力

生活场景引入

想象一下,你已经学会了如何使用各种工具来建造东西。现在,你要使用这些工具来建造一个完整的房子。在编程中,我们已经学习了各种基础知识,现在要使用这些知识来制作一个完整的游戏。

预期成果展示

通过这节课的学习,你将能够:

  • 选择一个适合的项目
  • 设计项目的结构
  • 实现项目的核心功能
  • 测试和调试项目
  • 完成一个完整的小游戏

2. 项目选择

项目A:文字冒险游戏

功能

  • 玩家输入名字开始游戏
  • 多个场景选择(森林、城堡、洞穴)
  • 遇到不同事件(战斗、宝藏、陷阱)
  • 生命值和金币系统
  • 存档读档功能

项目B:学生成绩管理系统

功能

  • 添加/删除/修改学生信息
  • 录入各科成绩
  • 自动计算总分和平均分
  • 成绩排序
  • 统计信息(及格率、优秀率)
  • 数据保存到文件

项目C:简易绘图程序

功能

  • 使用字符画绘制简单图形
  • 画各种图形(正方形、圆形、五角星)
  • 彩色输出
  • 循环绘制复杂图案
  • 交互式绘图(根据输入画不同图形)

3. 项目开发流程

1. 需求分析

首先,我们需要明确项目的需求,确定要实现哪些功能。

2. 设计数据结构

根据需求,设计合适的数据结构来存储数据。

3. 设计功能模块

将项目分解为多个功能模块,每个模块负责一个特定的功能。

4. 设计结构体和方法

设计合适的结构体和方法来实现功能。

5. 逐步实现

从核心功能开始,逐步实现所有功能。

6. 测试调试

测试项目,找出并修复bug。

7. 数据持久化

实现数据保存和读取功能。

8. 优化完善

添加细节,优化用户体验。

4. 项目实现示例:文字冒险游戏

1. 需求分析

我们要实现一个文字冒险游戏,包含以下功能:

  • 玩家输入名字开始游戏
  • 多个场景选择
  • 遇到不同事件
  • 生命值和金币系统
  • 存档读档功能

2. 设计数据结构

rust 复制代码
// 玩家结构体
struct 玩家 {
    姓名: String,
    生命值: i32,
    金币: i32,
    当前场景: 场景,
}

// 场景枚举
enum 场景 {
    森林,
    城堡,
    洞穴,
    结束,
}

// 事件枚举
enum 事件 {
    战斗,
    宝藏,
    陷阱,
    休息,
}

3. 设计功能模块

  • 游戏初始化模块
  • 场景管理模块
  • 事件处理模块
  • 玩家状态管理模块
  • 存档读档模块

4. 实现核心功能

rust 复制代码
use std::io;
use std::fs;

// 玩家结构体
struct 玩家 {
    姓名: String,
    生命值: i32,
    金币: i32,
    当前场景: 场景,
}

// 场景枚举
enum 场景 {
    森林,
    城堡,
    洞穴,
    结束,
}

// 事件枚举
enum 事件 {
    战斗,
    宝藏,
    陷阱,
    休息,
}

impl 玩家 {
    // 新建玩家
    fn 新(姓名: String) -> Self {
        Self {
            姓名,
            生命值: 100,
            金币: 0,
            当前场景: 场景::森林,
        }
    }
    
    // 显示状态
    fn 显示状态(&self) {
        println!("=== 玩家状态 ===");
        println!("姓名:{}", self.姓名);
        println!("生命值:{}", self.生命值);
        println!("金币:{}", self.金币);
        println!("当前场景:{:?}", self.当前场景);
        println!("================");
    }
    
    // 处理事件
    fn 处理事件(&mut self, 事件: 事件) {
        match 事件 {
            事件::战斗 => {
                println!("你遇到了一个怪物!");
                let 伤害 = 20;
                self.生命值 -= 伤害;
                println!("你受到了{}点伤害,剩余生命值:{}", 伤害, self.生命值);
                if self.生命值 <= 0 {
                    println!("你死了!游戏结束。");
                    self.当前场景 = 场景::结束;
                } else {
                    println!("你战胜了怪物!获得了10金币。");
                    self.金币 += 10;
                }
            },
            事件::宝藏 => {
                println!("你发现了一个宝藏!");
                let 金币 = 50;
                self.金币 += 金币;
                println!("你获得了{}金币,现在有{}金币。", 金币, self.金币);
            },
            事件::陷阱 => {
                println!("你踩到了陷阱!");
                let 伤害 = 30;
                self.生命值 -= 伤害;
                println!("你受到了{}点伤害,剩余生命值:{}", 伤害, self.生命值);
                if self.生命值 <= 0 {
                    println!("你死了!游戏结束。");
                    self.当前场景 = 场景::结束;
                }
            },
            事件::休息 => {
                println!("你休息了一会儿,恢复了生命值。");
                self.生命值 = 100;
                println!("生命值已恢复到:{}", self.生命值);
            },
        }
    }
    
    // 移动到新场景
    fn 移动(&mut self, 新场景: 场景) {
        self.当前场景 = 新场景;
        println!("你来到了{:?}。", self.当前场景);
    }
}

// 生成随机事件
fn 生成随机事件() -> 事件 {
    use rand::Rng;
    let mut rng = rand::thread_rng();
    let 随机数 = rng.gen_range(0..4);
    match 随机数 {
        0 => 事件::战斗,
        1 => 事件::宝藏,
        2 => 事件::陷阱,
        _ => 事件::休息,
    }
}

// 保存游戏
fn 保存游戏(玩家: &玩家) -> Result<(), io::Error> {
    let 数据 = format!("{},{},{},{:?}", 玩家.姓名, 玩家.生命值, 玩家.金币, 玩家.当前场景);
    fs::write("save.txt", 数据)
}

// 加载游戏
fn 加载游戏() -> Option<玩家> {
    match fs::read_to_string("save.txt") {
        Ok(数据) => {
            let 部分: Vec<&str> = 数据.split(',').collect();
            if 部分.len() != 4 {
                return None;
            }
            
            let 姓名 = 部分[0].to_string();
            let 生命值: i32 = 部分[1].parse().unwrap_or(100);
            let 金币: i32 = 部分[2].parse().unwrap_or(0);
            let 当前场景 = match 部分[3] {
                "森林" => 场景::森林,
                "城堡" => 场景::城堡,
                "洞穴" => 场景::洞穴,
                _ => 场景::森林,
            };
            
            Some(玩家 {
                姓名,
                生命值,
                金币,
                当前场景,
            })
        },
        Err(_) => None,
    }
}

fn main() {
    println!("欢迎来到文字冒险游戏!");
    
    // 尝试加载游戏
    let mut 玩家 = if let Some(加载的玩家) = 加载游戏() {
        println!("检测到存档,是否加载?(y/n)");
        let mut 输入 = String::new();
        io::stdin().read_line(&mut 输入).expect("读取失败");
        if 输入.trim().to_lowercase() == "y" {
            println!("加载存档成功!");
            加载的玩家
        } else {
            // 新建玩家
            println!("请输入你的名字:");
            let mut 姓名 = String::new();
            io::stdin().read_line(&mut 姓名).expect("读取失败");
            玩家::新(姓名.trim().to_string())
        }
    } else {
        // 新建玩家
        println!("请输入你的名字:");
        let mut 姓名 = String::new();
        io::stdin().read_line(&mut 姓名).expect("读取失败");
        玩家::新(姓名.trim().to_string())
    };
    
    // 游戏主循环
    while 玩家.当前场景 != 场景::结束 {
        玩家.显示状态();
        
        // 显示场景选项
        println!("\n你现在在{:?},你可以:", 玩家.当前场景);
        println!("1. 探索(可能遇到事件)");
        println!("2. 移动到其他场景");
        println!("3. 保存游戏");
        println!("4. 退出游戏");
        
        // 读取用户输入
        let mut 选择 = String::new();
        io::stdin().read_line(&mut 选择).expect("读取失败");
        let 选择 = 选择.trim();
        
        match 选择 {
            "1" => {
                // 探索,生成随机事件
                let 事件 = 生成随机事件();
                玩家.处理事件(事件);
            },
            "2" => {
                // 移动到其他场景
                println!("选择要去的场景:");
                println!("1. 森林");
                println!("2. 城堡");
                println!("3. 洞穴");
                
                let mut 场景选择 = String::new();
                io::stdin().read_line(&mut 场景选择).expect("读取失败");
                let 场景选择 = 场景选择.trim();
                
                match 场景选择 {
                    "1" => 玩家.移动(场景::森林),
                    "2" => 玩家.移动(场景::城堡),
                    "3" => 玩家.移动(场景::洞穴),
                    _ => println!("无效选择!"),
                }
            },
            "3" => {
                // 保存游戏
                if let Err(错误) = 保存游戏(&玩家) {
                    println!("保存失败:{}", 错误);
                } else {
                    println!("保存成功!");
                }
            },
            "4" => {
                // 退出游戏
                println!("再见!");
                break;
            },
            _ => println!("无效选择!"),
        }
        
        // 按回车键继续
        println!("\n按回车键继续...");
        let mut 输入 = String::new();
        io::stdin().read_line(&mut 输入).expect("读取失败");
    }
    
    println!("游戏结束!");
}

5. 测试调试

在实现过程中,我们需要不断测试和调试代码,确保游戏能够正常运行。

6. 数据持久化

我们使用文件来保存游戏数据,实现了存档和读档功能。

7. 优化完善

我们可以添加更多的场景和事件,使游戏更加丰富有趣。

5. 其他项目实现思路

项目B:学生成绩管理系统

核心数据结构

rust 复制代码
struct 学生 {
    姓名: String,
    年龄: i32,
    语文: i32,
    数学: i32,
    英语: i32,
}

impl 学生 {
    fn 总分(&self) -> i32 {
        self.语文 + self.数学 + self.英语
    }
    
    fn 平均分(&self) -> f64 {
        self.总分() as f64 / 3.0
    }
}

struct 学生管理系统 {
    学生们: Vec<学生>,
}

核心功能

  • 添加学生
  • 删除学生
  • 修改学生信息
  • 计算总分和平均分
  • 排序学生(按总分或某科成绩)
  • 统计信息(及格率、优秀率)
  • 保存和加载数据

项目C:简易绘图程序

核心功能

  • 绘制正方形
  • 绘制圆形
  • 绘制五角星
  • 绘制复杂图案
  • 彩色输出
  • 交互式绘图

实现思路

  • 使用字符画来表示图形
  • 使用循环来绘制重复的图案
  • 使用ANSI转义序列来实现彩色输出
  • 使用用户输入来控制绘图

6. 项目要求

  • 必须使用结构体来组织数据
  • 必须使用方法来实现功能
  • 数据必须保存到文件(实现存档功能)
  • 代码必须分模块组织(至少2个.rs文件)
  • 所有结构体名、函数名、变量名必须使用中文

7. 项目开发建议

  1. 从简单开始:先实现核心功能,然后逐步添加细节
  2. 分模块开发:将不同功能放在不同的模块中
  3. 测试驱动:边开发边测试,确保每个功能都能正常工作
  4. 数据持久化:实现数据的保存和读取功能
  5. 用户体验:添加适当的提示和反馈,使游戏更加友好

8. 知识总结

核心概念回顾

  • 项目开发流程:需求分析、设计、实现、测试、优化
  • 数据结构设计:根据需求设计合适的结构体
  • 功能模块分解:将项目分解为多个功能模块
  • 代码组织:使用模块来组织代码
  • 错误处理:处理可能的错误
  • 数据持久化:保存和读取数据
  • 用户交互:处理用户输入和输出

关键代码速查

功能 代码 说明
结构体定义 struct 结构体名 { 字段: 类型, ... } 定义结构体
方法实现 impl 结构体名 { fn 方法名(&self) {} } 为结构体实现方法
模块定义 mod 模块名 { 代码 } 定义模块
文件读写 fs::read_to_string(路径)fs::write(路径, 内容) 读取和写入文件
用户输入 io::stdin().read_line(&mut 输入) 读取用户输入
错误处理 match 结果 { Ok(值) => 处理, Err(错误) => 处理 } 处理可能的错误

常见错误提醒

  1. 文件路径:确保文件路径正确,避免文件读写错误
  2. 用户输入:处理用户的无效输入,避免程序崩溃
  3. 数据类型:确保数据类型正确,避免类型错误
  4. 边界条件:处理边界情况,避免逻辑错误
  5. 内存管理:注意Rust的所有权规则,避免内存错误

9. 课后作业

巩固练习题

  1. 选择一个项目,按照开发流程实现它
  2. 为项目添加新的功能,比如:
    • 为文字冒险游戏添加更多场景和事件
    • 为学生成绩管理系统添加更多统计功能
    • 为简易绘图程序添加更多图形

创意编程题

  1. 发挥你的创意,创建一个全新的项目,使用所学的Rust知识
  2. 与同学合作,开发一个更复杂的项目

恭喜你完成了第十三篇教程!你已经掌握了Rust的基本编程知识,并且学会了如何使用这些知识来制作一个完整的游戏。希望你在编程的道路上继续前进,创造更多有趣的作品!

学习交流

如果你在学习过程中遇到任何问题,欢迎联系我:

  • ** 视频号,"时空系"
  • 邮箱: wbtm2718@qq.com
  • 其他提示:
  • 本人正在开发纯中文编程语言和编译器,有兴趣的可以交流
  • 本人正在写一本基于中国母语思维习惯的数学教材,可以让你一年内学完从初中到研究生的数学,而且可以让你快速掌握人工智能的关键数学知识,有兴趣的可以交流

祝你学习愉快!

相关推荐
咸鱼咸鱼1 小时前
RustDesk 自建服务端教程:开源远程桌面,完全掌控你的数据
后端
CoderCodingNo2 小时前
【信奥业余科普】C++ 的奇妙之旅 | 19:内存的门牌号——地址与指针的设计原理
开发语言·c++
0xDevNull2 小时前
JDK多版本切换安装与配置
java·后端
@insist1232 小时前
信息安全工程师-物理隔离技术基础核心考点解析
开发语言·网络·安全·软考·信息安全工程师·软件水平考试
空中海2 小时前
02 状态、Hooks、副作用与数据流
开发语言·javascript·ecmascript
Aurorar0rua2 小时前
CS50 x 2024 Notes C - 09
c语言·开发语言·学习方法
兔小盈2 小时前
多线程篇-(二)线程创建、中断与终止
java·开发语言·多线程
Java编程爱好者2 小时前
1-5 线程池:Thread+阻塞队列+循环
后端
jnrjian2 小时前
Library Cache Load Lock library cache pins are replaced by mutexes
java·后端·spring