笔记 游戏 Gogot 小楼夜听雨 2026-04-25 2026-10-02 脚本 生命周期方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public override void _Ready() { } public override void _Process(double delta) { } public override void _ExitTree() { }
鼠标设置 在构造函数func _ready() -> void:中使用
1 2 3 4 5 6 7 8 9 10 11 Input.MouseMode = Input.MouseModeEnum.Visible; Input.MouseMode = Input.MouseModeEnum.Hidden; Input.MouseMode = Input.MouseModeEnum.Captured; Input.MouseMode = Input.MouseModeEnum.Confined;
按键输入 可以在 每帧执行一次的函数 或者在 input函数使用
在每帧执行一次的函数 1 2 3 4 5 //判断按钮是否按下 if (Input.IsKeyPressed(Key.B)) { GD.Print("按下了B"); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public override void _Input(InputEvent @event) { base._Input(@event); //判断输入的是什么 //如果是键盘,则转化为键盘事件 if (@event is InputEventKey) { //转化为键盘事件 var key = @event as InputEventKey; //判断按钮是否按下 if (key.Keycode == Key.V) { //判断当前是否是持续按压 if (key.IsEcho()) { GD.Print("持续按压了V" ); } //判断当前是否是按压瞬间 if (key.IsPressed()) { GD.Print("瞬间按压了V" ); } //判断当前是否是抬起瞬间 if (key.IsReleased()) { GD.Print("抬起了V" ); } } } //如果是鼠标,则转化为鼠标事件 if (@event is InputEventMouse) { //转化为鼠标事件 var mouse = @event as InputEventMouse; //判断当前是否是按压瞬间 if (mouse.IsPressed()) { //打印鼠标位置 GD.Print(mouse.Position); //打印鼠标按键 GD.Print(mouse.ButtonMask); } } }
虚拟按钮 在项目设置->输入映射中
添加新动作
+号绑定按键
在_Process函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 //监听虚拟按键是否按下 if (Input.IsActionJustPressed("跳跃")) { GD.Print("按下跳跃"); } //监听虚拟按键是否按下没有松开 if (Input.IsActionPressed("跳跃")) { GD.Print("跳跃中"); } //监听虚拟按键是否按下 if (Input.IsActionJustReleased("跳跃")) { GD.Print("松开了空格"); } //监听按键是否被按下,是返回1,否返回0 float s = Input.GetActionRawStrength("跳跃"); GD.Print(s);
监听上下左右 在虚拟按键中添加上下左右
1 2 3 4 5 6 7 //监听左右,-1/1 float a = Input.GetAxis("左","右"); GD.Print(a); //监听左右上下(0,0),左上-1,右下1 Vector2 b = Input.GetVector("左","右","上","下"); GD.Print(b);
节点方法 修改位置或者添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 if (Input.IsActionJustPressed("左" )) { Node root =this .GetTree().CurrentScene; Node test =root.FindChild("Test" ); root.RemoveChild(test); this .AddChild(test); } if (Input.IsActionJustPressed("右" )) { Node root =this .GetTree().CurrentScene; Node2D node2D =new Node2D(); node2D.Name = "new" ; this .AddChild(node2D); }
查找节点
1 2 3 4 5 6 7 8 9 10 11 Node test =root.FindChild("Test" ); Node2D test =root.FindChild("Test" ) as Node2D ; Node2D node =this .GetParent() as Node2D; Node2D node1 =this .GetParent<Node2D>(); Node2D node1 =GetNode<Node2D>("root/a/b/c" );
切换场景 方法一(会销毁)
1 2 3 4 5 6 7 8 9 10 //监听虚拟按键是否按下 if (Input.IsActionJustPressed("左")) { //获取场景树 SceneTree st = this.GetTree(); //方法1 st.ChangeSceneToFile("res://场景2.tscn"); }
方法二(会销毁)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 继承node public partial class 场景1脚本 : Node { //在面板创建一个场景变量,可直接拖场景到变量中 [Export] public PackedScene newScene; //监听虚拟按键是否按下 if (Input.IsActionJustPressed("左")) { //获取场景树 SceneTree st = this.GetTree(); //方法2 st.ChangeSceneToPacked(newScene); }
预制体(不会销毁)
1 2 3 4 5 6 7 8 9 10 11 12 13 public partial class 场景1脚本 : Node { [Export ] public PackedScene newScene; if (Input.IsActionJustPressed("右" )) { Node node =newScene.Instantiate(); this .GetTree().CurrentScene.AddChild(node); }
不可销毁脚本(单例) 游戏开始自动运行,切换场景也不会销毁,直到退出游戏
如:设置 的脚本
创建一个脚本GameManager,要继承 node
在项目设置中 全局的自动挂载中,添加上去
向量 定义: 标量:只有大小的量
向量:有大小,有方向
向量的模:向量的大小、
单位向量:大小为1的向量
单位化,归一化:把向量转为单位向量的过程
运算: 加法:A(X,Y)+B(X1,Y1) =(X+X1 , Y+Y1)
减法:A(X,Y)-B(X1,Y1) =(X-X1 , Y-Y1),方向指向B—>A
乘法:A(X,Y) *2 = (2X,2Y)
点乘:A(X,Y) * B(X1,Y1) =(X*X1 + Y *Y1) =|A|*|B|* COS& =N ,通过方法可以得到&
分组 在右边面板中给节点分组
可通过方法获取组的成员 1 2 3 4 5 6 7 8 9 10 11 12 if (Input.IsActionJustPressed("右")) { //获取分组中的节点 var enemys =this.GetTree().GetNodesInGroup("敌人"); //遍历 foreach(Node aa in enemys) { //销毁 aa.QueueFree(); } }
给一个分组的节点发信息(广播) 如果一个分组的节点都用同一个脚本,那么可以统一调用脚本的方法
1 2 3 4 5 if (Input.IsActionJustPressed("右")) {//给学生组发送信息,调用 上课 方法 this.GetTree().CallGroup("学生","上课"); } }
给节点分组 1 2 3 4 5 if (Input.IsActionJustPressed("右")) { //将当前节点添加到别的分组 this.AddToGroup("学生"); }
信号 在脚本中写好方法,在_Ready中或者在右边栏中绑定
1 2 3 4 5 6 //找到然后删除节点的方法 public void aaa() { Node node = GetNode<Node2D>("/root/node"); node.QueueFree(); }
动态绑定(信号名称,信号发出者,方法)
1 2 3 4 5 6 7 8 public override void _Ready() { //按钮连接删除节点的方法 this.Connect("pressed",new Callable(this,"aaa")); }
自定义信号
在A节点定义一个信号(名称后面加EventHandler),并且发送信号(只发送名称)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public partial class 场景1脚本 : Node2D { //创建一个信号 [Signal] public delegate void MYAAAAEventHandler(); public override void _Process(double delta) { if (Input.IsActionJustPressed("左")) { //发送信号 EmitSignal("MYAAAA"); } }
在B节点定义一个方法,并且绑定该信号
1 2 3 4 public void BBB() { GD.Print("BBB收到信号"); }
声音 搜 audiostream 节点
一般选择audiostreamplayer
左下角系统文件双击可以开启循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 if (Input.IsActionJustPressed("左")) { //判断当前是否在播放 if(this.Playing == false) { //播放 this.Play(); } } if (Input.IsActionJustPressed("下")) { //停止播放 this.StreamPaused = true; } if (Input.IsActionJustPressed("右")) { //继续播放 this.StreamPaused = false; }
在节点脚本中添加音频,不添加音频节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public partial class 场景1脚本 : Node2D { //声明音频类型节点 AudioStreamPlayer player; //在面板添加属性 [Export] AudioStream bgm; public override void _Ready() { //实例化音频节点 player = new AudioStreamPlayer(); //添加到当前子节点 this.AddChild(player); //加载音频 player.Stream =bgm; //播放 player.Play(); }
还有行政类(财务处类(管钱,监听学生的学费缴纳状态、奖助学金发放信号,更新财务台账;触发欠费预警等),后勤处类(维护校园卫生,维护公共设备等),招生办类(根据学校等级声誉等数值生成学生池,并且提供个专业的分数线等信息,根据时间录取并且实例好学生,并且全校同步新生信息),人事处类(可以招聘生成老师和职工,进行培训,解雇等),教务处类(开学通过招生办的新生信息,学生按时报到:触发「报到确认」信号,教务处激活学业档案,学生实例出现进入校园,学生毕业方法,),学生处类(分配宿舍方法,学生毕业相关方法),保卫处类(管理校园门禁,巡逻等),实训中心类(管理维护教学设备)),还有学院类(管理学院,负责解锁学院之后,检查老师是否充足,不足就通过人事处招聘老师,管理解锁的学院解锁专业)