godot2d的一些使用技巧(2)

前言吐槽:dfq作者无双说过,不要用冷门引擎。果然,相对于unity来说,godot在细节上面实在是坑爹。“人类从历史中学到的唯一教训,就是人类无法从历史中学到任何教训。——黑格尔”,这个实验项目完成后还是转移去unity算了……

 

1、windows平台上的导出还需要一个叫rcedit的程序,这个程序藏得很深,在官方的渐进式教程——导出——“在Windows上,如果希望导出的可执行文件的图标与默认图标不同,则需要手动更改它。请参阅: 更改Windows的应用程序图标。”中的“在导出选项中选择它之前,您需要额外安装一个名为 rcedit 的工具。您可以在 这里 下载它。”这个工具的作用是修改windows下exe的图标……而且修改后移动exe还会使exe缩略图标失效变成默认图标……我服了……

2、godot的UI节点默认Rect——min size是(0,0),如果是panel,那么可能会出现panel完全不显示的情况,要修改和size完全一样……这是哪门子设计……

3、godot的碰撞体在instance()后就可以触发碰撞事件,即使它在程序内还是远程debug内都是不可视的……这个东西在instance()的时候大概会位于窗口默认大小的正中间,所以有时候会出现些奇奇怪怪的bug……

4、如果使用信号,就会发现信号需要函数触发,函数需要连接到信号上……于是有如下逻辑:底层机制——信号——函数——信号——函数……,例如:敌人死亡的时候发射信号isdying到敌人出生点,敌人出生点有个执行Timer timerout的函数_timerstart()连接信号isdying,_timerstart()在敌人出生点的ready()函数里连接到敌人出生点的_loadenemy()函数,然后_loadenemy()函数执行新建敌人的部分……

太绕了,上代码:

    /// <summary>
    /// 敌人
    /// </summary>
public class Enemy : Sprite
{
    public delegate void isdying();//自身死亡信号
    public override void _Ready()
    {
        player = GetNode<Sprite>("../Player");
        RigidBody2D rigidBody2D = this.GetNode<RigidBody2D>("EnemyRigidBody2D");
        rigidBody2D.Connect("body_entered", this, nameof(_die));//碰撞信号触发自身死亡
        enemyhome = GetNode<Sprite>("../EnemyHome");
    }
}
    /// <summary>
    /// 碰撞销毁
    /// </summary>
    /// <param name="node">被碰撞的碰撞体</param>
private void _die(Node node)
{
    if (node.Name == "bulletRigidBody2D")
    {
        EmitSignal(nameof(isdying));//发射自身死亡信号
        this.QueueFree();
    }
}

  

/// <summary>
/// 敌人出生点
/// </summary>
public class EnemyHome : Sprite
{
    Timer timer;//延时生成敌人的计时器
    public override void _Ready()
    {
        timer = this.GetNode<Timer>("Timer");
        timer.Connect("timeout", this, nameof(timeoutEvent));//添加计时器触发后的执行函数
        _loadenemy();//初始化后立即创建一个敌人
    }
    /// <summary>
    /// 生成敌人
    /// </summary>
    private void _loadenemy()
    {
        Node enemy = GD.Load<PackedScene>("res://prefabs/Enemy.tscn").Instance();
        RigidBody2D enemyRigidBody2D = enemy.GetNode<RigidBody2D>("EnemyRigidBody2D");
        enemy.Connect("isdying", this, nameof(_timerstart));
        ((Sprite)enemy).Position = this.Position;
        enemyRigidBody2D.ContactMonitor = true;//开启碰撞检测
        enemyRigidBody2D.ContactsReported = 99;//默认为0,值大于0时碰撞信号才会传入被碰撞体;
        //初始化并调整位置后才启用碰撞检测
        //碰撞体实例化时会默认在窗口正中,即使未显示也能触发检测,所以要在预制体先阻止碰撞检测
        GetNode<Node>("../").AddChild(enemy);
        ((Enemy)enemy).speed += speed;
      }  
    private void timeoutEvent()
    {
        _rebuildEnemy();
    }
    private void _timerstart()
    {
        timer.Start(3);
    }
    /// <summary>
    /// 生成新敌人
    /// </summary>
    private void _rebuildEnemy()
    {
        _loadenemy();
    }
}

逻辑如图:

另外想说的是,如果要使用信号机制在多个物体间传导的话,将connect写在ready()里执行会好一点……吧……但这样一来耦合度不也上去了嘛……

3、开启碰撞检测的方法:

Node enemy = GD.Load<PackedScene>("res://prefabs/Enemy.tscn").Instance();
RigidBody2D enemyRigidBody2D = enemy.GetNode<RigidBody2D>("EnemyRigidBody2D");
enemyRigidBody2D.ContactMonitor = true;//开启碰撞检测
enemyRigidBody2D.ContactsReported = 99;//默认为0,值大于0时碰撞信号才会传入被碰撞体;

预制体要先设置为false和0,instance()后再设置回来

4、朝向:

this.LookAt(player.GlobalPosition);//朝向鼠标
this.RotationDegrees += 90f;//自身朝向
//LookAt()函数使素材的右边朝向坐标位置

5、直接获得根节点:

Node node= this.GetTree().Root.GetChild<Node>(0);

6、限定移动范围:


this.Position = new Vector2//限定自身可移动范围
  (
  x: Mathf.Clamp(this.Position.x, minmap.x, maxmap.x),
  y: Mathf.Clamp(this.Position.y, minmap.y, maxmap.y)
);

7、退出程序和游戏暂停:

1 GetTree().Quit();//退出程序
2 this.GetTree().Paused = false;//游戏暂停,节点设置mode为process则不受影响

8、获取其他节点的脚本的变量:

1 int enemyScore;
2 enemyScore = Convert.ToInt32(node.GetNode<Sprite>("..").Get(nameof(Enemy.Score)));//获取怪物得分值
3 public class Enemy : Sprite
4 {
5     public int Score;//击杀得分
6 }
 1 enemyHome.Position = new Vector2
 2 (
 3     x:Player.minmap.x-100,
 4     y: new Random().Next(Convert.ToInt32(Player.minmap.y), Convert.ToInt32(Player.maxmap.y))
 5 );
 6 public class Player : Sprite
 7 {
 8     public static Vector2 minmap = new Vector2(100, 100);//角色可移动范围,其一顶点
 9     public static Vector2 maxmap = new Vector2(1100, 600);//角色可移动范围,对角顶点
10 }

 (完)

 

posted @ 2021-02-06 21:03  陀娑御白弥  阅读(622)  评论(0编辑  收藏  举报