0

In godot 3.0, I have a platformer set up. I realized there was an issue with lag, so I designed it so pieces are destroyed after they get off screen to the left. For the most part, enemies will function. Except the last one, who will fire projectiles until it appears on screen, then it goes completely still. The player can push them around and such, but it won't do anything. All enemies, blocks, etc. have the method queue_free() when they fall too far to the left or bottom (the game moves to the right).

I'm sorry I can't get a video of the problem, my computer can't run both screen recording software and the game at the same time without the game being too laggy to use.

If the enemy is moved closer to the center to start, and is therefore encountered earlier, it works. I have tried having items delete themselves after they fall to the left or under the screen, this solved the same problem in level 1 but not level 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()

The enemy should move towards the player if the player is close enough and crossing the raycast and they won't fall. They should then throw their projectile.

What ends up happening is they do throw the projectile when the player crosses the raycast, but only until the enemy appears on screen. This only applies to enemies the player encounters about a minute down the level, before then enemies will funcion as expected.

  • I’ve been continuing with the program, and realized the enemy will eventually catch up and attack, but it takes a lot of time, so its still a lag issue – Litsabber Dudeguy Feb 01 '19 at 12:29

1 Answers1

0

Since you realized it was a lag issue, let me give you a small performance tip:

Do not use get_node every time you want to get a node, since it will make a search each time. Instead, you can either initialize a variable on func _ready() and keep the node reference there, or directly use the convenient syntax onready var check_left = get_node("CheckLeft") that does exactly that.

Logain
  • 4,259
  • 1
  • 23
  • 32