diff --git a/README.md b/README.md index 4741751..40c4107 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ A game made on gamedev dungeon over ~1.5 hours +**This is a procedural roguelike.** + +- By procedural I mean that the bricks have different colors every time +- By roguelike I mean that the game quits if you die + ## Assets - credits - Sounds by Kenney ([link](https://kenney.nl/assets/impact-sounds)) diff --git a/main.lua b/main.lua index 969c4b1..a4623a8 100644 --- a/main.lua +++ b/main.lua @@ -1,21 +1,9 @@ -player = { - position = { x = 0, y = 0 }, - width = 100, - height = 10, - moving_left = false, - moving_right = false, - -- Returns 2 values, x and y! - getCenter = function() - return player.position.x + player.width / 2, player.position.y + player.height / 2 - end -} - -settings = { +Settings = { player_speed = 8, ball_speed = 5, - block_rows = 1, - block_cols = 3, + block_rows = 3, + block_cols = 8, block_height = 15, block_offset_x = 30, @@ -25,7 +13,22 @@ settings = { collision_margin = 2 -- kinda tied to ball radius lol } -game = { +-- represenets the player-controlled paddle +Player = { + x = 0, + y = 0, + width = 100, + height = 10, + moving_left = false, + moving_right = false, + -- Returns 2 values, x and y! + getCenter = function() + return Player.x + Player.width / 2, Player.y + Player.height / 2 + end +} + + +Game = { ball = { position = { x = 0, y = 0 }, velocity = { dx = 0, dy = 0 }, @@ -37,115 +40,74 @@ game = { is_playing = true, } -media = {} +Assets = {} function love.load() - media.jirka = love.graphics.newImage("jirka.png") - media.impact = love.audio.newSource("impact.ogg", "static") - media.impact_wall = love.audio.newSource("impact_wall.ogg", "static") - media.impact_player = love.audio.newSource("impact_player.ogg", "static") + Assets.jirka = love.graphics.newImage("jirka.png") + Assets.impact = love.audio.newSource("impact.ogg", "static") + Assets.impact_wall = love.audio.newSource("impact_wall.ogg", "static") + Assets.impact_player = love.audio.newSource("impact_player.ogg", "static") - -- place the player - player.position.x = love.graphics.getWidth() / 2 - player.position.y = love.graphics.getHeight() - 30 - - -- place the ball - local px, py = player.getCenter() - game.ball.position.x = px - game.ball.position.y = py - player.height - game.ball.velocity.dx = (love.math.random() - 0.5) * settings.ball_speed - game.ball.velocity.dy = -settings.ball_speed - - -- Setup block variables - local cur_x = settings.block_offset_x - local cur_y = settings.block_offset_y - local gap = settings.block_gap - local block_width = (love.graphics.getWidth() - cur_x * 2 - gap * (settings.block_cols - 1)) / settings.block_cols - -- Generate the actual blocks - for row = 1, settings.block_rows do - for col = 1, settings.block_cols do - table.insert(game.blocks, { - x = cur_x, - y = cur_y, - width = block_width, - height = settings.block_height, - color = { - r = math.max(love.math.random(), 0.2), - g = math.max(love.math.random(), 0.2), - b = math.max(love.math.random(), 0.2) - }, - active = true -- This is turned off when a box is hit - }) - cur_x = cur_x + block_width + gap - end - cur_y = cur_y + settings.block_height + gap - cur_x = settings.block_offset_x - end + setupGame() end function love.update() - if game.is_playing == false then + if Game.is_playing == false then return end - if player.moving_left then - player.position.x = player.position.x - settings.player_speed + if Player.moving_left then + Player.x = Player.x - Settings.player_speed end - if player.moving_right then - player.position.x = player.position.x + settings.player_speed + if Player.moving_right then + Player.x = Player.x + Settings.player_speed end - local b = game.ball + local b = Game.ball -- move ball b.position.x = b.position.x + b.velocity.dx b.position.y = b.position.y + b.velocity.dy -- Check wall collisions - if b.position.x <= settings.collision_margin then + if b.position.x <= Settings.collision_margin then b.velocity.dx = -b.velocity.dx - media.impact_wall:stop() - media.impact_wall:play() + Assets.impact_wall:stop() + Assets.impact_wall:play() end - if b.position.x >= love.graphics.getWidth() - settings.collision_margin then + if b.position.x >= love.graphics.getWidth() - Settings.collision_margin then b.velocity.dx = -b.velocity.dx - media.impact_wall:stop() - media.impact_wall:play() + Assets.impact_wall:stop() + Assets.impact_wall:play() end - if b.position.y <= settings.collision_margin then + if b.position.y <= Settings.collision_margin then -- ceiling hit b.velocity.dy = -b.velocity.dy - media.impact_wall:stop() - media.impact_wall:play() + Assets.impact_wall:stop() + Assets.impact_wall:play() end -- player collision - local player_block = { - x = player.position.x, - y = player.position.y, - width = player.width, - height = player.height - } - if checkCollision(player_block, game.ball) then - media.impact_player:play() + if checkCollision(Player, Game.ball) then + Assets.impact_player:play() b.velocity.dy = -b.velocity.dy - local cx, cy = player.getCenter() + local cx, cy = Player.getCenter() local distance_from_center = b.position.x - cx - game.ball.velocity.dx = (distance_from_center / (player.width / 2)) * settings.ball_speed + Game.ball.velocity.dx = (distance_from_center / (Player.width / 2)) * Settings.ball_speed end -- Check box collisions - for _, block in ipairs(game.blocks) do + for _, block in ipairs(Game.blocks) do if block.active then local dist_x = block.x - b.position.x local dist_y = block.y - b.position.y - if checkCollision(block, game.ball) then + if checkCollision(block, Game.ball) then block.active = false - media.impact:stop() - media.impact:play() + Assets.impact:stop() + Assets.impact:play() - game.score = game.score + 1 + Game.score = Game.score + 1 -- block hit horizontal if b.position.x > (block.x + block.width) or b.position.x < block.x then @@ -163,13 +125,13 @@ function love.update() end -- WIN GAME?? - if game.score == #game.blocks then - game.is_playing = false + if Game.score == #Game.blocks then + Game.is_playing = false end end function love.draw() - if game.is_playing == false then + if Game.is_playing == false then love.graphics.clear(0.1, 0.9, 0.3, 1) love.graphics.setColor(0, 0, 0, 1) love.graphics.print("YOU WON! GOOD JOB!", love.graphics.getWidth() / 2, love.graphics.getHeight() / 2) @@ -177,7 +139,7 @@ function love.draw() "Press space to play again", love.graphics.getWidth() / 2, (love.graphics.getHeight() / 2) + 30 ) love.graphics.setColor(255, 255, 255, 255) -- white? - love.graphics.draw(media.jirka, + love.graphics.draw(Assets.jirka, (love.graphics.getWidth() / 2) - 150, (love.graphics.getHeight() / 2) - 70) @@ -186,15 +148,15 @@ function love.draw() love.graphics.setColor(1, 1, 1, 1) -- white love.graphics.clear() - love.graphics.print("Score: " .. tostring(game.score), 10, 10) + love.graphics.print("Score: " .. tostring(Game.score), 10, 10) - love.graphics.rectangle("fill", player.position.x, player.position.y, player.width, player.height) + love.graphics.rectangle("fill", Player.x, Player.y, Player.width, Player.height) -- draw the ball - love.graphics.circle("fill", game.ball.position.x, game.ball.position.y, game.ball.radius) + love.graphics.circle("fill", Game.ball.position.x, Game.ball.position.y, Game.ball.radius) -- draw the blocks - for _, block in ipairs(game.blocks) do + for _, block in ipairs(Game.blocks) do if block.active then love.graphics.setColor(block.color.r, block.color.g, block.color.b) love.graphics.rectangle("fill", block.x, block.y, block.width, block.height, 4, 4) @@ -206,24 +168,24 @@ end function love.keypressed(key) if key == "left" or key == "a" then - player.moving_left = true + Player.moving_left = true end if key == "right" or key == "d" then - player.moving_right = true + Player.moving_right = true end end function love.keyreleased(key) if key == "left" or key == "a" then - player.moving_left = false + Player.moving_left = false end if key == "right" or key == "d" then - player.moving_right = false + Player.moving_right = false end - if game.is_playing == false and key == "space" then + if Game.is_playing == false and key == "space" then resetGame() - game.is_playing = true + Game.is_playing = true end end @@ -241,14 +203,53 @@ function checkCollision(box, ball) return distanceSquared < (ball.radius * ball.radius) end +function setupGame() + -- place the player + Player.x = love.graphics.getWidth() / 2 + Player.y = love.graphics.getHeight() - 30 + + -- place the ball + local px, py = Player.getCenter() + Game.ball.position.x = px + Game.ball.position.y = py - Player.height + Game.ball.velocity.dx = (love.math.random() - 0.5) * Settings.ball_speed + Game.ball.velocity.dy = -Settings.ball_speed + + -- Setup block variables + local cur_x = Settings.block_offset_x + local cur_y = Settings.block_offset_y + local gap = Settings.block_gap + local block_width = (love.graphics.getWidth() - cur_x * 2 - gap * (Settings.block_cols - 1)) / Settings.block_cols + -- Generate the actual blocks + for row = 1, Settings.block_rows do + for col = 1, Settings.block_cols do + table.insert(Game.blocks, { + x = cur_x, + y = cur_y, + width = block_width, + height = Settings.block_height, + color = { + r = math.max(love.math.random(), 0.2), + g = math.max(love.math.random(), 0.2), + b = math.max(love.math.random(), 0.2) + }, + active = true -- This is turned off when a box is hit + }) + cur_x = cur_x + block_width + gap + end + cur_y = cur_y + Settings.block_height + gap + cur_x = Settings.block_offset_x + end +end + function resetGame() -- Remove all blocks - for k in pairs(game.blocks) do - game.blocks[k] = nil + for k in pairs(Game.blocks) do + Game.blocks[k] = nil end -- reset score - game.score = 0 + Game.score = 0 -- Reload - love.load() + setupGame() end