0 votes

Im currently working on a project that involves the player controlling a car and driving acoross intersections. One of the features is that the player can pick different vehicles. I have the basic animation working that makes each car drive into the screen, and spin until the player presses "next" and then it should stop spinning and drive off the screen.

It works most of the time but sometimes the car does not stop spinning and will stay on the screen while the next car drives on.
i'd like to know if anyone could recognise something in my code that may be causing this issue note that i have not cleaned it up yet and it is quite long. I also have the project on github if that would be helpful the code below is under "Garage.gd"
and the scene is "Garage-Car Selection.tscn"

My code:

extends Spatial


# Declare member variables here. Examples:
# var a = 2
# var b = "text"
export var Sports = false
export var Suv = false
export var nissian = false
export var Hatchback = false
export var SixbySix = false
export var Limo = false
# Called when the node enters the scene tree for the first time.
func _ready():
    Sports = true
    Suv = false
    nissian = false
    Hatchback = false
    SixbySix = false
    Limo = false
    garage.car_index = 1
    $SportsCar/SportsCar.entering = true


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#   pass
func _input(event):
    if Input.is_action_just_pressed("ui_right"):
        next_car()
        $ChangingVehicles.start()   
        if Sports == true: 
            Sports = false
        elif Suv == true:
            Suv = false
        elif nissian == true:
            nissian = false
        elif Hatchback == true:
            Hatchback = false
        elif SixbySix == true:
            SixbySix = false
        elif Limo == true:
            Limo = false
        print(garage.car_index)
    elif Input.is_action_just_pressed("ui_left"):
        previous_car()
        $ChangingVehicles.start()   
        if Sports == true: 
            Sports = false
        elif Suv == true:
            Suv = false
        elif nissian == true:
            nissian = false
        elif Hatchback == true:
            Hatchback = false
        elif SixbySix == true:
            SixbySix = false
        elif Limo == true:
            Limo = false
        print(garage.car_index)
#Checks when the next arrow button is clicked. It will test which car is currently active and change it to play it's exit animation
func _on_next_pressed():

    if Sports == true: 
        Sports = false
    elif Suv == true:
        Suv = false
    elif nissian == true:
        nissian = false
    elif Hatchback == true:
        Hatchback = false
    elif SixbySix == true:
        SixbySix = false
    elif Limo == true:
        Limo = false



func _on_Previous_pressed(): #Will repeat what the next_button function did but will go to the previous car instead
#   Sports = true
#   $SportsCar/SportsCar.entering = true
#   Suv = false
    pass


