godot-rust(gdext)2D游戏之旅【flappy-bird】 - 2

简介

本文以Make Flappy Bird Game in Godot Engine | gameidea为蓝本撰写。如果你对rust、godot等内容比较生疏或感到疑惑,可以先阅读godot-rust入门文档

本文搭建在godot-rust(gdext)创建项目的基础之上,如果你对该部分内容感到生疏,可以先阅读这部分内容,为接下来的操作做好准备。

注意,本文使用的godot版本为4.6.2,godot版本的变化可能会导致一些内容失效

本文所有操作均在Windows11环境下进行。

正文

创建Pipes

在rust中创建Pipe节点

rust 复制代码
// pipe.rs
use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base=Node2D)]
struct Pipe {}

执行cargo build

在godot中新建你刚刚创建的Pipe节点,并保存在你的Pipe文件夹下。

Pipe节点添加三个子节点Area2D,分别命名为PipeTopPipeBottomScoreArea,并向这三个子节点各添加一个CollisionShape2D子节点,并均用RectangleShape2D来表示CollisionShape2DShape

到编辑界面拖动三个子节点位置和形状,使之符合我们的游戏需求。

从上往下的顺序依次是:

  • PipeTop
  • ScoreArea
  • PipeBottom

上下碰撞检测游戏是否失败,中间碰撞用于检测游戏是否得分。

Pipe添加4个Sprite2D子节点,名称分别为Pipe1Pipe2Pipe3Pipe4,用assert 文件夹下的pipe.png 填充为Texture ,将Sprite2D分别摆放到适合的位置。

现在来丰富rust的Pipe代码

rust 复制代码
// pipe.rs
use godot::{
    classes::{Area2D, CollisionShape2D},
    prelude::*,
};

#[derive(GodotClass)]
#[class(init, base=Node2D)]
pub struct Pipe {
    base: Base<Node2D>,

    #[init(node = "PipeTop")]
    pipe_top: OnReady<Gd<Area2D>>,

    #[init(node = "PipeBottom")]
    pipe_bottom: OnReady<Gd<Area2D>>,

    #[init(node = "ScoreArea")]
    score_area: OnReady<Gd<Area2D>>,

    #[init(val = 150.0)]
    scroll_speed: real,
}

#[godot_api]
impl Pipe {
    #[signal]
    pub fn scored();

    #[signal]
    pub fn hit();

    fn on_pipe_body_entered(&mut self, _pipe: Gd<Node2D>) {
        self.signals().hit().emit();
    }

    fn on_score_area_body_entered(&mut self, _pipe: Gd<Node2D>) {
        self.signals().scored().emit();
        self.score_area
            .get_node_as::<CollisionShape2D>("CollisionShape2D")
            .set_deferred("disabled", &true.to_variant());
    }

    pub fn set_scroll_speed(&mut self, speed: real) {
        self.scroll_speed = speed;
    }
}

#[godot_api]
impl INode2D for Pipe {
    fn ready(&mut self) {
        self.pipe_top
            .signals()
            .body_entered()
            .connect_other(&*self, Self::on_pipe_body_entered);

        self.pipe_bottom
            .signals()
            .body_entered()
            .connect_other(&*self, Self::on_pipe_body_entered);

        self.score_area
            .signals()
            .body_entered()
            .connect_other(&*self, Self::on_score_area_body_entered);
    }

    fn process(&mut self, delta: f32) {
        let mut position = self.base().get_position();

        position.x -= self.scroll_speed * delta;

        self.base_mut().set_position(position);

        if position.x < -150.0 {
            self.base_mut().queue_free();
        }
    }
}

你一定有一个疑惑,这个Pipe到底需要多长?多大?原文没有详细写,这需要我们自己调整一下,回到godot 中,手动增加管道Sprite2D贴图的个数,使用鼠标和transform属性配合调整到合适的大小,这里我给一个图片作为参考

紫色矩形是窗口大小,记得管道中间要留出足够空间让Bird可以通过。

参考

  1. godot-rust(gdext)创建项目 - 掘金
  2. godot - Rust
  3. Make Flappy Bird Game in Godot Engine | gameidea
相关推荐
漫友也是程序猿13 小时前
ddraw.dll异常排查:旧游戏图形接口、兼容性模式和DirectX组件检查
程序人生·游戏·电脑
远程软件小助理18 小时前
ToDesk节点繁忙、向日葵免费试用受限,还有什么免费好用的远程软件推荐?
经验分享·游戏·远程工作
德迅--文琪18 小时前
游戏盾筑牢网络游戏防攻击安全防线
安全·游戏
Rauser Mack21 小时前
不懂编程,但是vibe coding一个扫雷游戏
人工智能·python·游戏·html·prompt
winlife_1 天前
全程用 AI 做一款商业级手游 · EP10 道具系统:让三个按钮真正改变棋盘
windows·算法·unity·ai编程·游戏开发·mcp·玩法系统
SmalBox1 天前
【节点】[VoronoiNoise节点]原理解析与实际应用
unity3d·游戏开发·图形学
小雨下雨的雨1 天前
数独算法与求解器鸿蒙PC Electron框架完成深度解析
javascript·人工智能·算法·游戏·华为·electron·鸿蒙系统
Swift社区1 天前
鸿蒙游戏自动测试:AI 驱动的测试方案实战
人工智能·游戏·harmonyos
jinxindeep1 天前
CVPR26最佳论文提名:NitroGen,面向通用游戏智能体的 视觉-动作基础模型
人工智能·游戏
海兰1 天前
【水浒传:第二篇】AI江湖 —项目详细设计指南(一)
jvm·人工智能·游戏