Rust 语言从入门到实战
唐刚
Rust 语言中文社区联合创始人
5266 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Rust 语言从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

27|Rust Bevy游戏开发:用300行代码做一个贪吃蛇游戏

你好,我是 Mike。今天我们一起来学习 Rust 游戏编程技术。这节课我们会基于 Bevy 游戏框架来开发一个入门版的贪吃蛇游戏。
Rust 生态内目前已经有不少很不错的游戏开发框架,而 Bevy 是其中最热门的那一个,目前(2023 年 12 月)最新版本是 0.12,还处在积极开发的过程中。Bevy 框架和 Axum Web 框架、Slint 框架给人的感觉有点儿像,都很简单、优美、灵活。用 Bevy 框架写游戏非常惬意,已经有不少人在尝试使用 Bevy 开发自己的独立游戏,目前有三款(Molecoole、Tiny Glade、Roids)已经上架或即将上架 Steam。
用 Bevy 开发的游戏能够运行在 Windows、macOS、Linux, Web 浏览器等平台。

Bevy 框架

Bevy 框架是一个数据驱动的游戏开发框架(引擎),其核心是一个 ECS。

ECS

ECS 是 Entity Component System 的缩写,意思是实体 - 组件 - 系统。它是一种编程范式,这种范式非常有趣,也非常有潜力,现在的主流游戏引擎都开始支持这种编程范式了。这种范式是与传统的 OOP(面向对象编程)范式相对的,跟 Rust 的 trait 的设计理念有一些相似之处。
我们用一个例子来说明 ECS 是怎样对问题进行建模的。假如现在有这样一幅画面:一个下午,在温暖的家里面,爸爸 D 正在边吃甜点边看书,妈妈 M 在边吃甜点边玩手机,儿子 S 在和狗狗 B 玩。你想一想,这个场景如果用 OOP 方式,应该如何建模呢?而用 ECS 范式可以这样建立模型:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

使用Rust语言和Bevy游戏框架开发贪吃蛇游戏的技术细节。文章首先介绍了Bevy框架的特点,包括其基于ECS的设计范式、资源管理、事件处理、世界状态维护、固定帧率和坐标系统等。通过实战贪吃蛇游戏的步骤,展示了如何引入Bevy库、创建窗口、绘制蛇的头等具体操作。在具体步骤中,作者介绍了如何让蛇动起来、控制蛇的方向、将窗口网格化、让蛇按网格移动、配置窗口比例和尺寸、随机产生食物以及使用定时器产生食物。接着,文章详细介绍了如何定义蛇的身体、让蛇身跟随蛇头移动、处理蛇吃食物并长大的效果。通过简洁的代码示例和清晰的解释,读者可以快速了解Rust游戏开发的基本原理和实践方法。整体而言,本文通过实际案例向读者展示了使用Rust和Bevy框架开发游戏的全过程,为对游戏开发感兴趣的读者提供了宝贵的参考和学习资源。文章还提到了撞墙和自身Game Over的处理,以及对Bevy游戏引擎的基本使用方式和ECS系统的重要性。同时,作者鼓励读者通过编写小游戏来提升建模能力,展示了游戏开发的乐趣和技术挑战。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Rust 语言从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • NiceBlueChai
    还有个bug,向上走的过程中快速按左下(或者右下),蛇直接原地向相反方向走了

    作者回复: 哈哈,真的是。🤔👍👍

    2024-01-29归属地:山东
  • seven9t
    补充了个最起码的长按加速功能,没找到timer的就地调频接口,只能另开了个timer做切换。各位有啥更好办法么。

    作者回复: 非常强的动手能力👍👍

    2024-01-21归属地:广东
  • unistart
    BUG: 食物可能在蛇身上产生 处理: 在生成食物的时候,判断一下随机生成的Position值是否和当前蛇的某一个部分位置是重合的,如果是就直接return,不生成食物。 // 修改food_spawner fn food_spawner( mut commands: Commands, time: Res<Time>, mut timer: ResMut<FoodSpawnTimer>, segment_pos_set: Query<&Position, With<SnakeSegment>> ) { // ... let rand_x: i32 = (random::<f32>() * ARENA_WIDTH as f32) as i32; let rand_y: i32 = (random::<f32>() * ARENA_HEIGHT as f32) as i32; for pos in segment_pos_set.iter() { if pos.x == rand_x && pos.y == rand_y { return; } } // ... .insert(Position { x: rand_x, y: rand_y, }) // ... } BUG: 食物有可能在已经产生过的地方产生 个人感觉这个不太算bug吧,分两种情况看,一种是食物A之前被吃过,又在相同的位置生成了新的食物,这个应该是没问题的;另一种就是食物A之前没有被吃过,同时新生成的食物B的位置和食物A重合,这样确实貌似有问题。 但是我不知道Bevy是如何处理的,按我的理解来说食物B应该会盖掉食物A,即某一位置只会有一个最新的食物实体。还是说bevy中出现这种情况,同一位置会有多个实体。如果是同一位置有多个实体的话,那么再Query一下已经生成的Food的Position,然后和新生成的食物坐标比较一下是否有出现的重合就行了吧。

    作者回复: 非常棒的思考 👍. 要判断食物位置是否重合的话, 需要用一个结构来维护食物的 Positions, 将其设定为 Resource. 在最新一篇总结更新中会讲到这个问题.

    2023-12-30归属地:湖南
    2
  • 大白菜🥬
    14步那里需要添加LastTailPosition资源, App需要添加 .insert_resource(LastTailPosition::default())

    作者回复: 对的对的

    2023-12-27归属地:重庆
  • 十八哥
    当年用vb.net用了1千行实现的。思路是按钮数组,一个二维数组。

    作者回复: 不错的思路。

    2023-12-26归属地:天津
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部