0
\$\begingroup\$

How can I spin a roulette wheel in a clockwise direction using a tween?

I've successfully managed to rotate counter-clockwise to the exact segment, but changing the direction to go clockwise is still a problem.

roulette wheel

extends Control


const DEGREES := 360.0
@onready var wheel := $Front as TextureRect

enum Directions {CCLOCKWISE=-1, CLOCKWISE=1}
@export var direction := Directions.CLOCKWISE
@export var segment_count := 8
@export var spin_time := 2.0
@export var spin_count := 1
var spinning := false


func spin(to_segment: int) -> void:
    if spinning:
        return
    spinning = true
    print(to_segment)
    randomize()
    var d := DEGREES / segment_count
    var r := d / 2
    var t := (to_segment-1) * d - r
    t += fposmod(wheel.rotation_degrees, DEGREES)
    #t += randf_range(0, d)  # add slight offset
    var target := wheel.rotation_degrees - (spin_count * DEGREES) - t

    var tween := create_tween().set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
    await tween.tween_property(wheel, "rotation_degrees", target, spin_time).finished
    spinning = false


func _input(event: InputEvent) -> void:
    if event is InputEventMouseButton:
        if event.pressed:
            spin(randi() % segment_count + 1)  # pick random segment

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

solved after some rest, now can work on both directions.

extends Control


const CIRCLE := 360.0
@onready var wheel := $Front as TextureRect

enum Directions {CCLOCKWISE=-1, CLOCKWISE=1}
@export var direction := Directions.CLOCKWISE
@export var segment_count := 8
@export var spin_time := 2.0
@export var spin_count := 1
var spinning := false


func spin(to_segment:=0) -> void:
    if spinning:
        return
    spinning = true

    if !to_segment: to_segment = randi() % segment_count + 1  # pick random segment if not prodived

    print(to_segment)
    var sd := CIRCLE / segment_count
    var rot := (to_segment-1) * sd - sd / 2
    rot += fposmod(wheel.rotation_degrees, CIRCLE)
    rot += randf_range(0, sd)  # pick random area in segment

    if direction == Directions.CCLOCKWISE:
        rot = fposmod(CIRCLE - rot, CIRCLE)

    var tween := create_tween().set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
    await tween.tween_property(
        wheel,
        "rotation_degrees",
        wheel.rotation_degrees + ((spin_count * CIRCLE) + rot) * -direction, spin_time
        ).finished
    spinning = false


func _input(event: InputEvent) -> void:
    if event is InputEventMouseButton:
        if event.pressed:
            randomize()
            spin()

```
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This answer would be even better if it included a brief summary of what you changed and why that solved the problem, to help future readers understand your solution. \$\endgroup\$
    – DMGregory
    Commented Dec 7 at 12:55
  • \$\begingroup\$ Maybe I'm not familiar enough with Godot here, but from the indentation, it looks like you set spinnging = true, and then after setting up the tweening via await, set spinning = false. Would that not be easier to set spinning = !to_segment: to_segment = randi() % segment_count + 1 and then check for spinning during the if statement? Or is the spinning = false part of .finished? \$\endgroup\$ Commented 18 hours ago

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .