godot脚本使用02

Processing

一些动作会触发回调和虚函数,所以写代码时不需要一遍遍的运行来检查代码的正确性。此外,很多动作都可以被动画播放器处理。然而,在脚本中对动画每一帧的处理有2种常见的情况---闲时处理和固定处理。

闲时处理被节点的set_process()函数激活,一旦激活,节点的_process()回调函数会被动画的每一帧调用,例如:

func _ready():
    set_process(true)

func _process(delta):
    [dosomething..]

delta参数表示时间秒 浮点 类型 两次调用_process()的时间间隔。

固定处理与闲时处理有些类似,但是只是和物理引擎同步。

做一个实例测试,创建一个Label节点的场景,然后给Label添加一个脚本,脚本中的代码:

extends Label

var accum=0

func _ready():
    set_process(true)

func _process(delta):
    accum+=delta
    set_text(str(accum))

accum的值会随着时间逐渐增加。这说明,一旦节点的set_process(true)被激活,_process()会被调用,在每一帧动画的时间里。

Groups

节点可以被添加到组,这对于组织非常大的场景很有用。有2种方法加入组:

1.通过ui界面中的组图标按钮:


2.通过代码:

例如在一个场景中标记敌人组

func _ready():
    add_to_group("enemies")
如果玩家潜入秘密基地,被发现,所有的敌人可以被警报通知,使用场景树中的 call_group()函数,

func _on_discovered():

    get_tree().call_group(0,"guards","player_was_discovered")

以上的代码中函数 "player_was_discovered"被敌人组中的每一个成员("guards")调用,可以得到全部的"guards"节点树,通过代码

var guards = get_tree().get_nodes_in_group("guards")
 之后还会有更多的东西添加到场景树中。

Notifications

godot的有一个通知系统,通常不是由脚本语言来实现的,大部分都是通过底层的虚函数来提供的。知道这个系统的存在是有好处的,比如在脚本中添加一个_notification()函数
func _notification(what):
     if (what==NOTIFICATION_READY):
        print("This is the same as overriding _ready()...")
     elif (what==NOTIFICATION_PROCESS):     
        var delta = get_process_time()
        print("This is the same as overriding _process()...")

 class list 有每一个类的Notification,然而,对于许多情况脚本提供了简单的重写函数。

Overrideable Functions

如前所述,最好使用这些可以重写的函数。节点提供了许多有用的可以重写的函数,如下所述:

func _enter_tree():
   pass # When the node enters the _Scene Tree_, it become acive and  this function is called. Children nodes have not entered the active scene yet. In general, it's better to use _ready() for most cases.

func _ready():
   pass # This function is called after _enter_tree, but it ensures that all children nodes have also entered the _Scene Tree_, and became active.

func _exit_tree():
   pass # When the node exists the _Scene Tree_, this function is called. Children nodes have all exited the _Scene Tree_  at this point and all became inactive.

func _process(delta):
   pass # When set_process() is enabled, this is called every frame

func _fixed_process(delta):
   pass # When set_fixed_process() is enabled, this is called every physics frame

func _paused():
   pass #Called when game is paused, after this call, the node will not receive any more process callbacks

func _unpaused():
   pass #Called when game is unpaused

Creating Nodes

用代码创建一个节点,只需要调用new()函数,例如:

var s
func _ready():
   s = Sprite.new() # create a new sprite!
   add_child(s) #add it as a child of this node
删除一个节点时调用free()函数(不管该节点在不在场景内):

func _someaction():
   s.free() # immediately removes the node from the scene and frees it

当一个节点被释放,同时这个节点的子节点也会被释放,因此,手动删除节点看上去很简单。只是将基节点和基节点的一切拿走放到子节点树上。然而,当想要删除一个被锁定的节点,也就是这个被删除的节点正在发射信号或者这在调用一个函数,这将导致游戏崩溃。在godot的调试器中经常会捕获到这样的情况,并向你发出警告。

使用queue_free()函数可以安全的删除节点,这个函数将取消被删除节点的锁定,可以让节点处于闲置状态,所以可以安全的删除节点。

func _someaction():
   s.queue_free() # remove the node and delete it while nothing is happening


Instancing Scenes

通过2步代码可以实现场景的引用:

1.加载场景从硬盘上:

var scene = load("res://myscene.scn") # will load when the script is instanced

在脚本被解析时可以加载场景预备之后的处理,通过preload()函数:

var scene = preload("res://myscene.scn") # will load when parsing the script
但是被加载的场景还不是一个包含子节点的节点,加载进来的场景是一个PackedScene,接下来创建实际的节点,通过函数   PackedScene.instance代码如下:

 
  
var node = scene.instance()
add_child(node)


instance()函数返回加载场景的节点树。

通过以上两步,被加载的场景就可以拿来使用了,并且可以根据需要创建加载场景的实例,这是相当有用的。



你可能感兴趣的:(godot游戏引擎基础)