func _process(delta):
    if Sports == true: #Checks what car is active
        if $SportsCar/SportsCar.entering == true:
            $SportsCar/SportsCar/AnimationPlayer.play("Enter") #Drives fowards onto the podium
        if $SportsCar/SportsCar.rotating == true:
            $SportsCar/SportsCar/AnimationPlayer.play("Rotate") #Rotates until next or previous button is selected
    elif Sports == false:
        if $SportsCar/SportsCar.rotating == true:
            $SportsCar/SportsCar/AnimationPlayer.play("Rotate") 
            #Wait until the car is facing fowards before driving off
            if ($SportsCar/SportsCar.rotation_degrees.y >= 359 && $SportsCar/SportsCar.rotation_degrees.y < 360 ): 
                $SportsCar/SportsCar/AnimationPlayer.stop()
                $SportsCar/SportsCar.rotating = false
                $SportsCar/SportsCar.exiting = true
                $SportsCar/SportsCar/AnimationPlayer.play("Exit") #Moves the car off the podium
                $SportsCar/SportsCar.exiting = false
                $SportsCar/SportsCar.rotating = false
                $SportsCar/SportsCar.entering = false
    if Suv == true:

        if $SUV/SUV.entering == true:
            $SUV/SUV/AnimationPlayer.play("Enter")
        if $SUV/SUV.rotating == true:
            $SUV/SUV/AnimationPlayer.play("Rotate")
    elif Suv == false:
            if $SUV/SUV.rotating == true:
                $SUV/SUV/AnimationPlayer.play("Rotate")
                if ($SUV/SUV.rotation_degrees.y >= 359 && $SUV/SUV.rotation_degrees.y < 360 ):
                    $SUV/SUV/AnimationPlayer.stop()
                    $SUV/SUV.rotating = false
                    $SUV/SUV.exiting = true
                    $SUV/SUV/AnimationPlayer.play("Exit")
                    $SUV/SUV.exiting = false
                    $SUV/SUV.rotating = false
                    $SUV/SUV.entering = false
    if nissian == true:
        if $Nissian/Nissian.entering == true:
            $Nissian/Nissian/AnimationPlayer.play("Enter")
        if $Nissian/Nissian.rotating == true:
            $Nissian/Nissian/AnimationPlayer.play("Rotate")
    elif nissian == false:
            if $Nissian/Nissian.rotating == true:
                $Nissian/Nissian/AnimationPlayer.play("Rotate")
                if ($Nissian/Nissian.rotation_degrees.y >= 359 && $Nissian/Nissian.rotation_degrees.y < 360 ):
                    $Nissian/Nissian/AnimationPlayer.stop()
                    $Nissian/Nissian.rotating = false
                    $Nissian/Nissian.exiting = true
                    $Nissian/Nissian/AnimationPlayer.play("Exit")
                    $Nissian/Nissian.exiting = false
                    $Nissian/Nissian.rotating = false
                    $Nissian/Nissian.entering = false
    if Hatchback == true:
        if $BMW/BMW.entering == true:
            $BMW/BMW/AnimationPlayer.play("Enter")
        if $BMW/BMW.rotating == true:
            $BMW/BMW/AnimationPlayer.play("Rotate")
    elif Hatchback == false:
            if $BMW/BMW.rotating == true:
                $BMW/BMW/AnimationPlayer.play("Rotate")
                if ($BMW/BMW.rotation_degrees.y >= 359 && $BMW/BMW.rotation_degrees.y < 360 ):
                    $BMW/BMW/AnimationPlayer.stop()
                    $BMW/BMW.rotating = false
                    $BMW/BMW.exiting = true
                    $BMW/BMW/AnimationPlayer.play("Exit")
                    $BMW/BMW.exiting = false
                    $BMW/BMW.rotating = false
                    $BMW/BMW.entering = false

    if SixbySix == true:
        if $SixbySix/SixbySix.entering == true:
            $SixbySix/SixbySix/AnimationPlayer.play("Enter")
        if $SixbySix/SixbySix.rotating == true:
            $SixbySix/SixbySix/AnimationPlayer.play("Rotate")
    elif SixbySix == false:
            if $SixbySix/SixbySix.rotating == true:
                $SixbySix/SixbySix/AnimationPlayer.play("Rotate")
                if ($SixbySix/SixbySix.rotation_degrees.y >= 359 && $SixbySix/SixbySix.rotation_degrees.y < 360 ):
                    $SixbySix/SixbySix/AnimationPlayer.stop()
                    $SixbySix/SixbySix.rotating = false
                    $SixbySix/SixbySix.exiting = true
                    $SixbySix/SixbySix/AnimationPlayer.play("Exit")
                    $SixbySix/SixbySix.exiting = false
                    $SixbySix/SixbySix.rotating = false
                    $SixbySix/SixbySix.entering = false
    if Limo == true: #Checks what car is active
        if $Limo/Limo.entering == true:
            $Limo/Limo/AnimationPlayer.play("Enter") #Drives fowards onto the podium
        if $Limo/Limo.rotating == true:
            $Limo/Limo/AnimationPlayer.play("Rotate") #Rotates until next or previous button is selected
    elif Limo == false:
        if $Limo/Limo.rotating == true:
            $Limo/Limo/AnimationPlayer.play("Rotate") 
            #Wait until the car is facing fowards before driving off
            if ($Limo/Limo.rotation_degrees.y >= 359 && $Limo/Limo.rotation_degrees.y < 360 ): 
                $Limo/Limo/AnimationPlayer.stop()
                $Limo/Limo.rotating = false
                $Limo/Limo.exiting = true
                $Limo/Limo/AnimationPlayer.play("Exit") #Moves the car off the podium
                $Limo/Limo.exiting = false
                $Limo/Limo.rotating = false
                $Limo/Limo.entering = false
func next_car(): #Checks if the index - (number of vehicles) is less than the max ammount before adding 1 or resets to 1 if index is at max
    if garage.car_index < 6:
        garage.car_index += 1
    elif garage.car_index == 6:
        garage.car_index = 1
    #the garage prefix is an autoload variable so the same values can easily be accessed in other scripts
