Godot 4 教程《勇者传说》依赖注入 学习笔记(0):环境配置

news/2024/4/30 11:48:11

文章目录

  • 前言
  • 相关地址
  • 环境配置
  • 初始化环境配置
    • 文件夹结构
    • 代码结构
    • 代码运行
  • 资源文件导入
  • 像素风格窗口环境设置
  • 背景设置,Tileap使用
    • 自动TileMap
  • 人物场景
  • 动画节点添加
    • 站立节点添加
    • 移动动画添加
  • 通过依赖注入获取Godot的全局属性
    • 项目声明
  • 当前项目逻辑讲解
  • 角色下降
    • 添加代码
    • 位置问题的思考
      • 在Node2D上面挂载Lable节点
      • 在CharacterBody2D下面挂载
      • 解决方案
        • 修改代码
        • 动画节点的问题,需要重新绑定
        • 为什么我要这么写
  • 动画效果
    • 初始化AnimationPlayer
  • 输入映射
    • 获取输入
      • 简单移动
      • 完善输入和添加动画
      • 完善跳跃手感

前言

我之前解决了C# 的IOC的配置,现在来认真学习一个完整的Godot 项目。我看B站上面这个教程非常的好,所以打算用C# 去复刻一下,使用IOC依赖注入的想法。

相关地址

十分钟制作横版动作游戏|Godot 4 教程《勇者传说》#0

人物素材

环境素材

Gclove2000/GodotNet_LegendOfPaladin

在这里插入图片描述

环境配置

  • Windows 10
  • .net core 8.0
  • Visual Studio 2022
  • godot.net 4.2.1

初始化环境配置

Godot.NET C# 工程化开发(1):通用Nuget 导入+ 模板文件导出,包含随机数生成,日志管理,数据库连接等功能

在这里插入图片描述

文件夹结构

  • Godot:Godot项目+主要游戏逻辑代码
  • GodotProgram:帮助类

代码结构

  • GodotNet_LegndOfPaladin:Godot主要逻辑
    • SceneModels:场景IOC对象
    • SceneScirpts:场景对应脚本
    • Util: Godot API帮助类
      • PackedSceneHelper:打包场景加载
    • Program:IOC容器
  • GodotProgram:C# 主要逻辑
    • Assets:资产文件
    • DB:数据库对象
    • Interfaces:接口
    • Service:服务
    • Utils:帮助类

代码运行

在这里插入图片描述
在这里插入图片描述

资源文件导入

人物素材

环境素材

在这里插入图片描述

在这里插入图片描述

像素风格窗口环境设置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

背景设置,Tileap使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

自动TileMap

Godot 官方2D C#重构(3):TileMap使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
大致实现效果

在这里插入图片描述
绘制TimeMap地形需要比较强的熟练度。多多联系即可

在这里插入图片描述
在这里插入图片描述

人物场景

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
长按左键选择站立动画

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

动画节点添加

站立节点添加

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击6次,添加6个关键帧
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

移动动画添加

和上面的一样

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过依赖注入获取Godot的全局属性

Godot的全局属性是通过字符串的方式获取的,这非常容易出问题。而且我们也希望这种配置信息能在项目启动的时候就获取

在这里插入图片描述

Godot ProjectSettings 字符串对应数据

