Godot Breakeys Godot Beginner Tutorial 游戏开发笔记

news/2024/11/16 7:36:57/文章来源:https://www.cnblogs.com/gclove2000/p/18173914

目录
  • 前言
  • 资源下载
  • 添加人物节点
    • 运动状态机
  • 移动平台
    • 单向穿过
    • 奇怪的Bug
  • Area2D
    • BodyEntered
  • 死亡区域
    • 全局类
    • 多线程安全
  • TileMap处理
    • TileMap分层

前言

这次来学习一下youtube的传奇Unity博主,Breakeys的Godot新手教程。Breakeys是从15岁左右就开始用unity做游戏并在youtube上面发布视频了。他已经在youtube上面发布了讲解450个视频,然后他累了,3年前发布了一个告别视频后离开了。因为前端时间的untiy收费事件,他又回来了。他并没有明确的批评Unity,但是他说游戏的未来应该是像Blender一样的开源社区,而且Godot的完成度远超他的想象。

基本的godot操作我们就不展开说明,我会对操作进行一些进阶的代码替换。会跳过很多步骤,详细的代码可以看我的github仓库:https://github.com/Gclove2000/Brackeys-Godot-Beginner-Tutorial-In-Dotnet

资源下载

Brackeys' Platformer Bundle:https://brackeysgames.itch.io/brackeys-platformer-bundle

添加人物节点

这里比较简单,我就跳过了

运动状态机

因为我之前写过状态机,我这里就直接写代码了。

