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
相关推荐
SmalBox1 天前
【节点】[OneMinus节点]原理解析与实际应用
unity3d·游戏开发·图形学
学会去珍惜1 天前
学会C语言可以做什么
c语言·网络编程·游戏开发·嵌入式系统·系统编程
上海云盾-小余1 天前
BGP 高防与普通高防差异解析:游戏与政企业务该如何选型
游戏
_Evan_Yao1 天前
当 if 成为性能判官:分支预测、流水线冲刷与 Java 中的“猜谜游戏”
人工智能·游戏
魔士于安1 天前
Unity windows 同步 异步 打开文件文件夹工具
游戏·unity·游戏引擎·贴图·模型
魔士于安1 天前
unity lowpoly 风格 城市 建筑 道路 交通标志
游戏·unity·游戏引擎·贴图·模型
^—app5668661 天前
短剧游戏APP广告联盟SDK类型模块调用源代码
游戏
chushiyunen1 天前
pygame实现射击游戏
python·游戏·pygame
开开心心就好1 天前
支持批量添加水印的实用工具推荐
人工智能·游戏·ci/cd·docker·音视频·语音识别·媒体
黑客说1 天前
2026 AI 游戏热度排行榜|游戏推荐
人工智能·科技·游戏·娱乐