📜  GDscript中的类

📅  最后修改于: 2021-01-02 10:09:07             🧑  作者: Mango

GDscript中的类

脚本文件的主体是未命名的类,并且只能在外部作为资源或文件引用。类语法是紧凑的,并且只能包含成员变量或函数。允许使用静态函数,但不允许使用静态成员(这是线程安全的精神,因为脚本可以在用户不知情的情况下在单独的线程中初始化)。以相同的方式,每次创建实例时都会初始化成员变量(包括数组和字典)。

以下是类文件的示例;

# Saved as a file named 'myclass.gd.' 

var a = 5

func print_value_of_a():
    print(a)

遗产

一个类可以继承表格

  • 全球课程
  • 另一个类文件
  • 另一个类文件中的内部类。

不允许多重继承。

继承使用extend关键字:

# Inherit/extend a globally available class.
extends SomeClass

# Inherit/extend a named class file.
extends "some file.gd."

# Inherit an inner class in another file.
Extends "somefile.gd."SomeInnerClass

要检查给定实例是否继承给定类,可以使用is键盘:

# Cache the enemy class.
const Enemy = preload("enemy.gd")

# [...]

# Use 'is' to check inheritance.
if (entity is Enemy):
    entity.apply_damage()

要调用基类(即,一个在我国现行类扩展-ed),在前面加上一个函数。 ()到函数名:

.basefunc(args)

这很有用,因为扩展类中的函数会在其基类中替换具有相同名称的函数。因此,如果我们仍然想致电,则可以使用它。 (点)就像其他语言中的super关键字:

func some_func(x):
    .some_func(x) # Calls the same function on the parent class.

类构造器

在类实例化上调用的类构造函数名为_init 。继承类时,将自动调用父类的构造函数。因此,通常无需调用.init()

与上述示例中带有.some_func的常规函数的类不同,如果继承类的构造函数接受参数,则将它们传递为:

func _init(args).(parent_args):
   pass

通过示例可以更好地说明这一点。假设我们有这种情况:

# State.gd (inherited class)
var entity = null
var message = null

func _init(e=null):
    entity = e

func enter(m):
    message = m


# Idle.gd (inheriting class)
extends "State.gd."

func _init(e=null, m=null).(e):
    # Do something with 'e.'
    message = m

这里有一些事情要记住:

  • 如果继承的类(State.gd)定义了一个带参数的_init构造函数(在本例中为e ),则继承的类(Idle.gd)也必须定义_init并将适当的参数从gd传递给_init
  • 与基类State.gd相比, gd可以具有不同数量的参数
  • 在上面的例子中,E传递给GD构造是移入Idle.gd相同的E。
  • 如果gd_init构造函数接受0个参数,即使它什么也不做,它仍然需要将一些值传递给State.gd基类。这使我们认识到,我们不仅在变量中,还在基本构造函数中传递字面量。

#Idle.gd
Func _init().(5):
pass

内部班

一个类文件可以包含内部类。内部类是使用class关键字定义的。它们使用ClassName.new()函数进行实例化。

# Inside a class file.

# An inner class in this class file.
class SomeInnerClass:
    var a = 5
    func print_value_of_a():
        print(a)

# This is the constructor of the class file's main class.
func _init():
    var c = SomeInnerClass.new()
    c.print_value_of_a()

类作为资源

存储为文件的类被视为资源。必须从磁盘加载它们才能在其他类中访问它们。这是使用加载或预加载功能完成的。加载类资源的实例化是通过在类对象上调用新函数来完成的。

# Load the class resource when calling load().
var my_class = load("myclass.gd")

# Preload the class only at compile time.
const MyClass = preload("myclass.gd")

func _init():
    var a = MyClass.new()
    a.some_function()

出口产品

班级成员可以导出。这意味着它们的值将与它们附加的资源一起保存。它们可在属性编辑器中进行编辑。导出通过使用export关键字完成:

extends Button
export var number = 5 # Value will be saved and visible in the property editor.

必须将导出的变量初始化为常量表达式,或者具有export关键字的参数形式的导出提示:

导出成员变量的重要好处之一是使它们在编辑器中可见并可编辑。运输是通过使用export关键字完成的。

导出成员变量的主要好处之一是使其在编辑器中可见并可编辑。这样,美术师和游戏设计师可以修改值,这些值以后会影响程序的运行方式。提供了特殊的导出语法。

# If the exported value assigns a constant or constant expression,
# the type will be inferred and used in the editor.

export var number = 5

# Export can take a primary data type as an argument which will be
# used in the editor.

export(int) var number

# Export can take a resource type to use as a hint.

export(Texture) var character_face
export(PackedScene) var scene_file

# Integers and strings hint enumerated values.

# Editor will enumerate as 0, 1 and 2.
export(int, "Warrior", "Magician", "Thief") var character_class
# Editor will enumerate with string names.
export(String, "Rebeca", "Mary", "Leah") var character_name

