当前位置: 首页 > article >正文

Godot实战(一)—— 用C#构建2D躲避游戏的核心机制

1. 环境准备与项目初始化第一次打开Godot引擎时那个简洁的界面可能会让你有点不知所措。别担心我们一步步来。点击New Project按钮给你的游戏项目起个名字比如DodgeTheCreeps。建议专门创建一个空文件夹来存放项目文件这样管理起来更方便。在项目设置中有几个关键参数需要调整进入Project - Project Settings找到Display - Window选项卡将Width设为480Height设为720在Stretch选项中Mode选择2dAspect选择keep这些设置确保了游戏在不同尺寸的屏幕上都能保持正确的比例。我刚开始用Godot时经常忽略这个步骤结果游戏在不同设备上显示效果千奇百怪后来才发现是这里没设置好。2. 创建玩家角色2.1 构建玩家场景在Scene面板中我们首先需要创建一个Area2D节点作为玩家角色的根节点。为什么选择Area2D而不是Sprite因为Area2D可以检测碰撞这对我们的躲避游戏至关重要。接下来添加这些子节点AnimatedSprite - 用于显示角色动画CollisionShape2D - 定义碰撞区域设置AnimatedSprite时我建议先准备好角色素材。你可以自己绘制简单的角色动画或者使用网上找到的免费素材。记得把Scale设为(0.5, 0.5)这样角色大小更合适。2.2 编写玩家移动代码玩家控制是游戏的核心我们使用C#来实现。创建一个Player.cs脚本核心代码如下[Export] public int Speed 400; // 玩家移动速度 public override void _Process(double delta) { var velocity Vector2.Zero; if (Input.IsActionPressed(move_right)) velocity.X 1; if (Input.IsActionPressed(move_left)) velocity.X - 1; if (Input.IsActionPressed(move_down)) velocity.Y 1; if (Input.IsActionPressed(move_up)) velocity.Y 1; if (velocity.Length() 0) { velocity velocity.Normalized() * Speed; GetNodeAnimatedSprite(AnimatedSprite).Play(); } else { GetNodeAnimatedSprite(AnimatedSprite).Stop(); } Position velocity * (float)delta; Position new Vector2( Mathf.Clamp(Position.x, 0, ScreenSize.x), Mathf.Clamp(Position.y, 0, ScreenSize.y) ); }这段代码实现了基本的WASD或方向键控制。Normalized()确保斜向移动时速度不会叠加Clamp()则防止角色跑出屏幕。3. 敌人生成系统3.1 创建敌人场景敌人我们使用RigidBody2D作为根节点这样可以利用物理引擎的特性。关键设置包括将Gravity Scale设为0敌人就不会下落取消勾选Mask属性的第一个框防止敌人互相碰撞添加VisibilityNotifier2D用于敌人离开屏幕时自动销毁敌人的动画可以多样化一些比如添加fly、swim、walk三种动画类型。在代码中随机选择一种public override void _Ready() { var animSprite GetNodeAnimatedSprite(AnimatedSprite); string[] mobTypes animSprite.Frames.GetAnimationNames(); animSprite.Animation mobTypes[GD.Randi() % mobTypes.Length]; }3.2 敌人生成逻辑在主场景中我们使用Path2D和PathFollow2D来生成敌人。这个设计很巧妙Path2D定义生成路径PathFollow2D可以在路径上随机定位。关键代码public void OnMobTimerTimeout() { var mob (Mob)MobScene.Instance(); var mobSpawnLocation GetNodePathFollow2D(MobPath/MobSpawnLocation); mobSpawnLocation.Offset GD.Randi(); float direction mobSpawnLocation.Rotation Mathf.Pi / 2; direction (float)GD.RandRange(-Mathf.Pi / 4, Mathf.Pi / 4); mob.Position mobSpawnLocation.Position; mob.Rotation direction; var velocity new Vector2((float)GD.RandRange(150.0, 250.0), 0); mob.LinearVelocity velocity.Rotated(direction); AddChild(mob); }这里有几个值得注意的点使用GD.Randi()实现随机位置方向计算考虑了路径的切线方向速度也加入了随机性让游戏更有趣4. 碰撞检测与游戏逻辑4.1 玩家碰撞处理当敌人碰到玩家时我们需要触发游戏逻辑。在Player.cs中添加[Signal] public delegate void Hit(); public void OnPlayerBodyEntered(PhysicsBody2D body) { Hide(); EmitSignal(nameof(Hit)); GetNodeCollisionShape2D(CollisionShape2D).SetDeferred(disabled, true); }这里使用了Godot的信号系统当碰撞发生时发出Hit信号。SetDeferred确保在物理回调中安全地修改碰撞属性。4.2 游戏状态管理主场景需要管理游戏状态包括开始、结束和计分public void NewGame() { Score 0; var player GetNodePlayer(Player); player.Start(GetNodePosition2D(StartPosition).Position); GetNodeTimer(StartTimer).Start(); GetTree().CallGroup(mobs, queue_free); } public void GameOver() { GetNodeTimer(MobTimer).Stop(); GetNodeTimer(ScoreTimer).Stop(); }NewGame()会重置分数、玩家位置并清除所有现存敌人。GameOver()则停止所有计时器。5. 用户界面实现5.1 HUD设计使用CanvasLayer创建游戏UI包含以下元素分数显示(ScoreLabel)游戏消息(Message)开始按钮(StartButton)关键功能实现public async void ShowGameOver() { ShowMessage(Game Over); await ToSignal(GetNodeTimer(MessageTimer), timeout); GetNodeLabel(Message).Text Dodge the\nCreeps!; GetNodeLabel(Message).Show(); await ToSignal(GetTree().CreateTimer(1), timeout); GetNodeButton(StartButton).Show(); }这个异步方法实现了游戏结束时的UI流程显示Game Over - 短暂等待 - 显示标题 - 显示开始按钮。5.2 分数系统分数系统由ScoreTimer驱动每秒增加1分public void OnScoreTimerTimeout() { Score; GetNodeHUD(HUD).UpdateScore(Score); }HUD的UpdateScore方法简单更新Label文本public void UpdateScore(int score) { GetNodeLabel(ScoreLabel).Text score.ToString(); }6. 游戏测试与优化完成所有功能后我们需要进行测试。点击编辑器右上角的Play按钮选择Main.tscn作为主场景。测试时注意以下几点玩家移动是否流畅敌人生成位置是否合理碰撞检测是否准确游戏状态转换是否正确如果发现敌人生成太密集可以调整MobTimer的Wait Time属性。游戏难度也可以通过修改敌人速度范围来调整。7. 常见问题解决在实际开发中我遇到过几个典型问题C#脚本修改后不生效这是因为Godot需要重新构建项目程序集。点击编辑器右上方的Build按钮或者使用底部的MSBuild工具。信号连接失败C#中信号连接要特别注意方法签名匹配。如果遇到问题可以尝试手动连接而不是依赖自动生成。性能问题当敌人数量很多时可能会影响性能。解决方案是优化碰撞形状使用简单几何体限制同时存在的敌人数量使用对象池技术重用敌人实例跨平台问题如果计划发布到移动设备需要考虑触控输入。可以添加虚拟摇杆或者将屏幕分为左右区域分别控制移动方向。8. 扩展思路基础版本完成后可以考虑添加更多功能多种敌人类型不同敌人可以有不同速度、大小和分数价值。道具系统添加临时加速、无敌等道具丰富游戏性。音效和背景音乐Godot的AudioStreamPlayer很容易实现音效。存档系统使用Godot的ConfigFile保存最高分等数据。粒子效果玩家被击中或获得道具时添加视觉效果。实现这些扩展时建议保持代码模块化。比如把道具系统单独做成一个场景和脚本这样不会影响现有功能的稳定性。

