From df97902906e25d10bee217b7d36f7c20a1e9a2c8 Mon Sep 17 00:00:00 2001 From: Tyler Scott Date: Wed, 9 Feb 2022 08:06:39 +0700 Subject: [PATCH] Put bubble movement code in its own function --- main.lua | 141 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 59 deletions(-) diff --git a/main.lua b/main.lua index 59b814d..7c48817 100644 --- a/main.lua +++ b/main.lua @@ -108,6 +108,73 @@ local function find_nearest_slot(x, y) return nearest_slot_index end +local function move_bubble(x, y, velocity_x, velocity_y) + local start_time = love.timer.getTime() + local new_x = x + velocity_x + local new_y = y + velocity_y + local new_velocity_x = velocity_x + local new_velocity_y = velocity_y + local should_stop = false + + -- collision with ceiling + if new_y - game.bubble_radius <= game.level_top then + should_stop = true + end + + -- collision with walls + if not should_stop then + if new_x + game.bubble_radius >= game.level_right or + new_x - game.bubble_radius <= game.level_left then + local impact_x = game.level_left + game.bubble_radius + if new_x + game.bubble_radius >= game.level_right then + impact_x = game.level_right - game.bubble_radius + end + local dx = impact_x - x + local ratio = dx / new_velocity_x + local dy = new_velocity_y * ratio + local impact_y = y + dy + local ratio_after_bounce = 1.0 - ratio + new_velocity_x = -new_velocity_x + new_x = impact_x + new_velocity_x * ratio_after_bounce + new_y = impact_y + new_velocity_y * ratio_after_bounce + end + end + + -- collision with another bubble + if not should_stop then + for i = 1, #game.bubble_slots do + local slot = game.bubble_slots[i] + if slot.bubble_type ~= 0 then + local diff_x = new_x - slot.x + local diff_y = new_y - slot.y + local dist = math.sqrt(diff_x * diff_x + diff_y * diff_y) + if dist <= game.bubble_diameter - 3 then -- -3 to allow squeezing through + should_stop = true + break + end + end + end + end + + local nearest_slot_index = 0 + if should_stop then + nearest_slot_index = find_nearest_slot(new_x, new_y) + new_x = game.bubble_slots[nearest_slot_index].x + new_y = game.bubble_slots[nearest_slot_index].y + new_velocity_x = 0 + new_velocity_y = 0 + end + -- print(string.format("%.10f", love.timer.getTime() - start_time)) + + return { + x = new_x, + y = new_y, + velocity_x = new_velocity_x, + velocity_y = new_velocity_y, + should_stop = should_stop, + nearest_slot_index = nearest_slot_index + } +end local function find_matches(start_index) local bubble_type = game.bubble_slots[start_index].bubble_type local to_check = {start_index} @@ -280,64 +347,24 @@ function love.update(dt) if game.next_bubble and (game.next_bubble.velocity_x ~= 0 or game.next_bubble.velocity_y ~= 0) then - local next_x = game.next_bubble.x + game.next_bubble.velocity_x - local next_y = game.next_bubble.y + game.next_bubble.velocity_y - local bubble_should_stop = false + local movement_info - -- collision with ceiling - if next_y - game.bubble_radius <= game.level_top then - bubble_should_stop = true - end + movement_info = move_bubble( + game.next_bubble.x, + game.next_bubble.y, + game.next_bubble.velocity_x, + game.next_bubble.velocity_y + ) + game.next_bubble.x = movement_info.x + game.next_bubble.y = movement_info.y + game.next_bubble.velocity_x = movement_info.velocity_x + game.next_bubble.velocity_y = movement_info.velocity_y - -- collision with walls - if not bubble_should_stop 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 - local dy = game.next_bubble.velocity_y * 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 * ratio_after_bounce - next_y = impact_y + game.next_bubble.velocity_y * ratio_after_bounce - end - end + if movement_info.should_stop then + game.bubble_slots[movement_info.nearest_slot_index].bubble_type = + game.next_bubble.bubble_type - -- collision with another bubble - if not bubble_should_stop 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 - 2 then -- -2 to allow squeezing through - 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 - bubble_should_stop = true - break - end - end - end - end - - if bubble_should_stop 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 - game.bubble_slots[nearest_slot_index].bubble_type = game.next_bubble.bubble_type - - local matches = find_matches(nearest_slot_index) + local matches = find_matches(movement_info.nearest_slot_index) if #matches >= 3 then game.next_bubble = nil @@ -391,10 +418,6 @@ function love.update(dt) velocity_y = 0 } end - - else - game.next_bubble.x = next_x - game.next_bubble.y = next_y end end