• Godot Help2D
  • Wanting to add timer to confirm selection of object (Rock Paper Scissors)

Hi folks, I'm working on recreating the classic Rock Paper Scissors scenes seen in Alex Kidd in Miracle World, and what I'd like to do is figure out how to add a timer so that when the time runs out it keeps the choice I made between Rock Paper and Scissors. I've got a large amount of the code (taken from an awesome course on how to make a basic Rock Paper Scissors game courtesy of Canopy Games) and help from some lovely people in Adelaide Game Developer discord on how to scroll between scenes for the player as well.

Once I can figure that out, I'll look at how to get the opponent to show their choice. Code and screenshots as follow:

Globals.gd (autoload name is gl in case you wonder why so much "gl"'ing going on in the code:

extends Node
var rock = preload("res://Scenes/rock.tscn")
var paper = preload("res://Scenes/paper.tscn")
var scissors = preload("res://Scenes/scissors.tscn")
var array = [rock, paper, scissors]
var objidx:int = 0
var currobjref

player.gd:

extends CharacterBody2D
@onready var janken_container = $JankenContainer
func _process(delta):
    if Input.is_action_just_pressed("up"):
        _scroll(1)
    elif Input.is_action_just_pressed("down"):
        _scroll(-1)
func _scroll(delta: int) -> void:
    gl.objidx = (gl.objidx+delta) % gl.array.size()
    var newobj = gl.array[gl.objidx].instantiate()
    if (gl.currobjref):
        gl.currobjref.queue_free()
    gl.currobjref = newobj
    janken_container.add_child(newobj)
    newobj.global_position = global_position
    newobj.global_position.x += 0
    newobj.global_position.y -= 60

and opponent.gd:

extends Node2D
@onready var jankenoppcontainer = $jankoppcontainer
var delay:float = 0.5
var possible_choices:Array[String]
var opponent_choice
var player_choice
var timer_stage:int = 0
func _ready():
    possible_choices = [gl.rock, gl.paper, gl.scissors]
func _process(delta):
    if Input.is_action_just_pressed("ui_up"):
        opponent_scroll(1)
    elif Input.is_action_just_pressed("ui_down"):
        opponent_scroll(-1)    
 func opponent_scroll(delta: int) -> void:
    gl.objidx = (gl.objidx+delta) % gl.array.size()
    var newobj = gl.array[gl.objidx].instantiate()
    if (gl.currobjref):
        gl.currobjref.queue_free()
    gl.currobjref = newobj
func display_opponent_choice(jankenoppcontainer):
    jankenoppcontainer.show
    player_choice = jankenoppcontainer
    pick_action()
    print("You picked " + player_choice)
    await get_tree().create_timer(delay).timeout
    check_winner()
    await get_tree().create_timer(delay).timeout
    jankenoppcontainer.add_child(gl.newobj)
    gl.newobj.global_position = global_position
    gl.newobj.global_position.x += 0
    gl.newobj.global_position.y -= 60
func pick_action():
    randomize()
    opponent_choice = possible_choices[randi() % possible_choices.size()]
func check_winner():
    if player_choice == gl.rock and opponent_choice == gl.scissors:
        player_wins()
    elif player_choice == gl.paper and opponent_choice == gl.rock:
        player_wins()
    elif player_choice == gl.scissors and opponent_choice == gl.paper:
        player_wins()
    elif player_choice == opponent_choice:
        tie()
    else:
        opponent_wins()
func player_wins():
    print("You Win!")
func opponent_wins():
    print("You Lose!")
func tie():
    print("It's a Tie!")



It's way too hard to read your code with the indentation lost in the formatting.
Instead of single `s for each line, try
```
all
of
your
code
```
or just use the button that looks like </> to do it for you.

    award I did do that. So sorry! I’ll try again maybe I’ll post separate posts with each script if I can’t get that working.

    In addition to what @award said, your screenshots show several warning (yellow triangles). Don't ignore them! The may indicate that your node setup is broken in some way.

    Hopefully that makes the code easier to read. Incidentally the warning signs are referring to collision shapes which aren't needed in this instance as they're not interacting with each other. Or will I need collision shapes even if they're not physically interacting?

    • Zini replied to this.

      This probably has nothing to do with the problem, but this:

      if (gl.currobjref):
              gl.currobjref.queue_free()

      should be:

      if is_instance_valid(gl.currobjref):
              gl.currobjref.queue_free()

      But I'm not sure what kind of thing gl.currobjref is.

        DaveTheCoder

        Thank you! I believe it's meant to be current object reference. Happy to make the code simpler for just scrolling between scenes otherwise happy to give your suggested code a shot. 🙂

        And are you referring to the player or opponent code? Or both? Either way I added it to both.

        milktank81 If you don't need any form of physical interaction (including mouse picking) then obviously you don't need a CollisionShape. But if that is the case there is also no reason to use a CharacterBody.

          Zini So should I just use a sprite2D and/or animated sprite2D instead of a character body? Will that help with what I'm trying to achieve?

          • Zini replied to this.

            milktank81 Sprite2D and variants seems appropriate. That will not solve any issues. But at least it will remove the warnings so that you won't have to distinguish between "good" warnings and "bad" warnings late on. A project should always run warning-free.

              Zini

              Thanks the advice. I now recall that eventually I'd like them to be character shapes I move around in a top down world but that's at a later increment of progress. 🙂