| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- class_name Ball
- extends CharacterBody2D
- ## A ball that bounces off everything, speeds up slightly on each bounce and falls under
- ## light gravity.
- ## Emitted for every contact, so the game can react to what the ball touched.
- signal hit(ball: Ball, other: Node)
- ## A superball destroys one indestructible block, then turns back into a normal ball.
- var superball := false:
- set(value):
- superball = value
- queue_redraw()
- func throw() -> void:
- var angle := deg_to_rad(randf_range(-Params.THROW_ANGLE, Params.THROW_ANGLE))
- velocity = Vector2(sin(angle), -cos(angle)) * Params.INITIAL_SPEED
- func _physics_process(delta: float) -> void:
- velocity.y += Params.BALL_GRAVITY * delta
- var motion := velocity * delta
- for i in 4:
- var collision := move_and_collide(motion)
- if collision == null:
- break
- var other := collision.get_collider() as Node
- var normal := collision.get_normal()
- var bounce: float = other.get_meta("bounce", 1.0)
- velocity = velocity.bounce(normal) * Params.BALL_BOUNCE * bounce
- motion = collision.get_remainder().bounce(normal)
- hit.emit(self, other)
- if is_queued_for_deletion():
- return
- _kick_power_ups()
- ## Power-ups are 1/1000 of a ball's mass: they get knocked away and the ball doesn't notice.
- func _kick_power_ups() -> void:
- for power_up: PowerUp in get_tree().get_nodes_in_group("power_ups"):
- var offset := power_up.global_position - global_position
- var dist := offset.length()
- if dist == 0.0 or dist > Params.BALL_RADIUS + PowerUp.RADIUS:
- continue
- var normal := offset / dist
- var approach := (power_up.linear_velocity - velocity).dot(normal)
- if approach < 0.0:
- power_up.linear_velocity -= 2.0 * approach * normal
- hit.emit(self, power_up)
- func _draw() -> void:
- draw_circle(Vector2.ZERO, Params.BALL_RADIUS, Params.COLOR_ORANGE if superball else Params.COLOR_GREY, true, -1.0, true)
|