Using Timers with "extends KinematicBody2D"

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By GannyDeSpy

Hello, Im wondering if i am able to use timers with extends KinematicBody2D. I want to avoid using the engines update/tick function as much as possible and thought timers would be a good route to take.

Before, I had the code below using extends Node, which made the timers work, but I could not get position to modify the enemies position on screen. Alternatively when I used extends KinematicBody2Di could get the position, but the timers would no longer work.

I was thinking of making a child node and creating a script using extends Node. This would let me make timers that would call functions in the parent node containing a script using extends KinematicBody2D, so i can update the position of the enemy.

I was wondering if there is a simpler way to do this or if there are better ways of achieving what i am trying to do.

Thank you!

extends KinematicBody2D

var timerMovement = null
var timerAttack = null

var player = null

var currentPosition = Vector2(0,0)

export(int) var currentTileY = 1

func _enemyAttack1():
    #Shoot Projectile
    print("Stop movement timer and shoot projectile")
    pass

func _enemyMovement():
    #Get the position of the player
    var playerX = player._GetCurrentTileX()
    var playerY = player._GetCurrentTileY()

    #If player is above the enemy, move the enemy one space above
    if playerY > currentTileY:
	    position += Vector2(0, -256)
	    currentPosition += Vector2(0, -256)
	    currentTileY += 1
    #Move one space below otherwise
	elif playerY < currentTileY:
		position += Vector2(0, 256)
		currentPosition += Vector2(0, 256)
		currentTileY -= 1
	else:	
		#Else stay in place
		pass
	#Spawn Projectile that moves forward
	pass
	
func _wheresThePlayer():
	print("Where the hell is the player?")

func _ready():
	#Check if the playerBattle node exists in the scene before assigning it.
	if has_node("../playerBattle"):
		player = get_node("../playerBattle")
	else:
		_wheresThePlayer()
		
	currentPosition = position
	
	#Add a timer make the enemy attack
	timerAttack = Timer.new()
	add_child(timerAttack)
	
	#Every x seconds 
	timerAttack.connect("timerAttack", self, "_enemyAttack1")
	timerAttack.set_wait_time(5.0)
	timerAttack.set_one_shot(false) # loop timer
	timerAttack.start()
	
	#Add a timer to make enemy move
	timerMovement = Timer.new()
	add_child(timerMovement)
	
	#Every x seconds 
	timerMovement.connect("timerMovement", self, "_enemyMovement")
	timerMovement.set_wait_time(1.0)
	timerMovement.set_one_shot(false) # loop timer
	timerMovement.start()

Why would the Timer not work if you’re using a KinematicBody2D? It shouldn’t be making any differences. Are you sure they don’t work?

SIsilicon | 2018-12-17 02:31

It will still compile, but the timer function that is called will not print out the test line. The only thing that gets printed is “temp” which just tells me that it ran through everything in _ready()
If i switch extends KinematicBody2D to extends Node then the timers will work but the variable position will throw an error.

GannyDeSpy | 2018-12-29 17:22

:bust_in_silhouette: Reply From: GannyDeSpy

So i fixed the problem by changing the lines :
timerAttack.connect("timerAttack", self, "_enemyAttack1") and timerMovement.connect("timerMovement", self, "_enemyMovement")
to
timerAttack.connect("timeout", self, "_enemyAttack1") and timerMovement.connect("timeout", self, "_enemyMovement")

The problem was that i was calling a signal i named "timerAttack" and "timerMovement" without creating the signal before hand. I swapped both to a built in signal called "timeout" and the timers now work with 'extends KinematicBody2D