using Godot;
using GodotGame.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace GodotGame.SceneModels
{public class PlayerSceneModel : ISceneModel{private PrintHelper printHelper;private CharacterBody2D characterBody2D;private Sprite2D sprite2D;private AnimationPlayer animationPlayer;private CollisionShape2D collisionShape2D;public const int SPEED = 300;public const int JUMP_VELOCITY = -400;public enum AnimationEnum { Idel,Run,Roll,Hit,Death}private AnimationEnum animationState = AnimationEnum.Idel;public AnimationEnum AnimationState{get => animationState;set{if(animationState != value){printHelper?.Debug($"[{animationState}] => [{value}]");animationState = value;}}}private bool isFlip = false;public bool IsFlip{get => isFlip;set{if(isFlip != value){var postion = characterBody2D.Scale;postion.X = -1;characterBody2D.Scale = postion;isFlip = value;}}}public PlayerSceneModel(PrintHelper printHelper){this.printHelper = printHelper;printHelper.SetTitle(nameof(PlayerSceneModel));}public override void Ready(){characterBody2D = Scene.GetNode<CharacterBody2D>("CharacterBody2D");sprite2D = Scene.GetNode<Sprite2D>("CharacterBody2D/Sprite2D");animationPlayer = Scene.GetNode<AnimationPlayer>("CharacterBody2D/AnimationPlayer");collisionShape2D = Scene.GetNode<CollisionShape2D>("CharacterBody2D/CollisionShape2D");printHelper.Debug("加载成功!");}public override void Process(double delta){Move(delta);Play();SetAnimation();}private void SetAnimation(){if (!characterBody2D.IsOnFloor()){AnimationState = AnimationEnum.Roll;}switch (AnimationState){case AnimationEnum.Idel:if (!Mathf.IsZeroApprox(characterBody2D.Velocity.X)){AnimationState = AnimationEnum.Run;}break;case AnimationEnum.Run:if (Mathf.IsZeroApprox(characterBody2D.Velocity.X)){AnimationState = AnimationEnum.Idel;}break;case AnimationEnum.Hit:break;case AnimationEnum.Death:break;case AnimationEnum.Roll:if (characterBody2D.IsOnFloor()){AnimationState = AnimationEnum.Idel;}break;}if (!characterBody2D.IsOnFloor()){//printHelper.Debug("跳跃");AnimationState = AnimationEnum.Roll;}}private void Move(double delta){var move = new Vector2(0,0);move = characterBody2D.Velocity;move.Y += (float)(MyGodotSetting.GRAVITY * delta);if (MyGodotSetting.IsActionJustPressed(MyGodotSetting.InputMapEnum.Jump) && characterBody2D.IsOnFloor()){printHelper.Debug("跳跃");move.Y = JUMP_VELOCITY;}var direction = Input.GetAxis(MyGodotSetting.InputMapEnum.Left.ToString(), MyGodotSetting.InputMapEnum.Right.ToString());if(Mathf.IsZeroApprox(direction)){move.X = (float)Mathf.MoveToward(move.X, 0, delta*SPEED);}else{move.X = (float)Mathf.MoveToward(move.X, direction*SPEED, delta * SPEED);IsFlip = direction < 0;}characterBody2D.Velocity = move;characterBody2D.MoveAndSlide();}private void Play(){animationPlayer.Play(AnimationState.ToString());}}
}

移动平台

StaticBody2D和他的子节点都适合用于制作不会移动的节点

单向穿过

如果我们想要一个单向的碰撞体,就可以打开 One Way Collision 这个按钮

奇怪的Bug

如果我们使用Node作为根节点来进行移动,就会导致整个碰撞层的错误,这里我不知道为什么

Area2D

Area2D一般用于制作简单的无碰撞的物体

BodyEntered

之前我说过,在C# 中,不适用信号而改用委托事件的方式,能在C# 内部解决的,就尽量不调用Godot的API。

using Godot;
using GodotGame.SceneScripts;
using GodotGame.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace GodotGame.SceneModels
{public class CoinSceneModel : ISceneModel{private PrintHelper printHelper;private Area2D area2D;private Sprite2D sprite2D;private AnimationPlayer animationPlayer;private CollisionShape2D collisionShape2D;public CoinSceneModel(PrintHelper printHelper) {this.printHelper = printHelper;this.printHelper.SetTitle(nameof(CoinSceneModel));}public override void Process(double delta){}public override void Ready(){area2D = Scene.GetNode<Area2D>("Area2D");sprite2D = Scene.GetNode<Sprite2D>("Area2D/Sprite2D");animationPlayer = Scene.GetNode<AnimationPlayer>("Area2D/AnimationPlayer");collisionShape2D = Scene.GetNode<CollisionShape2D>("Area2D/CollisionShape2D");printHelper.Debug("加载完成");area2D.BodyEntered += Area2D_BodyEntered;}private void Area2D_BodyEntered(Node2D body){printHelper.Debug("有东西进入");if (body is PlayerScene){printHelper.Debug("玩家进入");}if(body.GetParent() is PlayerScene){printHelper.Debug("父节点是玩家的进入");}}}
}

这里的碰撞检测就用到了Godot的一个特性了,如果你使用了继承的脚本重载了节点,这样相当于你新建了一个类型。比如Node2D节点挂载了一个继承Node2D的 PlayerScene,这样Godot就认为你是PlayerScene这个节点,这样方便我们对各种碰撞事件的对象进行判断

但是要注意的是,碰撞的对象只是Player的Area节点,所以还要去找他的父节点才可以找到对应的脚本类型

当然,我们最好也设置一下物理层,这样防止出现额外的碰撞事件。

死亡区域

全局类

这里我们就用全局类来进行代替

using Godot;
using GodotGame.SceneScripts;
using GodotGame.Utils;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace GodotGame.Modules
{[GlobalClass]public partial class DeathArea :Area2D{private PrintHelper printHelper;public DeathArea() {this.printHelper = Program.Services.GetService<PrintHelper>();this.printHelper.SetTitle(nameof(DeathArea));this.BodyEntered += DeathArea_BodyEntered;}private void DeathArea_BodyEntered(Node2D body){printHelper.Debug("Anythiny enter!");//如果玩家进入,则等待0.6秒后重新加载if (body.GetParent() is PlayerScene){printHelper.Debug("You Get Die");Reload();}}/// <summary>/// 为了线程安全,我们只能这么做/// </summary>/// <returns></returns>private async Task Reload(){await Task.Delay(600);GetTree().ReloadCurrentScene();}}
}

多线程安全

线程安全这里就不展开说明了,我们目前暂时还没接触到大量的数学计算。

TileMap处理

TileMap分层

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/709205.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瞎折腾-友情链接自助申请

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 瞎折腾-友情链接自助申请 日期:2017-6-1 阿珏 折腾代码 浏览:3136次 评论:1条关于友情链接自助申请是使用PHP语言开发的一款友情链…

不管多久,都不要忘记曾经的初心~~

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 不管多久,都不要忘记曾经的初心~~ 日期:2017-6-9 阿珏 二次元 浏览:4394次 评论:1条有些机会,因瞬间的犹豫,擦肩而过;有些缘分…

各种语言按钮事件特征码

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 各种语言按钮事件特征码 日期:2017-5-15 阿珏 教程 浏览:2920次 评论:1条调试软件,最重要的就是下断点,那么如何下断点,就是一…

你访问的页面不存在

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 你访问的页面不存在 日期:2017-4-4 阿珏 折腾代码 浏览:2268次 评论:2条搞了个萌萌哒的404 页面好吧,我是偷bilibili的。http://…

暴露网站后台地址是一件非常危险的事

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 暴露网站后台地址是一件非常危险的事 日期:2017-4-30 阿珏 折腾代码 浏览:3982次 评论:3条暴露一个网站的后台地址是一件非常危险…

博客正式更换为emlog

Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 博客正式更换为emlog 日期:2017-4-2 阿珏 谈天说地 浏览:2454次 评论:1条由于原博客系统不够完善等种种原因,后又因多说服务将于…

数字客VR售楼处,实现精准获客并提升去化率,摆脱渠道依赖

一、营销现状 1、受环境影响:售楼处未完成,无法前期蓄客并延长营销周期。如受疫情等其他情况需要关闭售楼处,无法跨越空间和时间进行销售,回款更是难上加难; 2、受客户影响:客户留资难,销售转化低,项目去化慢,无法精准获取意向客户线索,实现精准分析精准营销; 3、受…

apisix~集成服务发现注册中心

摘要 当业务量发生变化时,需要对上游服务进行扩缩容,或者因服务器硬件故障需要更换服务器。如果网关是通过配置来维护上游服务信息,在微服务架构模式下,其带来的维护成本可想而知。再者因不能及时更新这些信息,也会对业务带来一定的影响,还有人为误操作带来的影响也不可忽…

(1)semantic-kernel入门课程

(1)semantic-kernel入门课程 获取OpenAI在线API由于在国内的限制,我们并没有办法直接访问OpenAI,所以下面的教程我们会推荐使用https://api.token-ai.cn,然后您需要在这个网站中注册一个账号,并且创建一个令牌(最好是设置无限额度和无过期时间),创建好的令牌我们保存好…

偶然遇到的cubeide一些问题

昨天感觉cubeide有一些bug,具体表现为在外设的.c文件明明识别到了某个函数但是又打不开定义,于是在软件内更新了一下cubeide,结果更新完软件打不开了,没办法只能重装。重装完后新建工程的时候提示无法生成代码,因为缺少固件包,但打开固件界面又有固件包,如果无视提示强行…

OpenAI“杀疯了”,GPT–4o模型保姆级使用教程!一遍就会!

5月14日凌晨1点,OpenAI发布了名为GPT-4o 最新的大语言模型,再次引领了人工智能领域的又一创新浪潮,让整个行业都为之震动。 据OpenAI首席技术官穆里-穆拉提(Muri Murati)表示,GPT-4o是在继承GPT-4智能的基础上,对文本、视觉和音频功能进行了进一步改进,而且目前所有用户…

计量管理使用文档

计量管理使用文档添加计量要求​​添加计量台账选择计量要求 填写相关信息 会提前一个月发送消息给计量状态为正常的责任人。​​其他功能:暂停计量可以修改计量状态; 再计量可以添加一次计量记录; 台账历史记录,可以查看所有计量记录‍​​