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.