Gogot

脚本

生命周期方法

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");
}

在input函数

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");
//删除节点
//test.QueueFree();

//将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
//FindChild的返回值是Node
Node test =root.FindChild("Test");
//如果我们的节点不是node,需要
Node2D test =root.FindChild("Test") as Node2D ;

//寻找当前节点的父节点,返回值是Node
Node2D node =this.GetParent() as Node2D;
Node2D node1 =this.GetParent<Node2D>();

////寻找当前节点的子节点,返回值是Node,可以相对、绝对
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();


}

还有行政类(财务处类(管钱,监听学生的学费缴纳状态、奖助学金发放信号,更新财务台账;触发欠费预警等),后勤处类(维护校园卫生,维护公共设备等),招生办类(根据学校等级声誉等数值生成学生池,并且提供个专业的分数线等信息,根据时间录取并且实例好学生,并且全校同步新生信息),人事处类(可以招聘生成老师和职工,进行培训,解雇等),教务处类(开学通过招生办的新生信息,学生按时报到:触发「报到确认」信号,教务处激活学业档案,学生实例出现进入校园,学生毕业方法,),学生处类(分配宿舍方法,学生毕业相关方法),保卫处类(管理校园门禁,巡逻等),实训中心类(管理维护教学设备)),还有学院类(管理学院,负责解锁学院之后,检查老师是否充足,不足就通过人事处招聘老师,管理解锁的学院解锁专业)