0 votes

I have been using Godot for a little while and now want to recode a snake game I wrote before in Lua and java.

I am really struggling with instancing a scene and adding it to my tree.
Somehow a function which is called on one single instance by the node above (its parent node) seems to take place twice as soon as I added it to the tree.

The SegmentScene I instanced holds only a Sprite as the root node with SegmentSkritpt.gd attached to it.
instanced

When I add an instance of that scene to my tree and call a function of the script attached to that scenes' sprite, it would always take place twice - and even worse - when printing the instance out upon calling its function, it prints two different numbers, meaning it is not only calling the function of one instance twice but instead the instance itself exists twice, although created and added only once.
When I call the function on the created scene instance, storing it in an array before adding it to the tree, it won't print anything at all...

tree
- map contains an unrelated script
- snake contains SnakeSkript.gd with related parent parts

in the create method:

var head = SnakeSScene.new()
add_child(head)
snake.append(head). #adding it to own array for referencing

and in the process method:

if snake[0] !=null:     
    snake[0].updateSnakeLog(delta)

calling it only on one instance and even if I put getparent().getchild(0).updateSnakelog(delta) here it gets called twice in SnakeSegmentSkript

SnakeSkript.gd:

extends Node

var SnakeSScene = preload("res://SegmentSkript.gd")

var snakeSpd = 32.0

var snakeCmds = []

var snake = []
func _ready():
var head = SnakeSScene.new()
add_child(head)
snake.append(head)


func _process(delta):

if Input.is_action_just_pressed("ui_left"):
    if snakeCmds.size() ==0 or snakeCmds.back() != 0 and snakeCmds.back() != 1:
        snakeCmds.append(0)
elif Input.is_action_just_pressed("ui_right"):
    if snakeCmds.size() ==0 or snakeCmds.back() != 1 and snakeCmds.back() != 0:
        snakeCmds.append(1)
elif Input.is_action_just_pressed("ui_up"):
    if snakeCmds.size() ==0 or snakeCmds.back() != 2 and snakeCmds.back() != 3:
        snakeCmds.append(2)
elif Input.is_action_just_pressed("ui_down"):
    if snakeCmds.size() ==0 or snakeCmds.back() != 3 and snakeCmds.back() != 2:
        snakeCmds.append(3)

if snake[0] !=null:     
     snake[0].updateSnakeLog(delta)


func addSnakeSegment():
pass

SnakeSegmentSkript.gd:

extends Sprite

var direction 
var snakeLogTimer = 0 
var walked = 0
var cmdIndex = 0


func _ready():
#snakeLogTimer=get_parent().get_child(0).snakeLogTimer
self.position.x = (SnakeSkript.snakeSpd/2)
self.position.y = (SnakeSkript.snakeSpd/2)
texture = load("res://assets/snake.png")
scale.x = SnakeSkript.snakeSpd/16
scale.y = SnakeSkript.snakeSpd/16
setDirection(globals.dirRight)

func setDirection(d):
direction = d
self.rotation_degrees = globals.directionRotations[d]


func movePosition(x,y):
self.walked += 1
position.x += x
position.y += y



func _process(delta):
pass

func updateSnakeLog(delta):

snakeLogTimer += delta
while snakeLogTimer >= 1/SnakeSkript.snakeSpd:
    snakeLogTimer -= 1/SnakeSkript.snakeSpd
    if direction == globals.dirLeft:
        movePosition(-1,0)
    if direction == globals.dirRight:
        movePosition(1,0)
    if direction == globals.dirUp:
        movePosition(0,-1)
    if direction == globals.dirDown:
        movePosition(0,1)

    if walked >= SnakeSkript.snakeSpd:
        walked = 0
        initNewSteps()

func initNewSteps():
    print("head"+ str(self))
    if cmdIndex >= SnakeSkript.snakeCmds.size():
            SnakeSkript.snakeCmds.append(direction)
    setDirection(SnakeSkript.snakeCmds[cmdIndex])
    cmdIndex +=1

So the snake node should add one instance of that snake segment scene and call update log... there a timer fills and triggers walked+1 once in a while. As soon as walked is >= 16 it gets reset and calls initnewStep() where "head" and the object is printed.
with this code every second initnewStep will be trigged by the updated instance and "head"+str(self) will be printed, but in Godot somehow two instances exist?!

This is the output:

head[Sprite:1180]
head[Sprite:1412]

in Engine by (18 points)

1 Answer

0 votes

I solved it. The mistake I made was to import the class on autoload and attaching it to a node in my tree, which lead to a double instance of the script inside the tree.

by (18 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.