相关文章:

Godot实战(一)—— 用C#构建2D躲避游戏的核心机制

1. 环境准备与项目初始化 第一次打开Godot引擎时,那个简洁的界面可能会让你有点不知所措。别担心,我们一步步来。点击"New Project"按钮,给你的游戏项目起个名字,比如"DodgeTheCreeps"。建议专门创建一个空文…...

你的综述,为什么像文献摘要合集?

相信不少科研人都有过这样的挫败:熬了数个夜晚整理几十篇文献,写出来的综述却被导师批“没有灵魂”——只是把文献摘要简单翻译、拼接,看不到领域的发展脉络,抓不住不同研究间的学术争议,更找不到值得深挖的研究空间&a…...

不止是图像采集:基于RK3588 NPU和FPGA,如何给Cameralink相机注入AI灵魂(附目标跟踪/电子稳像实战)

异构计算赋能Cameralink相机:RK3588 NPU与FPGA协同的AI视觉实战 在工业检测、安防监控和国防光电系统中,Cameralink相机凭借其高带宽、低延迟的特性成为高速图像采集的首选。但当面对动目标检测、电子稳像等复杂任务时,传统方案往往陷入算力瓶…...

教你一招轻松定生物医学论文插图

写生物医学论文时,信号通路图、细胞调控机制图、病理机制图是展示研究逻辑的核心视觉语言,几乎是投稿刚需。但不少科研人都踩过绘图的坑:找不到专业的受体、离子通道、磷酸化符号等矢量图标,只能用基础形状拼凑,结果图…...

植物树枝叶片果实检测数据集7220张VOC+YOLO格式

植物树枝叶片果实检测数据集7220张VOCYOLO格式数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):7220 标注数量(xml文件个数):7220…...