func previous_car(): #Checks if the index - (number of vehicles) is less than the max ammount before adding 1 or resets to 1 if index is at max
    if garage.car_index > 1:
        garage.car_index -= 1
    elif garage.car_index == 1:
        garage.car_index = 6


func _on_ChangingVehicles_timeout(): #CHANGING NEXT
    print('timeout')
 #Starts the function to find the new index
    print(garage.car_index)
    if garage.car_index == 1: #Porshe/Taxi
        Sports = true
        $SportsCar/SportsCar.entering = true
        Suv = false
        nissian = false
        Hatchback = false
        SixbySix = false
        Limo = false
        $Selection/AnimationPlayer.play("index 1") #User interface animation. Will Play the animation depending on the current selection
    if garage.car_index == 2: #SUV
        Suv = true
        $SUV/SUV.entering = true
        Sports = false
        nissian = false
        Hatchback = false
        SixbySix = false
        Limo = false

        $Selection/AnimationPlayer.play("index 2")
    if garage.car_index == 3: #Nissian
        nissian = true #Sets Correct vehicle to the active vehicle and sets others to false
        Sports = false
        Suv = false
        Hatchback = false
        SixbySix = false
        Limo = false
        $Nissian/Nissian.entering = true

        $Selection/AnimationPlayer.play("index 3")
    if garage.car_index == 4: #BMW Hatchback
        nissian = false
        Sports = false
        Suv = false
        Hatchback = true
        SixbySix = false
        Limo = false
        $BMW/BMW.entering = true
        $Selection/AnimationPlayer.play("index 4")
        if PlayerData.player.CityBonus == "locked":
            $Loadscene.disabled = true
        elif PlayerData.player.CityBonus == "completed":
            $Loadscene.disabled = false
    if garage.car_index == 5: #6x6
        nissian = false
        Sports = false
        Suv = false
        Hatchback = false
        SixbySix = true
        Limo = false
        $SixbySix/SixbySix.entering = true
        $Selection/AnimationPlayer.play("index 5")
    if garage.car_index == 6: #Limo
        nissian = false
        Sports = false
        Suv = false
        Hatchback = false
        SixbySix = false
        Limo = true
        $Limo/Limo.entering = true
        $Selection/AnimationPlayer.play("index 6")
#       $Selection/AnimationPlayer.play("index 4")
    $ChangingVehicles.wait_time = 5 # a 5 second wait for the car to fully spin around before the next car will drive over
    $ChangingVehicles.stop()

Link to the github project:
https://github.com/chaben11/CTDrivingGameProject

Godot version 3.3.2.stable
in Engine by (39 points)

Sorry to break this to you, but your code is a programmer's worst nightmare. Like, I-wake-up-in-the-middle-of-the-night-sweating kind of nightmare. It is not exactly readable and there are tons of unnecessary repetitions, which make it hard to debug. Here is a suggestion which is not directly connected to your question, but will help you debug your code nonetheless:

Use lists/classes/dictionaries instead of single variables to create the desired behavior. That way you won't have to write endless if/else statements for every single object. Instead you will be able to set attributes from lists .You can think of it as a table where you have objects in the horizontal axis and attributes in the vertical one. Then it is just a matter of changing these values by defining a single function that takes the selected object as an argument and iterates through said list/dictionary. Or use classes where you set each attribute only once. Right now you have to check what each car's type is multiple times. What if you want to add more cars in the future? will you rewrite the same code 1000 times?

Having said that I think that the problem might be the fact that your condition for a car exiting the scene is too restrictive. I mean, if the rotation is between 359 and 360 degrees and if it rotating is true. It might be the case that the degrees are never registed correctly, thus preventing the current car from leaving the scene. Your code is also unresponsive, since pressing the buttons sometimes does nothing or is very slow at best.

I would go for a simpler approach where I would put all available cars in a list and when the button is pressed, I would check the previous index in that list and trigger the animation of the car corresponding to that index. Then I would instruct the current car to turn towards the exit point (instead of waiting for it to turn on its own) and leave. Right now the game waits until all conditions are met before it does anything, which is buggy.

If this comment answers your question, let me know so that I can turn it into an answer.

Thank you. I will have a look and see if I can use your suggestion

Please log in or register to answer this question.

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.