项目声明

    public class GodotProjectSettingHelper{private NlogHelper nlogHelper;public readonly float Gravity = 0;public GodotProjectSettingHelper(NlogHelper nlogHelper){this.nlogHelper = nlogHelper;Gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");}}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当前项目逻辑讲解

在这里插入图片描述
在这里插入图片描述
所以我们新建一个场景的逻辑是

  • 新增XXX.tscn
  • 挂载XXXScene.sc脚本
  • IOC注入XXXSceneModel.cs 类
  • PackedSceneHelper添加对应的PackedScene

详情请看我的Github源码

Gclove2000/GodotNet_LegendOfPaladin

角色下降

在这里插入图片描述

在这里插入图片描述

添加代码

public class PlayerSceneModel : ISceneModel
{private NlogHelper nlogHelper;private GodotProjectSettingHelper godotProjectSettingHelper;public PlayerSceneModel(NlogHelper nlogHelper,GodotProjectSettingHelper godotProjectSettingHelper) {this.nlogHelper = nlogHelper;this.godotProjectSettingHelper = godotProjectSettingHelper;}private CharacterBody2D characterBody2D;public override void Process(double delta){//给角色一个速度,因为重力是加速度,所以角色的速度会不断的增加。characterBody2D.Velocity += new Vector2(0, godotProjectSettingHelper.Gravity * (float)delta);//让物体以这个速度进行移动characterBody2D.MoveAndSlide();nlogHelper.Debug($"x:{characterBody2D.Velocity.X},y:{characterBody2D.Velocity.Y}");}public override void Ready(){nlogHelper.Debug($"当前重力值为:{godotProjectSettingHelper.Gravity}");characterBody2D = this.Sence.GetNode<CharacterBody2D>("CharacterBody2D");}
}

在这里插入图片描述

位置问题的思考

我们知道CharacterBody2D就是为了获取CollisionShape2D的位置。因为他的位置取决于重力,物理碰撞,加速度等多方面因素。相当于他的位置是自动变化的

在Node2D上面挂载Lable节点

在这里插入图片描述
在这里插入图片描述

在CharacterBody2D下面挂载

在这里插入图片描述
在这里插入图片描述

解决方案

在这里插入图片描述

我们只需要CharacterBody2D给我们的位置更改即可,而在Godot中,Position都是相对父节点的位置。所以每次Character移动的时候,我们将CharacterBody2D的位置获取,然后我们将Character的相对位置 设置为0即可

修改代码
public override void Process(double delta)
{//给角色一个速度,因为重力是加速度,所以角色的速度会不断的增加。characterBody2D.Velocity += new Vector2(0, godotProjectSettingHelper.Gravity * (float)delta);//让物体以这个速度进行移动characterBody2D.MoveAndSlide();var postion = characterBody2D.Position;characterBody2D.Position = new Vector2(0, 0);this.Sence.Position += postion;}
动画节点的问题,需要重新绑定

主要,如果修改动画节点的位置,会导致绑定出现问题

在这里插入图片描述

为什么我要这么写

因为我们不一定会写横版战斗游戏,横版战斗是有重力的,但是俯视角战斗又没有重力了,或者说不是垂直向下的重力,而是俯视角的效果。比如【以撒的结合】

在这里插入图片描述

动画效果

在Godot中,AnimationPlayer通过【Play】这个函数来播放动画。但是Godot中,Play是通过字符串的形式调用的。为了保证字符串的正确性,我们添加一个Enum枚举类型来对其进行限制

在这里插入图片描述

初始化AnimationPlayer

在这里插入图片描述

//枚举类型,防止拼写错误
public enum AnimationFlame { REST, idel,running }......public override void Ready()
{nlogHelper.Debug($"当前重力值为:{godotProjectSettingHelper.Gravity}");//初始化子节点characterBody2D = this.Sence.GetNode<CharacterBody2D>("CharacterBody2D");animationPlayer = this.Sence.GetNode<AnimationPlayer>("AnimationPlayer");//播放动画animationPlayer.Play(AnimationFlame.idel.ToString());
}

在这里插入图片描述

输入映射

我们输入上下左右,一般都是wasd,但是因为我们可能要做手柄,可能也要做移动端。所以最好设置一个输入映射好一些。

在这里插入图片描述
我的输入是,wsad是上下左右,【j】/【空格】是跳跃

在这里插入图片描述

在这里插入图片描述

获取输入

Godot 输入处理

我们在任意一个节点下面去获取按钮事件


public override void Process(double delta)
{//获取move_left对应按下事件if (Input.IsActionPressed("move_left")){nlogHelper.Debug("move_left 按下");}}

在这里插入图片描述

简单移动

在这里插入图片描述

public const float RUN_SPEED = 200;
.......public override void Process(double delta)
{var velocity = new Vector2();var direction = Input.GetAxis(InputMapEnum.move_left.ToString(), InputMapEnum.move_right.ToString());var y = godotProjectSettingHelper.Gravity * (float)delta;var x = direction * RUN_SPEED;//在C# 中,velocity = characterBody2D.Velocity;//X是最终速度,所以不需要相加velocity.X = x;//给角色一个速度,因为重力是加速度,所以角色的速度会不断的增加。velocity.Y += y;characterBody2D.Velocity = velocity;//让物体以这个速度进行移动characterBody2D.MoveAndSlide();//同步场景根节点位置var postion = characterBody2D.Position;characterBody2D.Position = new Vector2(0, 0);this.Sence.Position += postion;
}

在这里插入图片描述

完善输入和添加动画

using Godot;
using GodotNet_LegendOfPaladin.Utils;
using GodotProgram.Interfaces;
using GodotProgram.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static GodotNet_LegendOfPaladin.Utils.GodotProjectSettingHelper;namespace GodotNet_LegendOfPaladin.SceneModels
{public class PlayerSceneModel : ISceneModel{public const float RUN_SPEED = 200;public const float JUMP_VELOCITY = -300;//枚举类型,防止拼写错误public enum AnimationFlame {  idel, running,jump }#region IOC注入private NlogHelper nlogHelper;private GodotProjectSettingHelper godotProjectSettingHelper;public PlayerSceneModel(NlogHelper nlogHelper, GodotProjectSettingHelper godotProjectSettingHelper){this.nlogHelper = nlogHelper;this.godotProjectSettingHelper = godotProjectSettingHelper;}#endregion#region 子节点获取private CharacterBody2D characterBody2D;private AnimationPlayer animationPlayer;private Sprite2D sprite2D;public override void Ready(){nlogHelper.Debug($"当前重力值为:{godotProjectSettingHelper.Gravity}");//初始化子节点characterBody2D = this.Sence.GetNode<CharacterBody2D>("CharacterBody2D");animationPlayer = this.Sence.GetNode<AnimationPlayer>("AnimationPlayer");sprite2D = this.Sence.GetNode<Sprite2D>("Sprite2D");//播放动画animationPlayer.Play(AnimationFlame.idel.ToString());}#endregionpublic override void Process(double delta){//初始化速度var velocity = new Vector2();//初始化动画节点var animation = AnimationFlame.idel;var direction = Input.GetAxis(InputMapEnum.move_left.ToString(), InputMapEnum.move_right.ToString());var y = godotProjectSettingHelper.Gravity * (float)delta;var x = direction * RUN_SPEED;var isOnFloor = characterBody2D.IsOnFloor();//在C# 中,velocity = characterBody2D.Velocity;//X是最终速度,所以不需要相加velocity.X = x;//给角色一个速度,因为重力是加速度,所以角色的速度会不断的增加。velocity.Y += y;//如果在地上并且按下跳跃,则直接给一个y轴的速度if(isOnFloor && Input.IsActionJustPressed(InputMapEnum.jump.ToString())){velocity.Y = JUMP_VELOCITY;}if (isOnFloor){if (Mathf.IsZeroApprox(direction)){animation = AnimationFlame.idel;}else{animation = AnimationFlame.running;}}else{animation = AnimationFlame.jump;}//方向翻转if (!Mathf.IsZeroApprox(direction)){sprite2D.FlipH = direction < 0;}characterBody2D.Velocity = velocity;//让物体以这个速度进行移动characterBody2D.MoveAndSlide();//同步场景根节点位置var postion = characterBody2D.Position;characterBody2D.Position = new Vector2(0, 0);this.Sence.Position += postion;animationPlayer.Play(animation.ToString());}}
}

在这里插入图片描述

完善跳跃手感

如果玩过超级马里奥或者别的平台跳跃游戏,都知道有一个手感的东西。就是有个跳跃的提前量。我们现在是正好落地的时候按下跳跃才能跳起来,现在我们将跳跃的按钮进行存储,给与一定的缓冲间隔。

/// <summary>
/// 最长跳跃等待时间
/// </summary>
public const int JUMP_WAIT_TIME = 3000;
/// <summary>
/// 初始化的时候让时间往后退一点,防止时间过快
/// </summary>
private DateTime jumpLastTime = DateTime.Now.AddDays(-1);......
public override void Process(double delta)
{......if (Input.IsActionJustPressed(InputMapEnum.jump.ToString())){jumpLastTime = DateTime.Now;}if (isOnFloor){//如果在地上并且按下跳跃,则直接给一个y轴的速度//超时判断if (jumpLastTime.AddMilliseconds(JUMP_WAIT_TIME) > DateTime.Now){//如果刚好触发了跳跃,给个速度,将jumpLastTime推前velocity.Y = JUMP_VELOCITY;jumpLastTime = DateTime.Now.AddDays(-1);}......}......
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

外包干了5天,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

git-怎样把连续的多个commit合并成一个?

Git怎样把连续的多个commit合并成一个&#xff1f; Git怎样把连续的多个commit合并成一个&#xff1f; 参考URL: https://www.jianshu.com/p/5b4054b5b29e 查看git日志 git log --graph比如下图的commit 历史&#xff0c;想要把bai “Second change” 和 “Third change” 这…

每日一题--- 环形链表[力扣][Go]

环形链表 题目&#xff1a;142. 环形链表 II 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给…

通过node 后端实现颜色窃贼 (取出某个图片的主体rgb颜色 )

1.需求 我前端轮播图的背景色 想通过每一张轮播图片的颜色作为背景色 这样的话 需要通过一张图片 取出图片的颜色 这个工作通过前端去处理 也可以通过后端去处理 前端我试了试 color-thief 的插件 但是 这个插件是基于canvas 的模式来的 我需要在小程序中使用这个插件 而且是…

qt事件机制学习笔记

实现闹钟功能 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), speecher(new QTextToSpeech(this)) //给语音播报者实例化空间 {ui->setupUi(this); }Widget::~Widget() {delete …

CAJViewer7.3 下载地址及安装教程

CAJViewer是中国学术期刊&#xff08;CAJ&#xff09;全文数据库的专用阅读软件。CAJViewer是中国知识资源总库&#xff08;CNKI&#xff09;开发的一款软件&#xff0c;旨在方便用户在线阅读和下载CAJ数据库中的学术论文、期刊和会议论文等文献资源。 CAJViewer具有直观的界面…