AI为编程赋能增效:从“古法编程”到氛围编程的范式革命

在人工智能技术飞速发展的今天,编程领域正经历着一场前所未有的范式革命。曾经,我们习惯于在编辑器中逐行敲击代码,为复杂的语法纠错而焦头烂额,那个需要死记硬背各种操作符与数据结构的“古法编程时代”正在悄然落幕。取而代之的…...

MD5是哈希,不是加密,防君子不防小人

一、先把概念说清楚很多开发者在日常交流中习惯说“MD5加密”,这个说法流传太久,以至于不少人真的以为MD5是一种加密算法。实际上,MD5属于哈希(Hash)算法,也叫散列算法或消息摘要算法。加密和哈希的本质区别…...

高层次综合设计算法-常见问题记录(一)

一、算法设计思考的重点 1.定点化的陷阱 整数部分数据位宽不足造成的溢出; 舍入导致图像的视觉差异; 小数部分位宽不足导致精度不够,或者效果不佳;2.pipelin流水线的设计 普通变量造成的数据依赖问题,导致II达不到&…...

SaaS ERP和传统ERP,到底差在哪?

这几年,ERP这个词越来越火。但有意思的是,很多企业老板、管理层,甚至已经在用ERP的人,其实都没真正分清:“SaaS ERP”和“传统ERP”,到底差在哪。很多人会觉得:“不都是ERP吗?不就是…...

第一卷第4章:接口而非实现编程

第一卷第4章:接口而非实现编程 目录介绍 00.先回答上篇思考题 0.1 上篇遗留三道题 0.2 云迁移6万行代码 0.3 五次反转补锅 0.4 灵魂五连问 01.从一个搬迁切入 1.1 上云搬迁案例...

4 款主流论文降 AI 软件实测对比!谁能 5 分钟把 AI 率降到 10% 以下

4 款主流论文降 AI 软件实测对比!谁能 5 分钟把 AI 率降到 10% 以下 毕业季最焦虑的事——答辩前剩 3 天、AI 率还有 70%、想找一款 5 分钟就能搞定的工具。 市面上很多工具宣称"几分钟出结果"——但实测下来快的快、慢的慢、效果差距更大。这篇文章实测对…...

智慧展馆(数字孪生 + 三维重建)全解析

智慧展馆(数字孪生 三维重建)全解析一、核心技术体系(含动态目标实时重构、数字孪生、透明建筑)智慧展馆的数字化升级,核心依托四大核心技术 ——视频孪生、三维重建、动态目标实时重构、透明建筑渲染,四大…...

RDMA网络调试实战:当你的应用卡顿时,如何定位是哪种Error导致了重传?

RDMA网络性能调优实战:从重传Error定位到精准修复 RDMA(Remote Direct Memory Access)技术凭借其超低延迟和高吞吐量的特性,已经成为高性能计算、分布式存储和金融交易系统的核心网络架构。但在实际生产环境中,即使是经…...

用Python和nilmtk库,5分钟上手非侵入式用电分析(附实战代码)

用Python和nilmtk库,5分钟上手非侵入式用电分析(附实战代码) 当你站在电表前,看着那个不断跳动的数字,是否好奇过家里每台电器究竟消耗了多少电能?传统方法需要在每个电器上安装传感器,既麻烦又…...

别再死记硬背了!用Python模拟D触发器与JK触发器波形,5分钟搞定时序逻辑难题

用Python动态模拟时序逻辑:D触发器与JK触发器的可视化实践 时序逻辑电路是数字系统设计的核心基础,但对于许多初学者而言,纯理论推导和手工绘制波形图往往令人望而生畏。本文将带你用Python构建一个直观的触发器模拟系统,通过代码…...

Webpack优化实战:从配置到性能调优

Webpack优化实战:从配置到性能调优 大家好,我是蔓蔓。在大厂工作时,我负责过多个大型项目的Webpack配置和优化。今天我来和大家分享Webpack优化的实战技巧。 基础优化 合理配置mode // webpack.config.js module.exports {mode: process.env…...

LangGraph入门:构建有状态的AI Agent工作流

LangGraph 入门:用状态图构建 Agent手写 ReAct 循环容易写出 bug。LangGraph 用「状态图」的方式定义 Agent,把每一步定义为一个节点,跳转逻辑定义为边——清晰、可测试、可扩展。一、为什么需要 LangGraph 手写 Agent 循环的痛点&#xff1a…...

FPGA+DDR3+千兆以太网:构建实时高清图像传输与显示系统(附源码)

1. 实时高清图像传输系统的核心价值 想象一下这样的场景:医疗内窥镜手术中,医生需要实时查看1080p高清影像;工业检测线上,高速摄像头每秒产生数百帧4K画面;无人机航拍时,需要将拍摄的高清视频实时回传到地面…...

