ball.gd 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. class_name Ball
  2. extends CharacterBody2D
  3. ## A ball that bounces off everything and speeds up slightly on each bounce.
  4. ## Emitted for every contact, so the game can react to what the ball touched.
  5. signal hit(ball: Ball, other: Node)
  6. ## A superball destroys one indestructible block, then turns back into a normal ball.
  7. var superball := false:
  8. set(value):
  9. superball = value
  10. queue_redraw()
  11. func throw() -> void:
  12. var angle := deg_to_rad(randf_range(-Params.THROW_ANGLE, Params.THROW_ANGLE))
  13. velocity = Vector2(sin(angle), -cos(angle)) * Params.INITIAL_SPEED
  14. func _physics_process(delta: float) -> void:
  15. var motion := velocity * delta
  16. for i in 4:
  17. var collision := move_and_collide(motion)
  18. if collision == null:
  19. break
  20. var other := collision.get_collider() as Node
  21. var normal := collision.get_normal()
  22. var bounce: float = other.get_meta("bounce", 1.0)
  23. velocity = velocity.bounce(normal) * Params.BALL_BOUNCE * bounce
  24. motion = collision.get_remainder().bounce(normal)
  25. hit.emit(self, other)
  26. if is_queued_for_deletion():
  27. return
  28. _kick_power_ups()
  29. ## Power-ups are 1/1000 of a ball's mass: they get knocked away and the ball doesn't notice.
  30. func _kick_power_ups() -> void:
  31. for power_up: PowerUp in get_tree().get_nodes_in_group("power_ups"):
  32. var offset := power_up.global_position - global_position
  33. var dist := offset.length()
  34. if dist == 0.0 or dist > Params.BALL_RADIUS + PowerUp.RADIUS:
  35. continue
  36. var normal := offset / dist
  37. var approach := (power_up.linear_velocity - velocity).dot(normal)
  38. if approach < 0.0:
  39. power_up.linear_velocity -= 2.0 * approach * normal
  40. hit.emit(self, power_up)
  41. func _draw() -> void:
  42. draw_circle(Vector2.ZERO, Params.BALL_RADIUS, Params.COLOR_ORANGE if superball else Params.COLOR_GREY, true, -1.0, true)