-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from JeremyLoh/breakout-11
breakout-11: Paddle Select Update
- Loading branch information
Showing
45 changed files
with
2,004 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
# breakout-11: Paddle Select Update | ||
|
||
Add ability for users to select a paddle before starting the game | ||
|
||
## `main.lua` changes | ||
|
||
```Lua | ||
function love.load() | ||
-- ... | ||
-- Quads generated from our textures | ||
gQuadsTable = { | ||
["paddles"] = GenerateQuadPaddles(gGraphics["main"]), | ||
["balls"] = GenerateQuadBalls(gGraphics["main"]), | ||
["bricks"] = GenerateQuadBricks(gGraphics["main"]), | ||
["hearts"] = generateQuads(gGraphics["hearts"], 16, 16), | ||
["arrows"] = generateQuads(gGraphics["arrows"], 16, 16), | ||
} | ||
|
||
states = { | ||
["start"] = function() return StartState() end, | ||
["highscores"] = function() return HighscoreState() end, | ||
["play"] = function() return PlayState() end, | ||
["serve"] = function() return ServeState() end, | ||
["game-over"] = function() return GameOverState() end, | ||
["victory"] = function() return VictoryState() end, | ||
["enter-highscores"] = function() return EnterHighscoreState() end, | ||
["paddle-select"] = function() return PaddleSelectState() end, | ||
} | ||
end | ||
``` | ||
|
||
## `constants.lua` changes | ||
|
||
```Lua | ||
HIGHEST_PADDLE_SKIN = 4 | ||
HIGHEST_PADDLE_SIZE = 4 | ||
LOWEST_PADDLE_SKIN = 1 | ||
LOWEST_PADDLE_SIZE = 1 | ||
|
||
PADDLE_SIZES = { | ||
-- small (size 1) | ||
[1] = { | ||
["width"] = 32, | ||
["height"] = 16, | ||
}, | ||
-- medium (size 2) | ||
[2] = { | ||
["width"] = 64, | ||
["height"] = 16, | ||
}, | ||
-- large (size 3) | ||
[3] = { | ||
["width"] = 96, | ||
["height"] = 16, | ||
}, | ||
-- extra-large (size 4) | ||
[4] = { | ||
["width"] = 128, | ||
["height"] = 16, | ||
}, | ||
} | ||
``` | ||
|
||
## `Dependencies.lua` changes | ||
|
||
```Lua | ||
require "src/states/PaddleSelectState" | ||
``` | ||
|
||
## `Paddle.lua` changes | ||
|
||
```Lua | ||
function Paddle:init(skin, size) | ||
-- Color of paddle (skin), used to offset gPaddleSkins | ||
self.skin = skin | ||
-- Paddle size (small (1), medium (2), large (3), extra-large (4)) | ||
self.size = size | ||
-- Paddle dimensions | ||
self.width = PADDLE_SIZES[self.size]["width"] | ||
self.height = PADDLE_SIZES[self.size]["height"] | ||
self.x = (VIRTUAL_WIDTH / 2) - (self.width / 2) | ||
self.y = VIRTUAL_HEIGHT - 30 | ||
-- Keep track of paddle velocity | ||
self.dx = 0 | ||
end | ||
``` | ||
|
||
## `PaddleSelectState.lua` | ||
|
||
```Lua | ||
PaddleSelectState = Class{__includes = BaseState} | ||
|
||
function PaddleSelectState:init() | ||
-- Color of paddle | ||
self.skin = 1 | ||
-- Paddle size (small (1), medium (2), large (3), extra-large (4)) | ||
self.size = 1 | ||
end | ||
|
||
function PaddleSelectState:update(dt) | ||
if love.keyboard.wasPressed("enter") or love.keyboard.wasPressed("return") then | ||
gStateMachine:change("serve", { | ||
["paddle"] = Paddle(self.skin, self.size), | ||
["bricks"] = LevelMaker.createMap(1), | ||
["ball"] = Ball(1), | ||
["lives"] = MAX_LIVES, | ||
["score"] = 0, | ||
["level"] = 1, | ||
}) | ||
elseif love.keyboard.wasPressed("escape") then | ||
gStateMachine:change("start") | ||
elseif love.keyboard.wasPressed("left") then | ||
if self.skin == LOWEST_PADDLE_SKIN and self.size == LOWEST_PADDLE_SIZE then | ||
gSounds["no-select"]:play() | ||
else | ||
gSounds["select"]:play() | ||
self.size = self.size - 1 | ||
if self.size < 1 then | ||
self.skin = self.skin - 1 | ||
self.size = HIGHEST_PADDLE_SIZE | ||
end | ||
end | ||
elseif love.keyboard.wasPressed("right") then | ||
if self.skin == HIGHEST_PADDLE_SKIN and self.size == HIGHEST_PADDLE_SIZE then | ||
gSounds["no-select"]:play() | ||
else | ||
gSounds["select"]:play() | ||
self.size = self.size + 1 | ||
if self.size > 4 then | ||
self.size = LOWEST_PADDLE_SIZE | ||
self.skin = self.skin + 1 | ||
end | ||
end | ||
end | ||
end | ||
|
||
function PaddleSelectState:render() | ||
love.graphics.setFont(gFonts["medium"]) | ||
love.graphics.printf("Select your paddle with the left and right arrow keys", 0, 20, VIRTUAL_WIDTH, "center") | ||
love.graphics.setFont(gFonts["small"]) | ||
love.graphics.printf("Press \"Enter\" to continue", 0, 40, VIRTUAL_WIDTH, "center") | ||
|
||
local arrowHeight = gGraphics["arrows"]:getHeight() | ||
local arrowWidth = gGraphics["arrows"]:getWidth() | ||
local arrowX = (VIRTUAL_WIDTH / 3) - (arrowWidth / 2) | ||
local arrowY = (VIRTUAL_HEIGHT / 2) - (arrowHeight / 2) | ||
local rightArrowOffset = (VIRTUAL_WIDTH / 2 - arrowX) - arrowWidth / 2 | ||
|
||
-- Left select arrow | ||
if self.skin == LOWEST_PADDLE_SKIN and self.size == LOWEST_PADDLE_SIZE then | ||
-- Give grey tint to indicate no further selection possible | ||
love.graphics.setColor(40/255, 40/255, 40/255, 128/255) | ||
else | ||
-- Reset drawing color to full white for proper rendering | ||
love.graphics.setColor(1, 1, 1, 1) | ||
end | ||
love.graphics.draw(gGraphics["arrows"], gQuadsTable["arrows"][1], arrowX, arrowY) | ||
|
||
-- Right select arrow | ||
if self.skin == HIGHEST_PADDLE_SKIN and self.size == HIGHEST_PADDLE_SIZE then | ||
-- Give grey tint to indicate no further selection possible | ||
love.graphics.setColor(40/255, 40/255, 40/255, 128/255) | ||
else | ||
-- Reset drawing color to full white for proper rendering | ||
love.graphics.setColor(1, 1, 1, 1) | ||
end | ||
love.graphics.draw(gGraphics["arrows"], gQuadsTable["arrows"][2], | ||
(VIRTUAL_WIDTH / 2) + rightArrowOffset, arrowY) | ||
|
||
-- Reset drawing color to full white for proper rendering | ||
love.graphics.setColor(1, 1, 1, 1) | ||
-- Draw paddle | ||
local paddleWidth = PADDLE_SIZES[self.size]["width"] | ||
local paddleHeight = PADDLE_SIZES[self.size]["height"] | ||
love.graphics.draw(gGraphics["main"], | ||
gQuadsTable["paddles"][(self.skin - 1) * 4 + self.size], | ||
VIRTUAL_WIDTH / 2 - paddleWidth / 2, | ||
VIRTUAL_HEIGHT / 2 - paddleHeight / 2) | ||
end | ||
``` | ||
|
||
## `StartState.lua` changes | ||
|
||
```Lua | ||
function StartState:update(dt) | ||
if love.keyboard.wasPressed("up") or love.keyboard.wasPressed("down") then | ||
selectedOption = selectedOption == 1 and 2 or 1 | ||
gSounds["paddle-hit"]:play() | ||
elseif love.keyboard.wasPressed("enter") or love.keyboard.wasPressed("return") then | ||
gSounds["confirm"]:play() | ||
if selectedOption == 1 then | ||
-- Start game, select paddle | ||
gStateMachine:change("paddle-select") | ||
elseif selectedOption == 2 then | ||
-- Highscores | ||
gStateMachine:change("highscores", { | ||
["highscores"] = highscores | ||
}) | ||
end | ||
elseif love.keyboard.wasPressed("escape") then | ||
love.event.quit() | ||
end | ||
end | ||
``` |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
--[[ | ||
Copyright (c) 2010-2013 Matthias Richter | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
Except as contained in this notice, the name(s) of the above copyright holders | ||
shall not be used in advertising or otherwise to promote the sale, use or | ||
other dealings in this Software without prior written authorization. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
]]-- | ||
|
||
local function include_helper(to, from, seen) | ||
if from == nil then | ||
return to | ||
elseif type(from) ~= 'table' then | ||
return from | ||
elseif seen[from] then | ||
return seen[from] | ||
end | ||
|
||
seen[from] = to | ||
for k,v in pairs(from) do | ||
k = include_helper({}, k, seen) -- keys might also be tables | ||
if to[k] == nil then | ||
to[k] = include_helper({}, v, seen) | ||
end | ||
end | ||
return to | ||
end | ||
|
||
-- deeply copies `other' into `class'. keys in `other' that are already | ||
-- defined in `class' are omitted | ||
local function include(class, other) | ||
return include_helper(class, other, {}) | ||
end | ||
|
||
-- returns a deep copy of `other' | ||
local function clone(other) | ||
return setmetatable(include({}, other), getmetatable(other)) | ||
end | ||
|
||
local function new(class) | ||
-- mixins | ||
class = class or {} -- class can be nil | ||
local inc = class.__includes or {} | ||
if getmetatable(inc) then inc = {inc} end | ||
|
||
for _, other in ipairs(inc) do | ||
if type(other) == "string" then | ||
other = _G[other] | ||
end | ||
include(class, other) | ||
end | ||
|
||
-- class implementation | ||
class.__index = class | ||
class.init = class.init or class[1] or function() end | ||
class.include = class.include or include | ||
class.clone = class.clone or clone | ||
|
||
-- constructor call | ||
return setmetatable(class, {__call = function(c, ...) | ||
local o = setmetatable({}, c) | ||
o:init(...) | ||
return o | ||
end}) | ||
end | ||
|
||
-- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Commons). | ||
if class_commons ~= false and not common then | ||
common = {} | ||
function common.class(name, prototype, parent) | ||
return new{__includes = {prototype, parent}} | ||
end | ||
function common.instance(class, ...) | ||
return class(...) | ||
end | ||
end | ||
|
||
|
||
-- the module | ||
return setmetatable({new = new, include = include, clone = clone}, | ||
{__call = function(_,...) return new(...) end}) |
Oops, something went wrong.