从源头到治理:光伏并网逆变器直流分量抑制技术全解析

1. 光伏并网逆变器直流分量问题概述 第一次在光伏电站现场看到直流分量超标告警时,我盯着监控屏幕愣了半天。作为从业多年的光伏系统工程师,我深知这个看似微小的技术指标背后隐藏着多大的隐患。直流分量就像电网中的"隐形杀手",它…...

Linux Ext 调度器核心原理:BPF 驱动的自定义调度革命

简介 Linux 内核调度器自诞生以来,始终以通用公平调度(CFS)与硬实时调度(SCHED_DEADLINE/SCHED_FIFO)为核心,支撑服务器、桌面、嵌入式等全场景负载。但传统调度框架存在硬耦合、难扩展、定制成本极高的痛…...

MATLAB单双目标定实战:逐图解析重投影误差的提取与评估

1. 重投影误差的底层逻辑与MATLAB实现 第一次用MATLAB做相机标定时,盯着那个总均方根误差(Total RMS Error)数值看了半天,总觉得少了点什么。后来才明白,就像考试不能只看总分,标定质量评估也需要细化到每张…...

Linux Idle 调度器的 cpuidle_reflect:Idle 状态统计更新

简介 在 Linux 内核电源管理与调度体系中,CPU Idle(空闲)调度器是实现 CPU 低功耗管理的核心模块,负责在 CPU 无任务可调度时,选择并进入合适的硬件空闲状态(C-state),在性能与功耗…...

从特征稀缺到精准定位:基于HS-FPN与可变形注意力的白细胞检测新范式

1. 白细胞检测的现状与挑战 在医学影像分析领域,白细胞检测一直是个让人头疼的问题。想象一下,医生需要从密密麻麻的血细胞图像中找出白细胞,就像在沙滩上找特定形状的贝壳一样困难。传统方法主要依赖医生手动操作显微镜,不仅效率…...

SmartDock:让Android设备拥有桌面级生产力的智能启动器

SmartDock:让Android设备拥有桌面级生产力的智能启动器 【免费下载链接】smartdock A user-friendly desktop mode launcher that offers a modern and customizable user interface 项目地址: https://gitcode.com/gh_mirrors/smar/smartdock 你是否曾经想过…...

从谐波治理到能量回馈:深入聊聊LCL滤波器在光伏逆变器和PWM整流器里的那些关键设计

LCL滤波器设计实战:从谐波抑制到能量回馈的工程权衡 在光伏逆变器和PWM整流器设计中,电流谐波治理一直是工程师面临的核心挑战。当项目要求总谐波失真率(THD)必须低于3%时,传统L滤波器往往力不从心——要么需要超大电感量导致体积膨胀&#x…...

Cadence变种BOM实战:以IMU模块为例,打造多配置硬件设计流程

1. 从零理解变种BOM的核心价值 第一次接触变种BOM这个概念时,我正被一个IMU模块的项目折磨得焦头烂额。客户要求这个模块能支持五种不同的通信接口,还要可选配导航和RTC功能。这意味着我需要维护十几个不同版本的原理图和BOM表,每次修改都要同…...

蚂蚁百灵 Ring-2.6-1T 开源解析:万亿级思考模型如何实现「按需推理」

引言 2026年5月,蚂蚁百灵团队正式开源了其旗舰级思考模型 Ring-2.6-1T,这是一款拥有万亿参数的推理模型,在 AIME 2026 数学竞赛基准测试中取得了 95.83分 的惊人成绩,一跃成为国产开源 Agent 模型的新里程碑。更值得关注的是,该模型首次引入了 可调节的 Reasoning Effort…...

CST仿真入门实战:Dipole天线结果解读与关键参数分析

1. Dipole天线仿真结果初探 第一次打开CST仿真软件完成Dipole天线仿真后,面对密密麻麻的结果图表,相信很多人都会感到无从下手。我刚开始接触电磁仿真时也是这样,盯着那些S参数曲线和远场辐射图发愣。其实读懂这些结果并不难,关键…...

别再只会用阿里云加速了!手把手教你配置Docker daemon.json,优化日志与存储路径

深度优化Docker生产环境:daemon.json高阶配置实战指南 当Docker从开发测试环境走向生产部署时,默认配置往往成为性能瓶颈和系统隐患的源头。许多团队在遭遇磁盘爆满、日志失控或网络拥塞后,才意识到基础镜像加速只是Docker调优的冰山一角。本…...

零代码构建你的AI知识库:让Obsidian笔记开口说话

零代码构建你的AI知识库:让Obsidian笔记开口说话 【免费下载链接】anything-llm The all-in-one AI productivity accelerator. On device and privacy first with no annoying setup or configuration. 项目地址: https://gitcode.com/GitHub_Trending/an/anythi…...