整活:多种武器

本节来实现玩家切换武器。

回顾目前玩家发射子弹时的代码,是这样写的:

func _process(delta):
    if Input.is_action_just_pressed("攻击"):
        var 创建的子弹:子弹类 = 子弹.instantiate()
        创建的子弹.移动速度 = 鼠标方向.normalized() * 1000
        $"/root/".add_child(创建的子弹)
        创建的子弹.global_position = global_position
        创建的子弹.rotation = 鼠标方向.angle()

这段代码写在了玩家节点上,此时我们为了能让玩家切换武器,可以来制作一个新的节点,用来表示武器,并将发射子弹的代码写在武器中。

武器节点

由于咱们的武器不会显示出来,所以武器节点其实就是一个 Node 节点,不需要其他东西,重点内容在 Node 节点的代码上。

当然如果你希望给玩家的武器显示一些图片,也可以在这个武器节点中添加一些 Sprite2D 节点。

武器节点的代码

extends Node2D
class_name 武器

@export var 子弹: PackedScene

func 开火(dir:float):
    pass

这里,我们定义了一个开火方法,并需要指定一个参数来表示开火的方向,但是这个方法内部我们什么都没写。

此时当我们要添加一种新武器时,即可让新武器类继承这个武器类,并重写其中的 开火 方法,在新的开火方法中创建子弹即可。

例如现在创建 步枪 类:

extends 武器

func 开火(dir:float):
    var zd:子弹类 = 子弹.instantiate()
    zd.global_position = global_position
    zd.rotation = dir
    $"/root/Game".add_child(zd)
    zd.移动速度 = Vector2.from_angle(dir) * 1000

霰弹枪 类:

extends 武器

func 开火(dir:float):
    创建子弹(dir - 0.6)
    创建子弹(dir - 0.3)
    创建子弹(dir)
    创建子弹(dir + 0.3)
    创建子弹(dir + 0.6)

func 创建子弹(dir:float):
    var zd:子弹类 = 子弹.instantiate()
    zd.global_position = global_position
    zd.rotation = dir
    $"/root/Game".add_child(zd)
    zd.移动速度 = Vector2.from_angle(dir) * 400

接着我们再创建两个 步枪霰弹枪 的 PackedScene,并在其节点上挂在上面两个脚本,然后在玩家切换武器时实例化这两个 PackedScene 即可:

func _process(delta):
    if Input.is_action_just_pressed("武器1"):
            切换武器(load("res://武器/步枪.tscn"))
        if Input.is_action_just_pressed("武器2"):
            切换武器(load("res://武器/霰弹.tscn"))

func 切换武器(武器:PackedScene):
    $"武器".free()
    var wq = 武器.instantiate()
    add_child(wq)
    wq.position = Vector2(0, 0)
    wq.name = "武器"

接着即可修改玩家的开火代码:

if Input.is_action_just_pressed("攻击"):
    $"武器".开火(rotation)