长沙网站制作哪家强,网站怎么做的精致一点,如何做同城信息网站,江门市智企互联网站建设文章目录 前言相关地址环境配置初始化环境配置文件夹结构代码结构代码运行 资源文件导入像素风格窗口环境设置背景设置,Tileap使用自动TileMap 人物场景动画节点添加站立节点添加移动动画添加 通过依赖注入获取Godot的全局属性项目声明 当前项目逻辑讲解角色下降添加代码位置问… 文章目录 前言相关地址环境配置初始化环境配置文件夹结构代码结构代码运行 资源文件导入像素风格窗口环境设置背景设置,Tileap使用自动TileMap 人物场景动画节点添加站立节点添加移动动画添加 通过依赖注入获取Godot的全局属性项目声明 当前项目逻辑讲解角色下降添加代码位置问题的思考在Node2D上面挂载Lable节点在CharacterBody2D下面挂载解决方案修改代码动画节点的问题需要重新绑定为什么我要这么写 动画效果初始化AnimationPlayer 输入映射获取输入简单移动完善输入和添加动画完善跳跃手感 前言
我之前解决了C# 的IOC的配置现在来认真学习一个完整的Godot 项目。我看B站上面这个教程非常的好所以打算用C# 去复刻一下使用IOC依赖注入的想法。
相关地址 十分钟制作横版动作游戏Godot 4 教程《勇者传说》#0 人物素材 环境素材 Gclove2000/GodotNet_LegendOfPaladin 环境配置
Windows 10.net core 8.0Visual Studio 2022godot.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.GetNodeCharacterBody2D(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.GetNodeCharacterBody2D(CharacterBody2D);animationPlayer this.Sence.GetNodeAnimationPlayer(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.GetNodeCharacterBody2D(CharacterBody2D);animationPlayer this.Sence.GetNodeAnimationPlayer(AnimationPlayer);sprite2D this.Sence.GetNodeSprite2D(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);}......}......
}