218 lines
6.5 KiB
Lua
218 lines
6.5 KiB
Lua
local tau = math.pi * 2
|
|
local game = {}
|
|
|
|
local function load_level(level, bubble_diameter, row_gap)
|
|
if arg[#arg] == "debug" then require("lldebugger").start() end
|
|
|
|
local slots = {}
|
|
local bubble_radius = bubble_diameter / 2
|
|
|
|
-- set prev_num_cols to size of 2nd row so x_offset is correct when row == 1
|
|
local prev_num_cols = #level[2]
|
|
for row = 1, #level do
|
|
local num_cols = #level[row]
|
|
local x_offset = num_cols < prev_num_cols and bubble_radius or 0
|
|
for col = 1, num_cols do
|
|
slots[#slots+1] = {
|
|
x = x_offset + bubble_radius + (col - 1) * bubble_diameter,
|
|
y = bubble_radius + (row - 1) * row_gap,
|
|
bubble_type = level[row][col]
|
|
}
|
|
end
|
|
prev_num_cols = num_cols
|
|
end
|
|
|
|
return slots
|
|
end
|
|
|
|
-- ex. remaining_bubble_types = {1,4,5,8} -- should only be regular, not special
|
|
local function get_next_bubble_type(index, remaining_bubble_types)
|
|
return remaining_bubble_types[love.math.random(#remaining_bubble_types)]
|
|
end
|
|
|
|
function love.load(arg)
|
|
game.window_width, game.window_height = love.graphics.getDimensions()
|
|
|
|
game.bubble_diameter = 60
|
|
game.bubble_radius = game.bubble_diameter / 2
|
|
game.bubble_speed = 900 -- px/s
|
|
|
|
-- vertical distance between bubble center points
|
|
game.row_gap = math.ceil(math.sqrt(
|
|
(game.bubble_diameter * game.bubble_diameter) -
|
|
(game.bubble_radius * game.bubble_radius)
|
|
))
|
|
|
|
game.background_image = love.graphics.newImage('images/background.png')
|
|
game.background_width = game.background_image:getWidth()
|
|
|
|
game.bubble_images = {
|
|
love.graphics.newImage('images/red.png'), -- 1
|
|
love.graphics.newImage('images/orange.png'), -- 2
|
|
love.graphics.newImage('images/yellow.png'), -- 3
|
|
love.graphics.newImage('images/green.png'), -- 4
|
|
love.graphics.newImage('images/blue.png'), -- 5
|
|
love.graphics.newImage('images/purple.png'), -- 6
|
|
love.graphics.newImage('images/pink.png'), -- 7
|
|
love.graphics.newImage('images/white.png') -- 8
|
|
}
|
|
|
|
game.levels = {}
|
|
game.levels[1] = {
|
|
{1,1,1,3,3,2,2,2},
|
|
{ 1,1,3,3,3,2,2 },
|
|
{4,4,7,8,8,6,5,5},
|
|
{ 4,7,7,8,6,6,5 },
|
|
{0,0,0,0,0,0,0,0},
|
|
{ 0,0,0,0,0,0,0 },
|
|
{0,0,0,0,0,0,0,0},
|
|
{ 0,0,0,0,0,0,0 },
|
|
{0,0,0,0,0,0,0,0},
|
|
{ 0,0,0,0,0,0,0 },
|
|
{0,0,0,0,0,0,0,0},
|
|
{ 0,0,0,0,0,0,0 },
|
|
{0,0,0,0,0,0,0,0},
|
|
{ 0,0,0,0,0,0,0 }
|
|
}
|
|
game.current_level = 1
|
|
|
|
game.bubble_slots = load_level(
|
|
game.levels[game.current_level], game.bubble_diameter, game.row_gap
|
|
)
|
|
local bubbles_wide = math.max(
|
|
#game.levels[game.current_level][1],
|
|
#game.levels[game.current_level][2]
|
|
)
|
|
local bubbles_high = #game.levels[game.current_level]
|
|
game.level_width = bubbles_wide * game.bubble_diameter
|
|
game.level_height = (bubbles_high - 1) * game.row_gap + game.bubble_diameter
|
|
game.level_x = (game.window_width - game.level_width) / 2
|
|
game.level_y = game.bubble_radius
|
|
|
|
game.launcher_image = love.graphics.newImage('images/launcher.png')
|
|
game.launcher_height = game.launcher_image:getHeight()
|
|
game.launcher_width = game.launcher_image:getWidth()
|
|
game.launcher_x = game.window_width / 2
|
|
game.launcher_y = game.level_y + game.level_height + game.bubble_diameter
|
|
game.launcher_offset_x = 90 -- rotation point in launcher image
|
|
game.launcher_offset_y = game.launcher_height / 2
|
|
game.launcher_rotation = -tau / 4 -- up
|
|
|
|
game.bubble_type_counts = {}
|
|
local bubble_types = {}
|
|
for i = 1, #game.bubble_slots do
|
|
local bubble_type = game.bubble_slots[i].bubble_type
|
|
if game.bubble_type_counts[bubble_type] == nil then
|
|
game.bubble_type_counts[bubble_type] = 0
|
|
if bubble_type >= 1 and bubble_type <= 8 then
|
|
bubble_types[#bubble_types+1] = bubble_type
|
|
end
|
|
end
|
|
game.bubble_type_counts[bubble_type] = game.bubble_type_counts[bubble_type] + 1
|
|
end
|
|
game.next_bubble_index = 1
|
|
game.next_bubble = {
|
|
x = game.launcher_x,
|
|
y = game.launcher_y,
|
|
bubble_type = get_next_bubble_type(game.next_bubble_index, bubble_types),
|
|
velocity_x = 0,
|
|
velocity_y = 0
|
|
}
|
|
end
|
|
|
|
function love.update(dt)
|
|
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
|
|
game.next_bubble.y = game.next_bubble.y + game.next_bubble.velocity_y * dt
|
|
end
|
|
end
|
|
|
|
function love.draw()
|
|
-- draw background
|
|
love.graphics.setColor(1, 1, 1, 1)
|
|
love.graphics.draw(game.background_image, 0, 0)
|
|
love.graphics.draw(game.background_image, game.background_width, 0)
|
|
|
|
-- draw stationary bubbles
|
|
for i = 1, #game.bubble_slots do
|
|
local slot = game.bubble_slots[i]
|
|
if slot.bubble_type >= 1 and slot.bubble_type <= #game.bubble_images then
|
|
love.graphics.draw(
|
|
game.bubble_images[slot.bubble_type], -- image
|
|
game.level_x + slot.x, -- x
|
|
game.level_y + slot.y, -- y
|
|
0, -- rotation
|
|
1, -- x scale
|
|
1, -- y scale
|
|
game.bubble_radius, -- x offset
|
|
game.bubble_radius -- y offset
|
|
)
|
|
else
|
|
love.graphics.circle(
|
|
'line',
|
|
game.level_x + slot.x,
|
|
game.level_y + slot.y,
|
|
game.bubble_radius
|
|
)
|
|
end
|
|
end
|
|
|
|
-- draw level border
|
|
love.graphics.setColor(0, 0, 0, 1)
|
|
love.graphics.rectangle(
|
|
'line',
|
|
game.level_x,
|
|
game.level_y,
|
|
game.level_width,
|
|
game.level_height
|
|
)
|
|
|
|
-- draw launcher
|
|
love.graphics.setColor(1, 1, 1, 1)
|
|
love.graphics.draw(
|
|
game.launcher_image,
|
|
game.launcher_x,
|
|
game.launcher_y,
|
|
game.launcher_rotation,
|
|
1,
|
|
1,
|
|
game.launcher_offset_x,
|
|
game.launcher_offset_y
|
|
)
|
|
|
|
-- draw next bubble
|
|
love.graphics.setColor(1, 1, 1, 1)
|
|
love.graphics.draw(
|
|
game.bubble_images[game.next_bubble.bubble_type],
|
|
game.next_bubble.x,
|
|
game.next_bubble.y,
|
|
0,
|
|
1,
|
|
1,
|
|
game.bubble_radius,
|
|
game.bubble_radius
|
|
)
|
|
end
|
|
|
|
function love.mousepressed(x, y, button, is_touch, presses)
|
|
if button == 1 then
|
|
local diff_x = x - game.launcher_x
|
|
local diff_y = y - game.launcher_y
|
|
local dist = math.sqrt(diff_x * diff_x + diff_y * diff_y)
|
|
game.next_bubble.velocity_x = diff_x / dist * game.bubble_speed
|
|
game.next_bubble.velocity_y = diff_y / dist * game.bubble_speed
|
|
end
|
|
end
|
|
|
|
function love.mousemoved(x, y, dx, dy, is_touch)
|
|
local diff_x = x - game.launcher_x
|
|
local diff_y = y - game.launcher_y
|
|
game.launcher_rotation = math.atan2(diff_y, diff_x)
|
|
end
|
|
|
|
function love.keypressed(key, scan_code, is_repeat)
|
|
if key == 'escape' then
|
|
love.event.quit()
|
|
end
|
|
end
|