Godot Version
Godot 4.4
Question
I am working on a turn-based sumo game. If the player or AI character exit the ring, I want it to declare a winner and end the game. The issue I am encountering is that when a character is pushed out of the ring, the win_condition is not activated (lose_boundary.get_overlapping_bodies() still shows both characters). However, upon the next turn, the game is won/lost.
What I have tested so far:
- Are my collision shapes and Area3D shapes flawed?
-
- I am confident this is not the case. For example, when the AI is clearly outside the boundary and I go for another turn, the outcome results in my player character moving position, but not the AI. Nonetheless, it then triggers the game over. From this, I am fairly confident the issue is timing.
- Debugging I have tried
-
- call_deferred(“check_win_conditions”)
-
- lose_boundary.force_update_transform()
-
- await get_tree().physics_frame
-
- await get_tree().process_frame
func process_turn():
if not current_state == TurnState.PROCESSING_TURN:
current_state = TurnState.PROCESSING_TURN
print("Processing turn...")
# Ensure both wrestlers have selected a move
if player_rikishi.current_move == "" or ai_rikishi.current_move == "":
push_warning("Moves not selected for both Rikishi. Aborting turn.")
reset_turn() # Go back to waiting state
return
# Calculate the outcome based on moves
calculate_outcome(player_rikishi.current_move, ai_rikishi.current_move)
# Reset moves for the next turn
player_rikishi.reset_move()
ai_rikishi.reset_move()
# Check for win/loss conditions
check_win_conditions()
# Go back to waiting for input for the next turn
reset_turn()
print("Turn complete. Waiting for next input.")
# --- Win condition checks ---
##TODO: Not triggering correctly
func check_win_conditions():
## Check if players are still valid nodes
if !is_instance_valid(player_rikishi) or !is_instance_valid(ai_rikishi):
print("Error: One or more rikishi are invalid")
return
## A player is out if they're not inside the dohyo area
print(lose_boundary.get_overlapping_bodies())
var player_out = !lose_boundary.overlaps_body(player_rikishi)
var ai_out = !lose_boundary.overlaps_body(ai_rikishi)
if ai_out:
print("AI is outside the dohyo!")
game_over(true)
if player_out:
print("Player is outside the dohyo!")
game_over(false)
Below is how my wrestlers are moved:
func rotate_opponent_position(thrower: Node3D, opponent: Node3D):
var direction = opponent.global_transform.origin - thrower.global_transform.origin
var rotation_axis = Vector3.UP # Set Y-axis as basis of rotation
var clockwise_or_countercw = (randi() & 2) - 1 # Randomly determine if the rotation is clockwise (1) or counterclockwise (-1)
var rotated_direction = direction.rotated(rotation_axis, deg_to_rad(throw_rotation * clockwise_or_countercw))
opponent.global_transform.origin = thrower.global_transform.origin + rotated_direction
func push_calc(rikishi1: Node3D, rikishi2: Node3D, push_distance: float):
var direction = (rikishi2.global_transform.origin - rikishi1.global_transform.origin).normalized()
rikishi1.global_transform.origin += direction * push_distance
rikishi2.global_transform.origin += direction * push_distance
I am a beginner so I imagine there may be a better way to do this, so any advice is appreciated. My guess is that maybe by instantly moving the positions happens so quickly there is no time for the calculation to catch up. However, it seems that adding delays hasn’t worked (maybe I need more).