# Named Enum Values

# Editor will enumerate as THING_1, THING_2, ANOTHER_THING.
enum NamedEnum {THING_1, THING_2, ANOTHER_THING = -1}
export (NamedEnum) var x

# Strings as Paths

# String is a path to a file.
export(String, FILE) var f
# String is a path to a directory.
export(String, DIR) var f
# String is a path to a file, custom filter provided as a hint.
export(String, FILE, "*.txt") var f

# Using paths in the global filesystem is also possible,
# but only in tool scripts (see further below).

# String is a path to a PNG file in the global filesystem.
export(String, FILE, GLOBAL, "*.png") var tool_image
# String is a path to a directory in the global filesystem.
export(String, DIR, GLOBAL) var tool_dir

# The MULTILINE setting tells the editor to show a large input
# field for editing over multiple lines.
export(String, MULTILINE) var text

# Limiting editor input ranges

# Allow integer values from 0 to 20.
export(int, 20) var i
# Allow integer values from -10 to 20.
export(int, -10, 20) var j
# Allow floats from -10 to 20, with a step of 0.2.
export(float, -10, 20, 0.2) var k
# Allow values y = exp(x) where y varies between 100 and 1000
# while snapping to steps of 20. The editor will present a
# slider for easily editing the value.
export(float, EXP, 100, 1000, 20) var l

# Floats with Easing Hint

# Display a visual representation of the ease() function
# when editing.
export(float, EASE) var transition_speed

# Colors

# Color given as Red-Green-Blue value
export(Color, RGB) var col # Color is RGB.
# Color given as Red-Green-Blue-Alpha value
export(Color, RGBA) var col # Color is RGBA.

# Another node in the scene can be exported too.

export(NodePath) var node

必须注意,即使脚本不在编辑器中,导出的属性仍可编辑。

参见下面的(工具)

导出位标志

位标记中使用的整数可以在一个属性中存储多个true / false值。通过使用导出提示[ int,FLAGS ],可以将它们发送给编辑器。

# individually edit a bit of integer.
Export(int,FLAGS) var spell/elements=ELEMENT/WIND|ELEMENT/WATER

也可以将标志限制为任意数量的标志。语法类似于枚举语法。

# Set any of the given flags from the editor.
export(int, FLAGS, "Fire", "Water", "Earth", "Wind") var spell_elements = 0

在示例中,火的值为1,水的值为2,地球的值为4,风的值为8。通常,应相应地定义常数。

使用位标志需要对按位操作有所了解。如有疑问,应改为导出布尔变量。

导出数组

导出数组是可行的,但有一个重要的警告:尽管在每个类实例的本地都创建了常规数组,但是导出的数组在所有实例之间共享。这意味着在一个实例中进行编辑将导致它们在所有其他实例中进行更改。导出的数组可以具有初始化程序,但是它们必须是常量表达式。

# Exported array, shared between all instances.
The # Default value must be a constant expression.

export var a = [1, 2, 3]

# Exported arrays can specify a type (using the same hints as before).

export(Array, int) var ints = [1,2,3]
export(Array, int, "Red", "Green", "Blue") var enums = [2, 1, 0]
export(Array, Array, float) var two_dimensional = [[1, 2], [3, 4]]

# You can omit the default value, but then it would be null if not assigned.

export(Array) var b
export(Array, PackedScene) var scenes

# Typed arrays also work, only initialized empty:

export var vector3s = PoolVector3Array()
export var strings = PoolStringArray()
# Regular array created locally for every instance.
The # Default value can include run-time values, but can't
# be exported.

var c = [a, 2, 3]

设置者/获取者

为此,GDScript使用setget关键字提供了setter / getter语法。它在变量定义后直接使用:

var variable = value setget setterfunc, getterfunc

每当变量的值被外部源修改(即,不是从类中的本地用法)修改时,将调用setter函数(上面的setterfunc )。

这发生在值更改之前。设置者必须决定如何处理新值。反之亦然,访问变量时,上述的getter函数getterfunc )必须返回所需的值。

例:

var my_var setget my_var_set, my_var_get

func my_var_set(new_value):
    my_var = new_value

func my_var_get():
    return my_var # Getter must return a value.

可以省略setter或getter函数中的任何一个:

# Only a setter.
var my_var = 5 setget myvar_set
# Only a getter (note the comma).
var my_var = 5 setget ,myvar_get

将变量导出到工具脚本或插件中的编辑器以验证输入时,“获取/设置”特别有用。

本地访问不会触发设置程序和获取程序。这是一个说明:

func _init():
    # Does not trigger setter/getter.
    my_integer = 5
    print(my_integer)

    # Does trigger setter/getter.
    self.my_integer = 5
    print(self.my_integer)