# frozen_string_literal: true # Handles physics simulation. class Physics def update(actors) actors.each do |actor| [0, 1].each do |axis| actor.position[axis] += actor.velocity[axis] actor.velocity[axis] *= 0.5 actors.each do |other| next unless actor != other && collide?(actor, other) fix_position_of(actor, other, axis) end end end end private def collide?(actor, other) return false unless collide_for_axis?(actor, other, 0) return false unless collide_for_axis?(actor, other, 1) actor_is_solid = actor.collide(other) other_is_solid = other.collide(actor) actor_is_solid && other_is_solid end def collide_for_axis?(actor, other, axis) foo = actor.position[axis] bar = other.position[axis] foo_size = actor.aabb[axis] * 0.5 bar_size = other.aabb[axis] * 0.5 foo - foo_size < bar + bar_size && foo + foo_size > bar - bar_size end def fix_position_of(actor, other, axis) offset = (actor.aabb[axis] + other.aabb[axis]) * 0.5 offset *= -1 if actor.velocity[axis].positive? actor.position[axis] = other.position[axis] + offset end end