A game created for the Godot Wild Jam #21

176 lines
5.7KB

  1. extends RigidBody2D
  2. const COLLISION_MINOR_SPEED_THRESHOLD = 8
  3. const COLLISION_MAJOR_SPEED_THRESHOLD = 32
  4. const COLLISION_TIMEDT_THRESHOLD = 0.1
  5. # The maximum distance from the player in which the mouse will adjust the push force.
  6. # at max_mouse_distance the full base_push_force <+ modifiers> will be applied.
  7. export var max_mouse_distance = 256 setget _set_max_mouse_distance
  8. # The maximum the mouse can be from the player before player becomes "uncomfortable"
  9. # (adjusted by mood)
  10. export var max_comfort_distance = 10 setget _set_max_comfort_distance
  11. # The base tangential acceleration that will be applied to the particles to give the
  12. # player the illusion it's trying to move on it's own. This is just effects things visually (ATM)
  13. export var base_tangential_accel = 32 setget _set_base_tangential_accel
  14. # The base force applied when being pushed.
  15. export var base_push_force = 128 setget _set_base_push_force
  16. # Mood = r: <aggression>, g: <neediness>, b: <contentment>
  17. # <aggression> Affects how strong a players push is and how strong the player's collision with the world will be.
  18. # <neediness> Affects how quickly and strongly the player will follow the mouse
  19. # <contentment> Affects how slowly mood color is shifted back to neutral and widens comfort distance
  20. var mood = Color.black
  21. var neutral_rim = Color(0.9, 0.9, 0.9, 1.0)
  22. var mouse_position = Vector2.ZERO
  23. var mouse_down = false
  24. var push = false
  25. var in_air = true
  26. var air_time = 0
  27. var last_speed = 0
  28. func set_colors(prime, alt):
  29. if alt.r != alt.g or alt.r != alt.b:
  30. # only change the rim if there's a single dominant color.
  31. $Sprite.material.set_shader_param("rim_color", alt);
  32. $Particles.process_material.color = alt
  33. if prime.r != prime.g or prime.r != prime.b: # Only adjust mood if not all values are the same.
  34. # Even if not all the same, there must be a single dominant color for mood to be adjusted.
  35. if prime.r > prime.g and prime.r > prime.b:
  36. adjust_mood(Vector3(0.25, 0.0, 0.0))
  37. if prime.g > prime.r and prime.g > prime.b:
  38. adjust_mood(Vector3(0.0, 0.25, 0.0))
  39. if prime.b > prime.r and prime.b > prime.g:
  40. adjust_mood(Vector3(0.0, 0.0, 0.25));
  41. func get_colors():
  42. return {
  43. "prime": $Sprite.material.get_shader_param("cell_color"),
  44. "alt": $Sprite.material.get_shader_param("rim_color")
  45. };
  46. func adjust_mood(mv):
  47. mood.x = clamp(mood.x + mv.x, 0.0, 1.0)
  48. mood.y = clamp(mood.y + mv.y, 0.0, 1.0)
  49. mood.z = clamp(mood.z + mv.z, 0.0, 1.0)
  50. var color = Color(mood.x, mood.y, mood.z, 1.0)
  51. $Sprite.material.set_shader_param("cell_color", color);
  52. func get_tangential_acceleration():
  53. return base_tangential_accel
  54. func get_push_force():
  55. return base_push_force
  56. func get_discomfort():
  57. pass
  58. func get_body_radius():
  59. return $CollisionShape2D.shape.radius
  60. func _set_max_mouse_distance(v):
  61. var br = $CollisionShape2D.shape.radius
  62. max_mouse_distance = max(br * 2, v)
  63. func _set_max_comfort_distance(v):
  64. var br = $CollisionShape2D.shape.radius
  65. max_comfort_distance = max(br, v)
  66. func _set_base_tangential_accel(v):
  67. base_tangential_accel = max(1.0, v)
  68. func _set_base_push_force(v):
  69. base_push_force = max(1.0, v)
  70. # Called when the node enters the scene tree for the first time.
  71. func _ready():
  72. set_process(true)
  73. set_physics_process(true)
  74. set_process_input(true)
  75. $Sprite.material.set_shader_param("rim_color", neutral_rim);
  76. $Particles.process_material.color = neutral_rim
  77. func _input(event):
  78. if event is InputEventMouseMotion:
  79. mouse_position = get_global_mouse_position()
  80. if Input.is_action_just_pressed("ButtonA"):
  81. mouse_down = true
  82. elif Input.is_action_just_released("ButtonA"):
  83. mouse_down = false
  84. push = true
  85. func _shift_mood(delta):
  86. # This should shift the mood color back to black.
  87. # called py the _physics_process method (I could use the _process method, but I don't
  88. # want to possibly mix timings)
  89. pass
  90. func _physics_process(delta):
  91. if mouse_down:
  92. return # We don't follow the mouse or move the squiq when mouse is down.
  93. if push:
  94. push = false
  95. var v_direction = (position - mouse_position).normalized()
  96. apply_central_impulse(v_direction * abs(v_direction.length()) * get_push_force())
  97. elif in_air:
  98. air_time += delta
  99. else:
  100. var distance = clamp(mouse_position.x - position.x, -max_mouse_distance, max_mouse_distance)
  101. var dpercent = distance / max_mouse_distance
  102. if abs(distance) > get_body_radius():
  103. var v_horizontal = Physics2DServer.area_get_param(get_world_2d().get_space(), Physics2DServer.AREA_PARAM_GRAVITY_VECTOR).rotated(deg2rad(-90))
  104. $Particles.process_material.tangential_accel = dpercent * get_tangential_acceleration();
  105. apply_central_impulse(v_horizontal * distance * delta)
  106. else:
  107. $Particles.process_material.tangential_accel = 0
  108. last_speed = linear_velocity.length()
  109. #print(last_speed)
  110. func _process(delta):
  111. update()
  112. func _draw():
  113. if mouse_down:
  114. var distance = min(position.distance_to(mouse_position), max_mouse_distance)
  115. var v_direction = (position - mouse_position).normalized().rotated(-rotation)
  116. var v_start = v_direction * get_body_radius()
  117. var v_end = v_direction * distance
  118. var v_tipA = v_end - (v_direction.rotated(deg2rad(30)) * min(distance, 16))
  119. var v_tipB = v_end - (v_direction.rotated(-deg2rad(30)) * min(distance, 16))
  120. var c_line = Color(0.25, 1.0, 0.0)
  121. draw_line(v_start, v_end, c_line)
  122. draw_line(v_end, v_tipA, c_line)
  123. draw_line(v_end, v_tipB, c_line)
  124. func _on_Player_body_entered(body):
  125. in_air = false
  126. #print(linear_velocity)
  127. if air_time > COLLISION_TIMEDT_THRESHOLD:
  128. var lvlen = linear_velocity.length()
  129. if lvlen >= COLLISION_MINOR_SPEED_THRESHOLD and lvlen < COLLISION_MAJOR_SPEED_THRESHOLD:
  130. print("ooOF")
  131. elif lvlen >= COLLISION_MAJOR_SPEED_THRESHOLD:
  132. print("Oooooch!")
  133. air_time = 0
  134. func _on_Player_body_exited(body):
  135. in_air = true