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
相关推荐
SmalBox3 小时前
02-05-原理篇-资源加载与缓存机制
unity3d·游戏开发
林川~0114 小时前
Unity 万能物理检测工具:射线检测 / 范围检测 / 层级过滤 / 编辑器可视化(可直接拿去用)
游戏·unity·c#·射线检测·通用工具
SmalBox16 小时前
02-04-原理篇-资源组织与依赖分析
unity3d·游戏开发
Huanzhi_Lin1 天前
从0搭建ECS:跨品类评估
架构·游戏开发·ecs·ecs跨品类评估
甲维斯1 天前
《钢铁洪流》开发笔记:AI策略升级!
人工智能·游戏开发
贾伟康1 天前
【HarmonyOS 7新能力|038】游戏快启工程封装:把接入逻辑放进可维护的分层结构
性能优化·harmonyos·arkts·游戏开发·软件架构
一孤程2 天前
游戏测试专题第七篇:游戏自动化测试实战
游戏·测试
一孤程2 天前
游戏测试专题第八篇:游戏安全测试与反外挂
游戏·测试
SmalBox2 天前
02-03-原理篇-资源打包流程详解
unity3d·游戏开发
UWA2 天前
让UE性能分析真正穿透指标:GPU看堆栈,Texture拆到Group
性能优化·游戏开发