RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
putt_putt_device_manager.gd
Go to the documentation of this file.
1extends RefCounted
2
3
6
7
8func resolve_devices(objects:Array, ball_position:Vector2, ball_velocity:Vector2, tile_size:float, elapsed:float) -> Dictionary:
9 var next_velocity:Vector2 = ball_velocity
10 var message:String = ""
11 var hit_id:String = ""
12 for object_row in objects:
13 if not object_row is Dictionary:
14 continue
15 var center:Vector2 = object_row.get("_world_center", Vector2.ZERO)
16 if center == Vector2.ZERO:
17 continue
18 match str(object_row.get("kind", "")):
19 "bumper":
20 var radius:float = float(object_row.get("radius", 0.45)) * tile_size
21 if ball_position.distance_to(center) <= radius:
22 var normal:Vector2 = (ball_position - center).normalized()
23 if normal == Vector2.ZERO:
24 normal = Vector2.UP
25 next_velocity = ball_velocity.bounce(normal) * float(object_row.get("bounce", 1.15))
26 message = "Bumper bounce."
27 hit_id = str(object_row.get("id", "bumper"))
28 break
29 "course_device":
30 var device:String = str(object_row.get("device", ""))
31 match device:
32 "bounce_pad":
33 var pad_radius:float = max(8.0, tile_size * 0.42)
34 if ball_position.distance_to(center) <= pad_radius:
35 next_velocity = ball_velocity * float(object_row.get("impulse", 1.4))
36 message = "Bounce pad launched the ball."
37 hit_id = str(object_row.get("id", "bounce_pad"))
38 break
39 "windmill":
40 var blade_open:bool = fmod(elapsed, float(object_row.get("cycle_time", 2.0))) < float(object_row.get("cycle_time", 2.0)) * 0.5
41 var windmill_radius:float = max(10.0, tile_size * 0.48)
42 if not blade_open and ball_position.distance_to(center) <= windmill_radius:
43 var wind_normal:Vector2 = (ball_position - center).normalized()
44 if wind_normal == Vector2.ZERO:
45 wind_normal = Vector2.LEFT
46 next_velocity = ball_velocity.bounce(wind_normal) * 0.75
47 message = "Windmill says not today."
48 hit_id = str(object_row.get("id", "windmill"))
49 break
50 "fan":
51 var fan_radius:float = max(10.0, tile_size * 0.55)
52 if ball_position.distance_to(center) <= fan_radius:
53 next_velocity = ball_velocity + _direction_vector(str(object_row.get("direction", "up"))) * float(object_row.get("force", 90.0))
54 message = "Fan nudged the ball."
55 hit_id = str(object_row.get("id", "fan"))
56 break
57 "water_wheel":
58 var wheel_radius:float = max(10.0, tile_size * 0.52)
59 if ball_position.distance_to(center) <= wheel_radius:
60 var redirect:Vector2 = Vector2(-ball_velocity.y, ball_velocity.x)
61 if bool(object_row.get("reverse", false)):
62 redirect = Vector2(ball_velocity.y, -ball_velocity.x)
63 next_velocity = redirect.normalized() * max(ball_velocity.length(), float(object_row.get("minimum_speed", 120.0)))
64 message = "Water wheel redirected the ball."
65 hit_id = str(object_row.get("id", "water_wheel"))
66 break
67 return {
68 "velocity": next_velocity,
69 "hit": hit_id != "",
70 "hit_id": hit_id,
71 "message": message
72 }
73
74
75func _direction_vector(direction:String) -> Vector2:
76 match direction:
77 "down":
78 return Vector2.DOWN
79 "left":
80 return Vector2.LEFT
81 "right":
82 return Vector2.RIGHT
83 _:
84 return Vector2.UP