0

在 godot 3.0 中,我设置了一个平台游戏。我意识到延迟存在问题,所以我设计了它,以便在离开屏幕左侧后将其销毁。在大多数情况下,敌人会起作用。除了最后一个,他会发射弹丸直到它出现在屏幕上,然后它就完全静止了。玩家可以将它们推来推去,但它不会做任何事情。当所有敌人、方块等落到左侧或底部太远时(游戏向右移动),它们都有方法 queue_free()。

很抱歉,我无法获得问题的视频,我的计算机无法同时运行屏幕录制软件和游戏,而游戏太慢而无法使用。

如果敌人靠近中心开始,因此更早遇到,它会起作用。我曾尝试让项目在它们落到左侧或屏幕下方后自行删除,这解决了第 1 级的相同问题,但没有解决第 2 级的问题。

#Here is my code for my enemies, all pound signs for comments are replaced with // so that stack overflow wouldn't bold them:
extends KinematicBody2D

var playerpos = Vector2(0, 0)
var left = true

var baton = load("res://Items/Baton/Baton.tscn")
var BatPick = load("res://Items/Baton/BatonPickup.tscn")

var shoot_timer = 0.0

var walk_speed = 425
var CollidingWithPlayer = false
var velocity = Vector2(0, 100)

var HP = 10

func _ready():
    //Flip player checking raycast back and forth
    get_node("Raycast").add_exception(get_node("Area"))
    set_physics_process(true)
    set_process(true)
    pass

//Raycast both sides
func _process(delta):
    //die if HP is less than zero and drop the baton
    get_node("Raycast").rotate(180)
    if HP <= 0:
        var pickup = BatPick.instance()
        get_tree().get_root().add_child(pickup)
        pickup.global_position = global_position
        queue_free()
    pass

//Check for player in raycast, throw if possible. Move towards it if wouldn't fall
func _physics_process(delta):
    shoot_timer = shoot_timer + delta
    //Check for player, throw baton if player is in range and 5 seconds or more has passed since it was thrown last
    if get_node("Raycast").is_colliding():
        var obj = get_node("Raycast").get_collider()
        if obj != null and obj.get_name() == "Area":
            obj = obj.get_parent()
        if obj != null and obj.get_name() == "Player":
            CollidingWithPlayer = true
            playerpos = obj.global_position
            //Throw baton and walk in player's direction if I wouldn't fall
            if playerpos.x < global_position.x and shoot_timer >= 1:
                left = true
                throw_baton()
                shoot_timer = 0
                get_node("AnimatedSprite").play("WalkingL")
                if not (left == true and (not get_node("CheckLeft").is_colliding())) or (left == false and (not get_node("CheckRight").is_colliding())):
                    velocity.x = -300
                move_and_slide(velocity, Vector2(0, -50))
            elif playerpos.x > global_position.x and shoot_timer >= 1:
                left = false
                throw_baton()
                shoot_timer = 0
                get_node("AnimatedSprite").play("WalkingR")
                if not(left == true and (not get_node("CheckLeft").is_colliding())) or (left == false and (not get_node("CheckRight").is_colliding())):
                    velocity.x = 300
                move_and_slide(velocity, Vector2(0, -50))
        else:
            CollidingWithPlayer = false

            get_node("AnimatedSprite").stop()
            get_node("AnimatedSprite").frame = 0
    else:
        CollidingWithPlayer = false
        get_node("AnimatedSprite").stop()
        get_node("AnimatedSprite").frame = 0

    get_node("CheckLeft").force_raycast_update()
    get_node("CheckRight").force_raycast_update()
    if (left == true and (not get_node("CheckLeft").is_colliding())) or (left == false and (not get_node("CheckRight").is_colliding())):
        velocity.x = 0

    //delete if fallen
    if global_position.y >= 650:
        queue_free()

    move_and_slide(velocity, Vector2(0, -500))
    pass
//Throw baton
func throw_baton():
    var projectile = baton.instance()
    get_tree().get_root().add_child(projectile)
    if left == true:
        projectile.global_position = global_position + Vector2(-60, 0)
        projectile.velocity = Vector2(-500, 0)
        get_tree().get_root().get_node("Baton").rotation_degrees = 180
    if left == false:
        projectile.global_position = global_position + Vector2(60, 0)
        projectile.velocity = Vector2(500, 0)
    pass

func take_damage(damage):
    HP -= damage
    pass

#Here is my code for the parent node that slides the blocks, items, enemies, etc across the board (the camera doesn't move and the player stays within the same "box" as everything moves towards the player):

extends Node2D

const endpos = 99999
var speed = -2.5


func _ready():
    get_node("True_Player").endpos = endpos
    pass

func _process(delta):
    get_node("ALL THE STUFF").move_and_collide(Vector2(speed, 0))
    //set if statement to close and execute corresponding file when endpos is reached
    pass

#The following code is in everything except the player and enemies so that they are deleted when they fall too far left, the disappear to avoid lag:

if global_position.x < -50:
        queue_free()

如果玩家足够近并且穿过光线投射并且他们不会倒下,那么敌人应该向玩家移动。然后他们应该投掷他们的弹丸。

最终发生的情况是,当玩家穿过光线投射时,它们确实会投掷弹丸,但只会在敌人出现在屏幕上之前。这仅适用于玩家在关卡下大约一分钟遇到的敌人,在此之前敌人将按预期运行。

4

1 回答 1

0

既然您意识到这是一个滞后问题,让我给您一个小的性能提示:

不要get_node每次想要获取节点时都使用,因为它每次都会进行搜索。相反,您可以初始化一个变量func _ready()并将节点引用保留在那里,或者直接使用方便的语法onready var check_left = get_node("CheckLeft")来做到这一点。

于 2019-03-30T18:33:17.950 回答