Add collision detection and response
parent
e6959f05ec
commit
c1447c4de2
84
main.lua
84
main.lua
|
|
@ -30,6 +30,25 @@ local function get_next_bubble_type(index, remaining_bubble_types)
|
||||||
return remaining_bubble_types[love.math.random(#remaining_bubble_types)]
|
return remaining_bubble_types[love.math.random(#remaining_bubble_types)]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function find_nearest_slot(x, y)
|
||||||
|
local nearest_slot_index = 0
|
||||||
|
local min_dist = math.huge
|
||||||
|
for i = 1, #game.bubble_slots do
|
||||||
|
local slot = game.bubble_slots[i]
|
||||||
|
if slot.bubble_type == 0 then
|
||||||
|
local diff_x = x - slot.x
|
||||||
|
local diff_y = y - slot.y
|
||||||
|
local dist = math.sqrt(diff_x * diff_x + diff_y * diff_y)
|
||||||
|
if dist < min_dist then
|
||||||
|
min_dist = dist
|
||||||
|
nearest_slot_index = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(nearest_slot_index ~= 0, "no nearest slot found")
|
||||||
|
return nearest_slot_index
|
||||||
|
end
|
||||||
|
|
||||||
function love.load(arg)
|
function love.load(arg)
|
||||||
game.window_width, game.window_height = love.graphics.getDimensions()
|
game.window_width, game.window_height = love.graphics.getDimensions()
|
||||||
|
|
||||||
|
|
@ -130,8 +149,69 @@ end
|
||||||
function love.update(dt)
|
function love.update(dt)
|
||||||
if game.paused then return end
|
if game.paused then return end
|
||||||
if game.next_bubble.velocity_x ~= 0 or game.next_bubble.velocity_y ~= 0 then
|
if game.next_bubble.velocity_x ~= 0 or game.next_bubble.velocity_y ~= 0 then
|
||||||
game.next_bubble.x = game.next_bubble.x + game.next_bubble.velocity_x * dt
|
local next_x = game.next_bubble.x + game.next_bubble.velocity_x * dt
|
||||||
game.next_bubble.y = game.next_bubble.y + game.next_bubble.velocity_y * dt
|
local next_y = game.next_bubble.y + game.next_bubble.velocity_y * dt
|
||||||
|
local collision_detection_finished = false
|
||||||
|
|
||||||
|
-- collision with ceiling
|
||||||
|
if next_y - game.bubble_radius <= game.level_top then
|
||||||
|
local nearest_slot_index = find_nearest_slot(next_x, next_y)
|
||||||
|
game.next_bubble.x = game.bubble_slots[nearest_slot_index].x
|
||||||
|
game.next_bubble.y = game.bubble_slots[nearest_slot_index].y
|
||||||
|
game.next_bubble.velocity_x = 0
|
||||||
|
game.next_bubble.velocity_y = 0
|
||||||
|
collision_detection_finished = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- collision with wall
|
||||||
|
if not collision_detection_finished then
|
||||||
|
if next_x + game.bubble_radius >= game.level_right or
|
||||||
|
next_x - game.bubble_radius <= game.level_left then
|
||||||
|
local impact_x = game.level_left + game.bubble_radius
|
||||||
|
if next_x + game.bubble_radius >= game.level_right then
|
||||||
|
impact_x = game.level_right - game.bubble_radius
|
||||||
|
end
|
||||||
|
local dx = impact_x - game.next_bubble.x
|
||||||
|
local ratio = dx / game.next_bubble.velocity_x * dt
|
||||||
|
local dy = game.next_bubble.velocity_y * dt * ratio
|
||||||
|
local impact_y = game.next_bubble.y + dy
|
||||||
|
local ratio_after_bounce = 1.0 - ratio
|
||||||
|
game.next_bubble.velocity_x = -game.next_bubble.velocity_x
|
||||||
|
next_x = impact_x + game.next_bubble.velocity_x * dt * ratio_after_bounce
|
||||||
|
next_y = impact_y + game.next_bubble.velocity_y * dt * ratio_after_bounce
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- collision with another bubble
|
||||||
|
if not collision_detection_finished then
|
||||||
|
for i = 1, #game.bubble_slots do
|
||||||
|
local slot = game.bubble_slots[i]
|
||||||
|
if slot.bubble_type ~= 0 then
|
||||||
|
local diff_x = next_x - slot.x
|
||||||
|
local diff_y = next_y - slot.y
|
||||||
|
local dist = math.sqrt(diff_x * diff_x + diff_y * diff_y)
|
||||||
|
if dist <= game.bubble_diameter then
|
||||||
|
local depth = game.bubble_diameter - dist
|
||||||
|
local direction_x = diff_x / dist
|
||||||
|
local direction_y = diff_y / dist
|
||||||
|
next_x = next_x + direction_x * depth
|
||||||
|
next_y = next_y + direction_y * depth
|
||||||
|
local nearest_slot_index = find_nearest_slot(next_x, next_y)
|
||||||
|
game.next_bubble.x = game.bubble_slots[nearest_slot_index].x
|
||||||
|
game.next_bubble.y = game.bubble_slots[nearest_slot_index].y
|
||||||
|
game.next_bubble.velocity_x = 0
|
||||||
|
game.next_bubble.velocity_y = 0
|
||||||
|
collision_detection_finished = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not collision_detection_finished then
|
||||||
|
game.next_bubble.x = next_x
|
||||||
|
game.next_bubble.y = next_y
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if game.frame_by_frame then
|
if game.frame_by_frame then
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue