Compare commits

..
57 Commits
Author SHA1 Message Date
Simon Kellet 8d756beb1b removed 2024-08-06 18:16:45 +01:00
Simon Kellet 86d33a7fc5 nearly there 2024-08-06 18:16:14 +01:00
Simon Kellet 65f4ee3473 wip 2024-08-06 17:39:14 +01:00
Simon Kellet e13114a736 power up colliders for both players 2024-08-06 17:39:09 +01:00
Simon Kellet 451d710326 escape key on pause 2024-08-02 17:27:23 +01:00
Simon Kellet 585fccf59a flips 2024-08-02 17:27:13 +01:00
Simon Kellet 3290d704e3 less prints 2024-08-02 17:27:09 +01:00
Simon Kellet 7b553d9758 formatting 2024-08-02 17:26:50 +01:00
Simon Kellet e9e3731a0b new window size 2024-08-02 17:26:43 +01:00
Simon Kellet ed9265939c scale conts 2024-08-02 17:26:35 +01:00
Simon Kellet 826ef98f19 no longer needed 2024-08-02 17:26:29 +01:00
Simon Kellet db3559b8c6 player scaling 2024-08-02 17:26:22 +01:00
Simon Kellet 88faf2538b scaling 2024-08-02 17:26:14 +01:00
Simon Kellet 7252c3cd2c scaling now works? yay? 2024-08-02 17:01:21 +01:00
Simon Kellet 7da12d3035 added mute 2024-07-31 20:37:25 +01:00
Simon Kellet ebf9369ba5 fixed game logix 2024-07-31 20:37:17 +01:00
Simon Kellet f6be8b2a16 removed btton func 2024-07-31 20:36:53 +01:00
Simon Kellet beb4c28a70 removed button func 2024-07-31 20:36:47 +01:00
Simon Kellet 2d22a50447 added mute 2024-07-31 20:36:29 +01:00
Simon Kellet d059017989 fix win 2024-07-31 20:36:20 +01:00
Simon Kellet 49a57a6e5d better bouncing finally 2024-07-31 20:36:10 +01:00
Simon Kellet f5770cd4e0 ops 2024-07-31 20:35:55 +01:00
Simon Kellet 49633072ac reset wind 2024-07-31 20:35:49 +01:00
Simon Kellet 7af90632fd added truncate method 2024-07-31 20:35:42 +01:00
Simon Kellet e47799650a added start of gui lib 2024-07-31 15:20:12 +01:00
Simon Kellet 8440be2ab1 better movement 2024-07-24 16:19:18 +01:00
Simon Kellet df4184eec4 moved stuff out of love.load 2024-07-24 15:58:44 +01:00
Simon Kellet e8a124fa63 bullet bounce count 2024-07-24 15:58:32 +01:00
Simon Kellet 78b4379143 debug keys 2024-07-24 15:58:04 +01:00
Simon Kellet b8106bc1aa deletes bullets after bouncing so many times 2024-07-24 15:57:59 +01:00
Simon Kellet f8d71bb27d moved 2024-07-24 15:57:43 +01:00
Simon Kellet 7016961609 restart doesnt stop battle music 2024-07-24 15:57:37 +01:00
Simon Kellet 95502bc429 added map 3 2024-07-24 15:57:13 +01:00
Simon Kellet f689632a92 better wall init and clearing 2024-07-22 23:30:19 +01:00
Simon Kellet da8bb7d083 removed unused music stops 2024-07-22 23:30:08 +01:00
Simon Kellet 0a25d11ac5 hitbox now circle and slower going backwards 2024-07-22 23:29:55 +01:00
Simon Kellet 71d1f6e929 changed 2024-07-22 23:29:16 +01:00
Simon Kellet a392755844 global tracker of current level 2024-07-22 23:29:09 +01:00
Simon Kellet f4d3969a1f new map for testing 2024-07-22 23:29:00 +01:00
Simon Kellet 2cd9f263e6 walls now properly get destoryed 2024-07-22 23:28:53 +01:00
Simon Kellet ff40a5507b draws score 2024-07-22 23:28:46 +01:00
Simon Kellet 26398f52b5 fixed wins 2024-07-22 23:28:36 +01:00
Simon Kellet 38826d0cd8 debug keys 2024-07-22 23:28:26 +01:00
Simon Kellet 9e968b9390 done for tonight 2024-07-21 21:24:12 +01:00
Simon Kellet cdc0f35f22 handling win states and moving stuff to be global 2024-07-21 19:48:02 +01:00
Simon Kellet e83ee4ec64 there is now a win screen 2024-07-21 19:47:41 +01:00
Simon Kellet 7b68420027 maps now clear their Wall tables before making new ones 2024-07-21 19:47:18 +01:00
Simon Kellet 5f915f617e added restarting functions 2024-07-21 19:46:59 +01:00
Simon Kellet 6049054a26 removed windows build, got it wrong lol 2024-07-21 18:08:12 +01:00
Simon Kellet 99b420cc7f format and stuff 2024-07-21 18:07:07 +01:00
Simon Kellet 53aa6d698d changes 2024-07-21 13:47:33 +01:00
Simon Kellet 407436f7f0 added love2d version for building 2024-07-21 13:46:55 +01:00
Simon Kellet 8a206de2a1 links 2024-07-21 13:46:42 +01:00
Simon Kellet 5830863a5f added windows build script 2024-07-21 13:46:32 +01:00
Simon Kellet ba6f2c8d49 checkboxes 2024-07-20 11:06:29 +01:00
Simon Kellet c8ac060ab3 checkboxes 2024-07-20 11:05:43 +01:00
Simon Kellet a46532814f moved files 2024-07-20 10:26:09 +01:00
42 changed files with 4715 additions and 3302 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
.DS_Store
game.love
*.love
*.exe
+19 -6
View File
@@ -6,15 +6,18 @@ end
local function drawHealth()
love.graphics.setFont(GameFont)
local height = love.graphics.getHeight()
local width = love.graphics.getWidth()
love.graphics.print("" .. UserPlayer1.health, 5, 5)
love.graphics.print("" .. UserPlayer2.health, width - 70, height - 95)
local height = love.graphics.getHeight() / _G.Y_SCALE
local width = love.graphics.getWidth() / _G.X_SCALE
love.graphics.print("P1:" .. UserPlayer1.health, 5, 5)
love.graphics.print("P2:" .. UserPlayer2.health, width - 200, height - 95)
end
function DrawGame()
--STI
GameMap:draw()
local curWidth, curHeight = love.graphics.getDimensions()
love.graphics.scale(_G.X_SCALE, _G.Y_SCALE)
GameMap:draw(0, 0, _G.X_SCALE, _G.Y_SCALE)
GameMap:resize(curWidth / _G.X_SCALE, curHeight / _G.Y_SCALE)
-- WindField
if DebugFlag then
@@ -22,6 +25,7 @@ function DrawGame()
drawFPS()
end
-- Bullets
for _, v in ipairs(Bullets1) do
v:draw()
end
@@ -29,9 +33,18 @@ function DrawGame()
v:draw()
end
-- PowerUps
for _, v in ipairs(PowerUps) do
v:draw()
end
UserPlayer1:draw()
UserPlayer2:draw()
--Draw Health
--TODO: make this nicer looking
drawHealth()
--TODO: draw running score
--drawScore()
end
+41 -6
View File
@@ -1,11 +1,15 @@
function GameKeyPressed(key)
if key == "escape" then
musicBattle:setVolume(0)
musicPause:setVolume(0.5)
if not MUTED then
musicBattle:setVolume(0)
musicPause:setVolume(0.6)
else
musicBattle:setVolume(0)
musicPause:setVolume(0)
end
_G.GAMESTATE = "PAUSE"
print("STATE CHANEGD: PAUSED!")
--print("STATE CHANEGD: PAUSED!")
_G.PAUSED = true
end
@@ -13,9 +17,40 @@ function GameKeyPressed(key)
DebugFlag = not DebugFlag
end
--[[
if key == "r" and not _G.PAUSED then
RestartGame()
_G.GAMESTATE = "GAME"
love.load()
end
]]--
if key == "m" then
_G.MUTED = not _G.MUTED
-- Need to set the battle music to mute
if _G.MUTED then
musicBattle:setVolume(0)
else
musicBattle:setVolume(0.5)
end
end
if DebugFlag and key == "1" then
--UserPlayer1.speed = 50000
--print("player1 speed increased!")
end
if DebugFlag and key == "2" then
_G.CUR_LEVEL = 2
RestartGame()
love.load()
end
if DebugFlag and key == "3" then
_G.CUR_LEVEL = 3
RestartGame()
love.load()
end
if key == "p" then
testP = PowerUp("speed", 300, 300, "assets/powerup.jpeg", 10)
table.insert(PowerUps, testP)
end
end
+107 -15
View File
@@ -1,9 +1,32 @@
local function checkLossState()
-- Check P1's health
if UserPlayer1.health <= 0 then --P1 Lost, P2 Win
_G.P2_COUNT = _G.P2_COUNT + 1
_G.P1_WIN = false
_G.P2_WIN = true
return true
end
if UserPlayer2.health <= 0 then --P2 Lost, P1 Win
_G.P1_COUNT = _G.P1_COUNT + 1
_G.P1_WIN = true
_G.P2_WIN = false
return true
end
return false
end
local max = math.max -- optimisations
function UpdateGame(dt)
--Check if anyone has won
if checkLossState() == true then
--print("STATE CHNAGED: WIN!")
_G.GAMESTATE = "WIN"
end
--WindField
World:update(dt)
local max = math.max
KeyPressTime1 = max(0, KeyPressTime1 - dt)
if KeyPressTime1 <= 0 then
EnableKeyPress1 = true
@@ -13,8 +36,18 @@ function UpdateGame(dt)
if KeyPressTime2 <= 0 then
EnableKeyPress2 = true
end
-- Update Bullets1
for i, v in ipairs(Bullets1) do
v:update(dt)
-- Check bounce count
if v.bounce >= _G.BULLETS_BOUNCE_MAX then
table.remove(Bullets1, i)
v.collider:destroy()
end
-- Handle screen edges
if v.y < 0 then --top of screen
table.remove(Bullets1, i)
v.collider:destroy()
@@ -22,8 +55,20 @@ function UpdateGame(dt)
table.remove(Bullets1, i)
v.collider:destroy()
end
-- Hit player2
if v.collider:enter("Player2") then
print("Player1 hit Player2!")
--print("Player1 hit Player2!")
table.remove(Bullets1, i)
v.collider:destroy()
if UserPlayer2.health > 0 then
UserPlayer2.health = UserPlayer2.health - 1
end
end
-- Hit player1
if v.collider:enter("Player1") then
--print("Player 1 hit themselves!")
table.remove(Bullets1, i)
v.collider:destroy()
if UserPlayer1.health > 0 then
@@ -31,18 +76,24 @@ function UpdateGame(dt)
end
end
if v.collider:enter("Player1") then
print("Player 1 hit themselves!")
--Hit another bullet
if v.collider:enter("Bullet1") then
table.remove(Bullets1, i)
v.collider:destroy()
if UserPlayer1.health > 0 then
UserPlayer1.health = UserPlayer1.health - 1
end
end
end
-- Update Bullets2
for i, v in ipairs(Bullets2) do
v:update(dt)
-- Check bounce count
if v.bounce >= _G.BULLETS_BOUNCE_MAX then
table.remove(Bullets2, i)
v.collider:destroy()
end
-- Handle screen edges
if v.y < 0 then --top of screen
table.remove(Bullets2, i)
v.collider:destroy()
@@ -51,25 +102,66 @@ function UpdateGame(dt)
v.collider:destroy()
end
-- Hit player1
if v.collider:enter("Player1") then
print("Player2 hit Player1!")
--print("Player2 hit Player1!")
table.remove(Bullets2, i)
v.collider:destroy()
if UserPlayer1.health > 0 then
UserPlayer1.health = UserPlayer1.health - 1
end
end
-- Hit player2
if v.collider:enter("Player2") then
--print("Player 2 hit themselves!")
table.remove(Bullets2, i)
v.collider:destroy()
if UserPlayer2.health > 0 then
UserPlayer2.health = UserPlayer2.health - 1
end
end
if v.collider:enter("Player2") then
print("Player 2 hit themselves!")
--Hit another bullet
if v.collider:enter("Bullet2") then
table.remove(Bullets2, i)
v.collider:destroy()
if UserPlayer2.health > 0 then
UserPlayer2.health = UserPlayer2.health - 1
end
end
end
-- PowerUp updates
for i, v in ipairs(PowerUps) do
v:update(dt)
if v.collider:enter("Player1") then
UserPlayer1:getPowerUp(v)
UserPlayer1:powerup()
table.remove(PowerUps, i)
v.collider:destroy()
end
if v.collider:enter("Player2") then
UserPlayer2:getPowerUp(v)
UserPlayer2:powerup()
table.remove(PowerUps, i)
v.collider:destroy()
end
end
--PowerUp timer to place
PUTimeToPlace = PUTimeToPlace - dt
--print(PUTimeToPlace)
if PUTimeToPlace <= 0 then
local w, h = love.graphics.getDimensions()
local ranx = love.math.random(30, w)
local rany = love.math.random(100, h)
local newPU = PowerUp("speed", ranx, rany, "assets/powerup.jpeg", 10)
table.insert(PowerUps, newPU)
PUTimeToPlace = _G.PU_TIMER --reset
end
UserPlayer1:handleKeys("w", "s", "a", "d", dt)
UserPlayer2:handleKeys("up", "down", "left", "right", dt)
UserPlayer1:updateCol()
UserPlayer2:updateCol()
UserPlayer1:update(dt)
UserPlayer2:update(dt)
end
+14 -38
View File
@@ -1,44 +1,20 @@
local function button(x,y, w, h, text, selected)
--x,y is the top left corner of the button
local rounding = 30 -- used for rounding the buttons
if not selected then
love.graphics.setColor(love.math.colorFromBytes(41,134,204))
elseif selected then
love.graphics.setColor(love.math.colorFromBytes(244,67,54))
end
-- Draw rectangle
love.graphics.rectangle("line", x, y, w, h, rounding, rounding)
-- Get width and height of text
local tw = MenuFont:getWidth(text)
local th = MenuFont:getHeight(text)
-- Calculate position to center the text
local textX = x + (w - tw) / 2
local textY = y + (h - th) / 2
-- Place text inside the rectangle
love.graphics.setFont(MenuFont)
love.graphics.print(text, textX, textY)
end
local function title()
local height = love.graphics.getHeight()
local width = love.graphics.getWidth()
local height = love.graphics.getHeight() / _G.Y_SCALE
local width = love.graphics.getWidth() / _G.X_SCALE
love.graphics.setFont(GameFont)
love.graphics.setColor(0.5,1,1)
love.graphics.rectangle("fill", 0, 0, width, height)
love.graphics.setColor(0,0,0)
love.graphics.print("MENU", 100,100)
love.graphics.setColor(0.5, 1, 1)
love.graphics.rectangle("fill", 0, 0, width, height)
love.graphics.setColor(0, 0, 0)
love.graphics.print("Tanks-A-Lot", 100, 100)
end
function DrawMenu()
local bwidth, bheight = 300, 140
title()
button(100, 200, bwidth, bheight, "Play", MENU_POS == 0 and true or false)
button(100, 350, bwidth, bheight, "???", MENU_POS == 1 and true or false)
button(100, 500, bwidth, bheight, "???", MENU_POS == 2 and true or false)
button(100, 650, bwidth, bheight, "Quit", MENU_POS == 3 and true or false)
local bwidth, bheight = 300 * _G.X_SCALE, 140 * _G.Y_SCALE
title()
GUI:newButton(100, 200, bwidth, bheight, "Play", MENU_POS == 0 and true or false)
GUI:newButton(100, 350, bwidth, bheight, "???", MENU_POS == 1 and true or false)
GUI:newButton(100, 500, bwidth, bheight, "???", MENU_POS == 2 and true or false)
GUI:newButton(100, 650, bwidth, bheight, "Quit", MENU_POS == 3 and true or false)
love.graphics.setColor(255,255,255) -- reset colours
end
love.graphics.setColor(255, 255, 255) -- reset colours
end
+21 -8
View File
@@ -1,5 +1,5 @@
function MenuKeyPressed(key)
if key == 'return' then
if key == "return" then
-- 0 Start Game
-- 1 ??
-- 2 ???
@@ -7,19 +7,15 @@ function MenuKeyPressed(key)
if MENU_POS == 0 then
--Change state to GAME!
_G.GAMESTATE = "GAME"
print("STATE CHANEGD: GAME!")
--print("STATE CHANEGD: GAME!")
musicMenu:stop()
elseif MENU_POS == 1 then
print("STATE CHANEGD: DUNNO!")
--print("STATE CHANEGD: DUNNO!")
elseif MENU_POS == 2 then
print("STATE CHANEGD: DUNNO!")
--print("STATE CHANEGD: DUNNO!")
elseif MENU_POS == 3 then
love.event.quit()
end
end
if love.keyboard.isDown("up") then
@@ -38,4 +34,21 @@ function MenuKeyPressed(key)
end
end
if key == "r" then
musicBattle:stop()
musicMenu:stop()
musicPause:stop()
_G.GAMESTATE = "MENU"
love.load()
end
if key == "m" then
MUTED = not MUTED
if MUTED then
musicMenu:setVolume(0)
else
musicMenu:setVolume(0.5)
end
end
end
+1 -2
View File
@@ -1,2 +1 @@
function UpdateMenu(dt)
end
function UpdateMenu(dt) end
+16 -40
View File
@@ -1,45 +1,21 @@
local function button(x,y, w, h, text, selected)
--x,y is the top left corner of the button
local rounding = 30 -- used for rounding the buttons
if not selected then
love.graphics.setColor(love.math.colorFromBytes(41,134,204))
elseif selected then
love.graphics.setColor(love.math.colorFromBytes(244,67,54))
end
-- Draw rectangle
love.graphics.rectangle("fill", x, y, w, h, rounding, rounding)
-- Get width and height of text
local tw = MenuFont:getWidth(text)
local th = MenuFont:getHeight(text)
-- Calculate position to center the text
local textX = x + (w - tw) / 2
local textY = y + (h - th) / 2
-- Place text inside the rectangle
love.graphics.setFont(MenuFont)
love.graphics.setColor(1,1,1) -- reset colours
love.graphics.print(text, textX, textY)
end
function DrawPause()
local opacity = 0.3
local height = love.graphics.getHeight()
local width = love.graphics.getWidth()
local bwidth, bheight = 300, 140
local opacity = 0.3
local height = love.graphics.getHeight() / _G.Y_SCALE
local width = love.graphics.getWidth() / _G.X_SCALE
local bwidth, bheight = 300 * _G.X_SCALE, 140 * _G.Y_SCALE
love.graphics.setFont(GameFont)
DrawGame() --Draw a single frame of the game
love.graphics.setColor(0.1,0.1,0.1, opacity) --overlay opaque img
love.graphics.rectangle("fill", 0, 0, width, height)
DrawGame() --Draw a single frame of the game
love.graphics.setColor(0.1, 0.1, 0.1, opacity) --overlay opaque img
love.graphics.rectangle("fill", 0, 0, width, height)
love.graphics.setColor(1,1,1)
love.graphics.print("PAUSED", 100,100)
--love.graphics.print("" .. PAUSE_POS, 200,200)
love.graphics.setColor(1, 1, 1)
love.graphics.print("PAUSED", 100, 100)
--love.graphics.print("" .. PAUSE_POS, 200,200)
button(100, 200, bwidth, bheight, "Return", PAUSE_POS == 0 and true or false)
button(100, 350, bwidth, bheight, "Menu", PAUSE_POS == 1 and true or false)
button(100, 500, bwidth, bheight, "Quit", PAUSE_POS == 2 and true or false)
love.graphics.setColor(255,255,255) -- reset colours
end
GUI:newButton(100, 200, bwidth, bheight, "Back", PAUSE_POS == 0 and true or false)
GUI:newButton(100, 350, bwidth, bheight, "Menu", PAUSE_POS == 1 and true or false)
GUI:newButton(100, 500, bwidth, bheight, "Quit", PAUSE_POS == 2 and true or false)
love.graphics.setColor(255, 255, 255) -- reset colours
end
+42 -23
View File
@@ -1,30 +1,49 @@
function PauseKeyPressed(key)
if key == 'return' then
musicBattle:setVolume(0.5)
musicPause:setVolume(0)
-- 0 Return to game
-- 1 Quit
if PAUSE_POS == 0 then
-- unpause the game
_G.GAMESTATE = "GAME"
print("STATE CHANEGD: GAME!")
_G.PAUSED = false
if key == "escape" then
-- quickly return to the game
if not _G.MUTED then
musicBattle:setVolume(0.5)
musicPause:setVolume(0)
else
musicBattle:setVolume(0)
musicPause:setVolume(0)
end
_G.GAMESTATE = "GAME"
end
elseif PAUSE_POS == 1 then
_G.GAMESTATE = "MENU"
print("STATE CHANEGD: MENU!")
_G.PAUSED = false
musicPause:stop()
musicBattle:stop()
elseif PAUSE_POS == 2 then
if key == "return" then
-- quickly return to the game
if not _G.MUTED then
musicBattle:setVolume(0.5)
musicPause:setVolume(0)
else
musicBattle:setVolume(0)
musicPause:setVolume(0)
end
-- 0 Return to game
-- 1 Quit
if PAUSE_POS == 0 then
-- unpause the game
_G.GAMESTATE = "GAME"
--print("STATE CHANEGD: GAME!")
_G.PAUSED = false
if not MUTED then
musicBattle:setVolume(0.5)
musicPause:setVolume(0)
else
musicBattle:setVolume(0)
musicPause:setVolume(0)
end
elseif PAUSE_POS == 1 then
_G.GAMESTATE = "MENU"
--print("STATE CHANEGD: MENU!")
_G.PAUSED = false
musicPause:stop()
musicBattle:stop()
elseif PAUSE_POS == 2 then
love.event.quit()
end
end
end
end
if love.keyboard.isDown("up") then
if _G.PAUSE_POS == 0 then
@@ -41,4 +60,4 @@ function PauseKeyPressed(key)
_G.PAUSE_POS = _G.PAUSE_POS + 1
end
end
end
end
+1 -2
View File
@@ -1,2 +1 @@
function UpdatePause(dt)
end
function UpdatePause(dt) end
+17 -8
View File
@@ -18,13 +18,22 @@ love game.love
## Credits
* Programming: Simon
* Art: Laura
* Music: AJ
* Programming: Simon [website](https://simonkellet.xyz)
* Art: Laura
* Music: AJ [website](https://sites.google.com/view/bitnailz)
# TODOS
* Links to socials
* Exe files
* Release stuff
* how to play instructions
* images for git
## Game
* [] Better music (for each level)
* [] Fill out menu screen
* [] Finally fix physics
* [] Make more maps (different level types)
* [] Fix player placement at start of game
## Git
* [] Links to socials
* [] Exe files
* [] Release stuff
* [] how to play instructions
* [] images for git
+39
View File
@@ -0,0 +1,39 @@
local function winner()
local width = love.graphics.getWidth() / _G.X_SCALE
local height = love.graphics.getHeight() / _G.Y_SCALE
local opacity = 0.3
local s = ""
if _G.P1_WIN then
s = "P1 Win! R - Restart"
end
if _G.P2_WIN then
s = "P2 Win! R - Restart"
end
if _G.P1_WIN or _G.P2_WIN then
-- Overlay
DrawGame() --Draw a single frame of the game
love.graphics.setColor(0.1, 0.1, 0.1, opacity) --overlay opaque img
love.graphics.rectangle("fill", 0, 0, width, height)
-- Who won text
local sw, sh = MenuFont:getWidth(s), GameFont:getHeight(s)
local centreX = width / 2
local centreY = height / 2
love.graphics.setFont(MenuFont)
love.graphics.setColor(1, 1, 1) -- white
love.graphics.print(s, centreX - sw / 2, centreY - sh / 2) -- who won
love.graphics.print(
"" .. _G.P1_COUNT .. ":" .. "" .. _G.P2_COUNT,
(centreX - sw / 2),
(centreY - sh / 2) - sh / 1.5
) -- score
end
end
function DrawWin()
winner()
love.graphics.setColor(255, 255, 255) -- reset colours
end
+1
View File
@@ -0,0 +1 @@
function UpdateWin(dt) end
+7
View File
@@ -0,0 +1,7 @@
function WinKeyPressed(key)
if key == "r" then
RestartGame()
_G.GAMESTATE = "GAME"
love.load()
end
end
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Regular → Executable
+64 -23
View File
@@ -1,7 +1,9 @@
Bullet = Object:extend()
cos = math.cos
sin = math.sin --optimisation
pi = math.pi
local pi = math.pi
local cos = math.cos
local sin = math.sin
local atan = math.atan
local deg = math.deg
function Bullet:new(x, y, p, speed, rotation)
self.image = love.graphics.newImage("assets/bullet.png")
@@ -20,9 +22,13 @@ function Bullet:new(x, y, p, speed, rotation)
self.originY = self.height / 2
self.collider = World:newCircleCollider(x, y, 10)
--self.collider = World:newRectangleCollider(x, y, 10, 10)
--self.collider:setType("")
self.collider:setFixedRotation(true)
self.collider:setPosition(self.x, self.y)
self.bounce = 0 -- how many times this bullet has bounced
if self.p == 1 then
self.collider:setCollisionClass("Bullet1")
elseif self.p == 2 then
@@ -31,35 +37,70 @@ function Bullet:new(x, y, p, speed, rotation)
end
function Bullet:update(dt)
--If a bullet hits a wall, make it bounce off the wall and change its rotation
if self.p == 1 then
if self.collider:enter("Wall") then
--calculate normal of the wall
--calculate the angle of reflection
local angle = (math.atan2(dx, dy))
--get normal of the wall without using getNormal()
-- Calculate the velocity
local dx = math.cos(self.rotation) * self.speed * dt
local dy = math.sin(self.rotation) * self.speed * dt
----TODO: fix this
-- Check for collisions
if self.collider:enter("Wall") then
self.bounce = self.bounce + 1
--set the new angle
self.rotation = angle
self.collider:setAngle(self.rotation)
end
dx = cos(self.rotation) * self.speed * dt
dy = sin(self.rotation) * self.speed * dt
self.collider:setLinearVelocity(dx, dy)
-- Get the collision normal
local collision_data = self.collider:getEnterCollisionData("Wall")
local contact = collision_data.contact
local normal_x, normal_y = contact:getNormal()
-- Debug print to verify normal values
--print("---------------------------------")
--print("Collision detected!")
--print("Normal X:", normal_x, "Normal Y:", normal_y)
--print("Initial Velocity X:", dx, "Initial Velocity Y:", dy)
--print("Initial Angle: ", self.rotation)
-- Reflect the velocity using the normal
local dot_product = dx * normal_x + dy * normal_y
dx = dx - 2 * dot_product * normal_x
dy = dy - 2 * dot_product * normal_y
--print("################################")
-- Debug print to verify reflected velocity
--print("Reflected Velocity X:", dx, "Reflected Velocity Y:", dy)
self.rotation = deg(atan(dy, dx))
-- Update the rotation based on the new velocity direction
--self.rotation = deg(atan(dy, dx))
--print("Reflected Angle (radians):", self.rotation)
--print("Reflected Angle (degrees):", self.rotation)
--print("---------------------------------")
end
if self.p == 2 then
local dx = cos(self.rotation) * self.speed * dt
local dy = sin(self.rotation) * self.speed * dt
self.collider:setLinearVelocity(dx, dy)
end
-- Set the linear velocity of the collider
self.collider:setLinearVelocity(dx, dy)
-- Update position
self.x = self.collider:getX()
self.y = self.collider:getY()
end
--[[
function Bullet:update(dt)
local normal_x, normal_y = 0, 0
local dx, dy = 0, 0
if self.p == 1 or self.p == 2 then
if self.collider:enter("Wall") then
self.collider:setLinearVelocity(dx, dy)
else
dx = cos(self.rotation) * self.speed * dt
dy = sin(self.rotation) * self.speed * dt
self.collider:setLinearVelocity(dx, dy)
end
end
-- Update position
self.x = self.collider:getX()
self.y = self.collider:getY()
end
]]
function Bullet:draw()
for _, _ in ipairs(Bullets1) do
love.graphics.draw(
-68
View File
@@ -1,68 +0,0 @@
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.
--
local Object = {}
Object.__index = Object
function Object:new()
end
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Object:implement(...)
for _, cls in pairs({...}) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
end
function Object:is(T)
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
end
function Object:__tostring()
return "Object"
end
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
end
return Object
View File
+6
View File
@@ -1,6 +1,12 @@
--Config file for the game
function love.conf(t)
--t.window.width = 1366
--t.window.height = 768
t.window.width = 1600
t.window.height = 960
t.window.title = "Tanks-A-Lot"
t.window.resizable = true
t.version = "11.5"
end
+47 -1
View File
@@ -1,8 +1,54 @@
-- WINDOW SCALE
-- Used to scale the game up or down
-- (scales STI world map and Walls in the game! )
-- (see debug for more)
X_SCALE = 1
Y_SCALE = 1
-- TILE SCALE
-- Since this game is put together rather badly
-- the game world is 1600x960
GAME_WORLD_DIM_WIDTH = 1600
GAME_WORLD_DIM_HEIGHT = 960
--[[
* Game states:
* - MENU
* - GAME
* - PAUSE
* - WIN
]]
--
GAMESTATE = "MENU"
-- Mute for game
MUTED = false
MENU_POS = 0
MENU_MAX = 3 --0 play, 1 ?, 2 ?, 3 quit
PAUSED = false
PAUSE_POS = 0
PAUSE_MAX = 2 -- 0 resume, 1 menu, 2 quit
PAUSE_MAX = 2 -- 0 resume, 1 menu, 2 quit
BULLETS_MAX = 10 -- MAX amount of bullets a player can shoot
BULLETS_BOUNCE_MAX = 10 -- MAX amount of bounces before exploding!
BULLETS_LIFETIME = 50 --TODO: impl. lifetime for a bullet!
-- Power up timer
PU_TIMER = 10
-- WIN flags for P1 and P2
P1_WIN = false
P2_WIN = false
-- Default speeds for bullets and player
DEFAULT_P_SPEED = 12000
DEFAULT_B_SPEED = 22000
-- WIN counts!
P1_COUNT = 0
P2_COUNT = 0
-- Current Level
CUR_LEVEL = 1
BIN
View File
Binary file not shown.
+43
View File
@@ -0,0 +1,43 @@
GUI = Object:extend()
function GUI:new() end
function GUI:newButton(x, y, w, h, text, selected)
love.graphics.setColor(255, 255, 255) -- reset colours
--x,y is the top left corner of the button
local rounding = 30 -- used for rounding the buttons
local xoff = x + 10
local yoff = y - 10
local textX, textY = 0, 0
-- Get width and height of text
local tw = MenuFont:getWidth(text)
local th = MenuFont:getHeight(text)
love.graphics.setFont(MenuFont)
if not selected then
love.graphics.setColor(love.math.colorFromBytes(41, 134, 204))
love.graphics.rectangle("fill", x, y, w, h, rounding, rounding)
-- Calculate position to center the text
textX = x + (w - tw) / 2
textY = y + (h - th) / 2
-- Place text inside the rectangle
love.graphics.setColor(0, 0, 0)
love.graphics.print(text, textX, textY)
elseif selected then
-- If selected, raise the button and draw a shadow
love.graphics.setColor(love.math.colorFromBytes(0, 0, 0))
love.graphics.rectangle("fill", x, y, w, h, rounding, rounding) -- shadow
love.graphics.setColor(love.math.colorFromBytes(244, 67, 54))
love.graphics.rectangle("fill", xoff, yoff, w, h, rounding, rounding) -- button offset
-- Calculate position to center the text
textX = xoff + (w - tw) / 2
textY = yoff + (h - th) / 2
-- Place text inside the rectangle
love.graphics.setColor(1, 1, 1)
love.graphics.print(text, textX, textY)
end
end
+30 -39
View File
@@ -7,62 +7,53 @@
-- the terms of the MIT license. See LICENSE for details.
--
local Object = {}
Object.__index = Object
function Object:new()
end
function Object:new() end
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Object:implement(...)
for _, cls in pairs({...}) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
for _, cls in pairs({ ... }) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
end
function Object:is(T)
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
end
function Object:__tostring()
return "Object"
return "Object"
end
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
local obj = setmetatable({}, self)
obj:new(...)
return obj
end
return Object
-193
View File
@@ -1,193 +0,0 @@
local clock = os.clock
--- Simple profiler written in Lua.
-- @module profile
-- @alias profile
local profile = {}
-- function labels
local _labeled = {}
-- function definitions
local _defined = {}
-- time of last call
local _tcalled = {}
-- total execution time
local _telapsed = {}
-- number of calls
local _ncalls = {}
-- list of internal profiler functions
local _internal = {}
--- This is an internal function.
-- @tparam string event Event type
-- @tparam number line Line number
-- @tparam[opt] table info Debug info table
function profile.hooker(event, line, info)
info = info or debug.getinfo(2, 'fnS')
local f = info.func
-- ignore the profiler itself
if _internal[f] or info.what ~= "Lua" then
return
end
-- get the function name if available
if info.name then
_labeled[f] = info.name
end
-- find the line definition
if not _defined[f] then
_defined[f] = info.short_src..":"..info.linedefined
_ncalls[f] = 0
_telapsed[f] = 0
end
if _tcalled[f] then
local dt = clock() - _tcalled[f]
_telapsed[f] = _telapsed[f] + dt
_tcalled[f] = nil
end
if event == "tail call" then
local prev = debug.getinfo(3, 'fnS')
profile.hooker("return", line, prev)
profile.hooker("call", line, info)
elseif event == 'call' then
_tcalled[f] = clock()
else
_ncalls[f] = _ncalls[f] + 1
end
end
--- Sets a clock function to be used by the profiler.
-- @tparam function func Clock function that returns a number
function profile.setclock(f)
assert(type(f) == "function", "clock must be a function")
clock = f
end
--- Starts collecting data.
function profile.start()
if rawget(_G, 'jit') then
jit.off()
jit.flush()
end
debug.sethook(profile.hooker, "cr")
end
--- Stops collecting data.
function profile.stop()
debug.sethook()
for f in pairs(_tcalled) do
local dt = clock() - _tcalled[f]
_telapsed[f] = _telapsed[f] + dt
_tcalled[f] = nil
end
-- merge closures
local lookup = {}
for f, d in pairs(_defined) do
local id = (_labeled[f] or '?')..d
local f2 = lookup[id]
if f2 then
_ncalls[f2] = _ncalls[f2] + (_ncalls[f] or 0)
_telapsed[f2] = _telapsed[f2] + (_telapsed[f] or 0)
_defined[f], _labeled[f] = nil, nil
_ncalls[f], _telapsed[f] = nil, nil
else
lookup[id] = f
end
end
collectgarbage('collect')
end
--- Resets all collected data.
function profile.reset()
for f in pairs(_ncalls) do
_ncalls[f] = 0
end
for f in pairs(_telapsed) do
_telapsed[f] = 0
end
for f in pairs(_tcalled) do
_tcalled[f] = nil
end
collectgarbage('collect')
end
--- This is an internal function.
-- @tparam function a First function
-- @tparam function b Second function
-- @treturn boolean True if "a" should rank higher than "b"
function profile.comp(a, b)
local dt = _telapsed[b] - _telapsed[a]
if dt == 0 then
return _ncalls[b] < _ncalls[a]
end
return dt < 0
end
--- Generates a report of functions that have been called since the profile was started.
-- Returns the report as a numeric table of rows containing the rank, function label, number of calls, total execution time and source code line number.
-- @tparam[opt] number limit Maximum number of rows
-- @treturn table Table of rows
function profile.query(limit)
local t = {}
for f, n in pairs(_ncalls) do
if n > 0 then
t[#t + 1] = f
end
end
table.sort(t, profile.comp)
if limit then
while #t > limit do
table.remove(t)
end
end
for i, f in ipairs(t) do
local dt = 0
if _tcalled[f] then
dt = clock() - _tcalled[f]
end
t[i] = { i, _labeled[f] or '?', _ncalls[f], _telapsed[f] + dt, _defined[f] }
end
return t
end
local cols = { 3, 29, 11, 24, 32 }
--- Generates a text report of functions that have been called since the profile was started.
-- Returns the report as a string that can be printed to the console.
-- @tparam[opt] number limit Maximum number of rows
-- @treturn string Text-based profiling report
function profile.report(n)
local out = {}
local report = profile.query(n)
for i, row in ipairs(report) do
for j = 1, 5 do
local s = row[j]
local l2 = cols[j]
s = tostring(s)
local l1 = s:len()
if l1 < l2 then
s = s..(' '):rep(l2-l1)
elseif l1 > l2 then
s = s:sub(l1 - l2 + 1, l1)
end
row[j] = s
end
out[i] = table.concat(row, ' | ')
end
local row = " +-----+-------------------------------+-------------+--------------------------+----------------------------------+ \n"
local col = " | # | Function | Calls | Time | Code | \n"
local sz = row..col..row
if #out > 0 then
sz = sz..' | '..table.concat(out, ' | \n | ')..' | \n'
end
return '\n'..sz..row
end
-- store all internal profiler functions
for _, v in pairs(profile) do
if type(v) == "function" then
_internal[v] = true
end
end
return profile
+147 -118
View File
@@ -10,150 +10,179 @@ local module = {}
-- @param sort If "size" will sort by size, or if "id" will sort by id
-- @param ids Array with ids of each file
-- @param pow2 If true, will force a power of 2 size
function module.Atlas( files, sort, ids, pow2 )
function module.Atlas(files, sort, ids, pow2)
local function Node(x, y, w, h)
return { x = x, y = y, w = w, h = h }
end
local function Node(x, y, w, h)
return {x = x, y = y, w = w, h = h}
end
local function nextpow2(n)
local res = 1
while res <= n do
res = res * 2
end
return res
end
local function nextpow2( n )
local res = 1
while res <= n do
res = res * 2
end
return res
end
local function loadImgs()
local images = {}
for i = 1, #files do
images[i] = {}
--images[i].name = files[i]
if ids then
images[i].id = ids[i]
end
images[i].img = love.graphics.newImage(files[i])
images[i].w = images[i].img:getWidth()
images[i].h = images[i].img:getHeight()
images[i].area = images[i].w * images[i].h
end
if sort == "size" or sort == "id" then
table.sort(images, function(a, b)
return (a.area > b.area)
end)
end
return images
end
local function loadImgs()
local images = {}
for i = 1, #files do
images[i] = {}
--images[i].name = files[i]
if ids then images[i].id = ids[i] end
images[i].img = love.graphics.newImage( files[i] )
images[i].w = images[i].img:getWidth()
images[i].h = images[i].img:getHeight()
images[i].area = images[i].w * images[i].h
end
if sort == "size" or sort == "id" then
table.sort( images, function( a, b ) return ( a.area > b.area ) end )
end
return images
end
--TODO: understand this func
local function add(root, id, w, h)
if root.left or root.right then
if root.left then
local node = add(root.left, id, w, h)
if node then
return node
end
end
if root.right then
local node = add(root.right, id, w, h)
if node then
return node
end
end
return nil
end
--TODO: understand this func
local function add(root, id, w, h)
if root.left or root.right then
if root.left then
local node = add(root.left, id, w, h)
if node then return node end
end
if root.right then
local node = add(root.right, id, w, h)
if node then return node end
end
return nil
end
if w > root.w or h > root.h then
return nil
end
if w > root.w or h > root.h then return nil end
local _w, _h = root.w - w, root.h - h
local _w, _h = root.w - w, root.h - h
if _w <= _h then
root.left = Node(root.x + w, root.y, _w, h)
root.right = Node(root.x, root.y + h, root.w, _h)
else
root.left = Node(root.x, root.y + h, w, _h)
root.right = Node(root.x + w, root.y, _w, root.h)
end
if _w <= _h then
root.left = Node(root.x + w, root.y, _w, h)
root.right = Node(root.x, root.y + h, root.w, _h)
else
root.left = Node(root.x, root.y + h, w, _h)
root.right = Node(root.x + w, root.y, _w, root.h)
end
root.w = w
root.h = h
root.id = id
root.w = w
root.h = h
root.id = id
return root
end
return root
end
local function unmap(root)
if not root then
return {}
end
local function unmap(root)
if not root then return {} end
local tree = {}
if root.id then
tree[root.id] = {}
tree[root.id].x, tree[root.id].y = root.x, root.y
end
local tree = {}
if root.id then
tree[root.id] = {}
tree[root.id].x, tree[root.id].y = root.x, root.y
end
local left = unmap(root.left)
local right = unmap(root.right)
local left = unmap(root.left)
local right = unmap(root.right)
for k, v in pairs(left) do
tree[k] = {}
tree[k].x, tree[k].y = v.x, v.y
end
for k, v in pairs(right) do
tree[k] = {}
tree[k].x, tree[k].y = v.x, v.y
end
for k, v in pairs(left) do
tree[k] = {}
tree[k].x, tree[k].y = v.x, v.y
end
for k, v in pairs(right) do
tree[k] = {}
tree[k].x, tree[k].y = v.x, v.y
end
return tree
end
return tree
end
local function bake()
local images = loadImgs()
local function bake()
local images = loadImgs()
local root = {}
local w, h = images[1].w, images[1].h
local root = {}
local w, h = images[1].w, images[1].h
if pow2 then
if w % 1 == 0 then
w = nextpow2(w)
end
if h % 1 == 0 then
h = nextpow2(h)
end
end
if pow2 then
if w % 1 == 0 then w = nextpow2(w) end
if h % 1 == 0 then h = nextpow2(h) end
end
repeat
local node
repeat
local node
root = Node(0, 0, w, h)
root = Node(0, 0, w, h)
for i = 1, #images do
node = add(root, i, images[i].w, images[i].h)
if not node then
break
end
end
for i = 1, #images do
node = add(root, i, images[i].w, images[i].h)
if not node then break end
end
if not node then
if h <= w then
if pow2 then
h = h * 2
else
h = h + 1
end
else
if pow2 then
w = w * 2
else
w = w + 1
end
end
else
break
end
until false
if not node then
if h <= w then
if pow2 then h = h * 2 else h = h + 1 end
else
if pow2 then w = w * 2 else w = w + 1 end
end
else
break
end
until false
local limits = love.graphics.getSystemLimits()
if w > limits.texturesize or h > limits.texturesize then
return "Resulting texture is too large for this system"
end
local limits = love.graphics.getSystemLimits()
if w > limits.texturesize or h > limits.texturesize then
return "Resulting texture is too large for this system"
end
local coords = unmap(root)
local map = love.graphics.newCanvas(w, h)
love.graphics.setCanvas(map)
-- love.graphics.clear()
local coords = unmap(root)
local map = love.graphics.newCanvas(w, h)
love.graphics.setCanvas( map )
-- love.graphics.clear()
for i = 1, #images do
love.graphics.draw(images[i].img, coords[i].x, coords[i].y)
if ids then
coords[i].id = images[i].id
end
end
love.graphics.setCanvas()
for i = 1, #images do
love.graphics.draw(images[i].img, coords[i].x, coords[i].y)
if ids then coords[i].id = images[i].id end
end
love.graphics.setCanvas()
if sort == "ids" then
table.sort(coords, function(a, b)
return (a.id < b.id)
end)
end
if sort == "ids" then
table.sort( coords, function( a, b ) return ( a.id < b.id ) end )
end
return { image = map, coords = coords }
end
return { image = map, coords = coords }
end
return bake()
return bake()
end
return module
+1 -1
View File
@@ -1,4 +1,4 @@
local lg = _G.love.graphics
local lg = _G.love.graphics
local graphics = { isCreated = lg and true or false }
function graphics.newSpriteBatch(...)
+292 -316
View File
File diff suppressed because it is too large Load Diff
+57 -57
View File
@@ -4,14 +4,14 @@
-- @copyright 2019
-- @license MIT/X11
local love = _G.love
local utils = require((...):gsub('plugins.box2d', 'utils'))
local lg = require((...):gsub('plugins.box2d', 'graphics'))
local love = _G.love
local utils = require((...):gsub("plugins.box2d", "utils"))
local lg = require((...):gsub("plugins.box2d", "graphics"))
return {
box2d_LICENSE = "MIT/X11",
box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
box2d_VERSION = "2.3.2.7",
box2d_LICENSE = "MIT/X11",
box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
box2d_VERSION = "2.3.2.7",
box2d_DESCRIPTION = "Box2D hooks for STI.",
--- Initialize Box2D physics world.
@@ -19,7 +19,7 @@ return {
box2d_init = function(map, world)
assert(love.physics, "To use the Box2D plugin, please enable the love.physics module.")
local body = love.physics.newBody(world, map.offsetx, map.offsety)
local body = love.physics.newBody(world, map.offsetx, map.offsety)
local collision = {
body = body,
}
@@ -40,32 +40,32 @@ return {
local currentBody = body
--dynamic are objects/players etc.
if userdata.properties.dynamic == true then
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'dynamic')
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "dynamic")
-- static means it shouldn't move. Things like walls/ground.
elseif userdata.properties.static == true then
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'static')
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "static")
-- kinematic means that the object is static in the game world but effects other bodies
elseif userdata.properties.kinematic == true then
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'kinematic')
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "kinematic")
end
local fixture = love.physics.newFixture(currentBody, shape)
fixture:setUserData(userdata)
-- Set some custom properties from userdata (or use default set by box2d)
fixture:setFriction(userdata.properties.friction or 0.2)
fixture:setFriction(userdata.properties.friction or 0.2)
fixture:setRestitution(userdata.properties.restitution or 0.0)
fixture:setSensor(userdata.properties.sensor or false)
fixture:setSensor(userdata.properties.sensor or false)
fixture:setFilterData(
userdata.properties.categories or 1,
userdata.properties.mask or 65535,
userdata.properties.group or 0
userdata.properties.mask or 65535,
userdata.properties.group or 0
)
local obj = {
object = object,
body = currentBody,
shape = shape,
object = object,
body = currentBody,
shape = shape,
fixture = fixture,
}
@@ -84,33 +84,33 @@ return {
local function calculateObjectPosition(object, tile)
local o = {
shape = object.shape,
x = (object.dx or object.x) + map.offsetx,
y = (object.dy or object.y) + map.offsety,
w = object.width,
h = object.height,
polygon = object.polygon or object.polyline or object.ellipse or object.rectangle
shape = object.shape,
x = (object.dx or object.x) + map.offsetx,
y = (object.dy or object.y) + map.offsety,
w = object.width,
h = object.height,
polygon = object.polygon or object.polyline or object.ellipse or object.rectangle,
}
local userdata = {
object = o,
properties = object.properties
object = o,
properties = object.properties,
}
o.r = object.rotation or 0
if o.shape == "rectangle" then
local cos = math.cos(math.rad(o.r))
local sin = math.sin(math.rad(o.r))
local oy = 0
local oy = 0
if object.gid then
local tileset = map.tilesets[map.tiles[object.gid].tileset]
local lid = object.gid - tileset.firstgid
local t = {}
local lid = object.gid - tileset.firstgid
local t = {}
-- This fixes a height issue
o.y = o.y + map.tiles[object.gid].offset.y
oy = o.h
o.y = o.y + map.tiles[object.gid].offset.y
oy = o.h
for _, tt in ipairs(tileset.tiles) do
if tt.id == lid then
@@ -133,10 +133,10 @@ return {
end
o.polygon = {
{ x=o.x+0, y=o.y+0 },
{ x=o.x+o.w, y=o.y+0 },
{ x=o.x+o.w, y=o.y+o.h },
{ x=o.x+0, y=o.y+o.h }
{ x = o.x + 0, y = o.y + 0 },
{ x = o.x + o.w, y = o.y + 0 },
{ x = o.x + o.w, y = o.y + o.h },
{ x = o.x + 0, y = o.y + o.h },
}
for _, vertex in ipairs(o.polygon) do
@@ -149,7 +149,7 @@ return {
if not o.polygon then
o.polygon = utils.convert_ellipse_to_polygon(o.x, o.y, o.w, o.h)
end
local vertices = getPolygonVertices(o)
local vertices = getPolygonVertices(o)
local triangles = love.math.triangulate(vertices)
for _, triangle in ipairs(triangles) do
@@ -167,7 +167,7 @@ return {
end
end
local vertices = getPolygonVertices(o)
local vertices = getPolygonVertices(o)
local triangles = love.math.triangulate(vertices)
for _, triangle in ipairs(triangles) do
@@ -197,12 +197,12 @@ return {
-- Every instance of a tile
if tile.properties.collidable == true then
local object = {
shape = "rectangle",
x = instance.x,
y = instance.y,
width = map.tilewidth,
height = map.tileheight,
properties = tile.properties
shape = "rectangle",
x = instance.x,
y = instance.y,
width = map.tilewidth,
height = map.tileheight,
properties = tile.properties,
}
calculateObjectPosition(object, instance)
@@ -222,12 +222,12 @@ return {
for _, instance in ipairs(tiles) do
if instance.layer == layer then
local object = {
shape = "rectangle",
x = instance.x,
y = instance.y,
width = tileset.tilewidth,
height = tileset.tileheight,
properties = tile.properties
shape = "rectangle",
x = instance.x,
y = instance.y,
width = tileset.tilewidth,
height = tileset.tileheight,
properties = tile.properties,
}
calculateObjectPosition(object, instance)
@@ -240,12 +240,12 @@ return {
end
elseif layer.type == "imagelayer" then
local object = {
shape = "rectangle",
x = layer.x or 0,
y = layer.y or 0,
width = layer.width,
height = layer.height,
properties = layer.properties
shape = "rectangle",
x = layer.x or 0,
y = layer.y or 0,
width = layer.width,
height = layer.height,
properties = layer.properties,
}
calculateObjectPosition(object)
@@ -295,7 +295,7 @@ return {
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
for _, obj in ipairs(collision) do
local points = {obj.body:getWorldPoints(obj.shape:getPoints())}
local points = { obj.body:getWorldPoints(obj.shape:getPoints()) }
local shape_type = obj.shape:getType()
if shape_type == "edge" or shape_type == "chain" then
@@ -303,12 +303,12 @@ return {
elseif shape_type == "polygon" then
love.graphics.polygon("line", points)
else
error("sti box2d plugin does not support "..shape_type.." shapes")
error("sti box2d plugin does not support " .. shape_type .. " shapes")
end
end
lg.pop()
end
end,
}
--- Custom Properties in Tiled are used to tell this plugin what to do.
+48 -55
View File
@@ -4,13 +4,13 @@
-- @copyright 2019
-- @license MIT/X11
local lg = require((...):gsub('plugins.bump', 'graphics'))
local lg = require((...):gsub("plugins.bump", "graphics"))
return {
bump_LICENSE = "MIT/X11",
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
bump_VERSION = "3.1.7.1",
bump_DESCRIPTION = "Bump hooks for STI.",
bump_LICENSE = "MIT/X11",
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
bump_VERSION = "3.1.7.1",
bump_DESCRIPTION = "Bump hooks for STI.",
--- Adds each collidable tile to the Bump world.
-- @param world The Bump world to add objects to.
@@ -29,15 +29,14 @@ return {
for _, object in ipairs(tile.objectGroup.objects) do
if object.properties.collidable == true then
local t = {
name = object.name,
type = object.type,
x = instance.x + map.offsetx + object.x,
y = instance.y + map.offsety + object.y,
width = object.width,
height = object.height,
layer = instance.layer,
properties = object.properties
name = object.name,
type = object.type,
x = instance.x + map.offsetx + object.x,
y = instance.y + map.offsety + object.y,
width = object.width,
height = object.height,
layer = instance.layer,
properties = object.properties,
}
world:add(t, t.x, t.y, t.width, t.height)
@@ -49,13 +48,13 @@ return {
-- Every instance of a tile
if tile.properties and tile.properties.collidable == true then
local t = {
x = instance.x + map.offsetx,
y = instance.y + map.offsety,
width = map.tilewidth,
height = map.tileheight,
layer = instance.layer,
type = tile.type,
properties = tile.properties
x = instance.x + map.offsetx,
y = instance.y + map.offsety,
width = map.tilewidth,
height = map.tileheight,
layer = instance.layer,
type = tile.type,
properties = tile.properties,
}
world:add(t, t.x, t.y, t.width, t.height)
@@ -72,19 +71,18 @@ return {
if layer.type == "tilelayer" then
for y, tiles in ipairs(layer.data) do
for x, tile in pairs(tiles) do
if tile.objectGroup then
for _, object in ipairs(tile.objectGroup.objects) do
if object.properties.collidable == true then
local t = {
name = object.name,
type = object.type,
x = ((x-1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x,
y = ((y-1) * map.tileheight + tile.offset.y + map.offsety) + object.y,
width = object.width,
height = object.height,
layer = layer,
properties = object.properties
name = object.name,
type = object.type,
x = ((x - 1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x,
y = ((y - 1) * map.tileheight + tile.offset.y + map.offsety) + object.y,
width = object.width,
height = object.height,
layer = layer,
properties = object.properties,
}
world:add(t, t.x, t.y, t.width, t.height)
@@ -93,15 +91,14 @@ return {
end
end
local t = {
x = (x-1) * map.tilewidth + tile.offset.x + map.offsetx,
y = (y-1) * map.tileheight + tile.offset.y + map.offsety,
width = tile.width,
height = tile.height,
layer = layer,
type = tile.type,
properties = tile.properties
x = (x - 1) * map.tilewidth + tile.offset.x + map.offsetx,
y = (y - 1) * map.tileheight + tile.offset.y + map.offsety,
width = tile.width,
height = tile.height,
layer = layer,
type = tile.type,
properties = tile.properties,
}
world:add(t, t.x, t.y, t.width, t.height)
@@ -112,23 +109,23 @@ return {
world:add(layer, layer.x, layer.y, layer.width, layer.height)
table.insert(collidables, layer)
end
end
end
-- individual collidable objects in a layer that is not "collidable"
-- or whole collidable objects layer
if layer.type == "objectgroup" then
if layer.type == "objectgroup" then
for _, obj in ipairs(layer.objects) do
if layer.properties.collidable == true or obj.properties.collidable == true then
if obj.shape == "rectangle" then
local t = {
name = obj.name,
type = obj.type,
x = obj.x + map.offsetx,
y = obj.y + map.offsety,
width = obj.width,
height = obj.height,
layer = layer,
properties = obj.properties
name = obj.name,
type = obj.type,
x = obj.x + map.offsetx,
y = obj.y + map.offsety,
width = obj.width,
height = obj.height,
layer = layer,
properties = obj.properties,
}
if obj.gid then
@@ -143,7 +140,7 @@ return {
end
end
map.bump_world = world
map.bump_world = world
map.bump_collidables = collidables
end,
@@ -157,11 +154,7 @@ return {
for i = #collidables, 1, -1 do
local obj = collidables[i]
if obj.layer == layer
and (
layer.properties.collidable == true
or obj.properties.collidable == true
) then
if obj.layer == layer and (layer.properties.collidable == true or obj.properties.collidable == true) then
map.bump_world:remove(obj)
table.remove(collidables, i)
end
@@ -185,7 +178,7 @@ return {
end
lg.pop()
end
end,
}
--- Custom Properties in Tiled are used to tell this plugin what to do.
+41 -37
View File
@@ -3,19 +3,21 @@ local utils = {}
-- https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua#L286
function utils.format_path(path)
local np_gen1,np_gen2 = '[^SEP]+SEP%.%.SEP?','SEP+%.?SEP'
local np_pat1, np_pat2 = np_gen1:gsub('SEP','/'), np_gen2:gsub('SEP','/')
local np_gen1, np_gen2 = "[^SEP]+SEP%.%.SEP?", "SEP+%.?SEP"
local np_pat1, np_pat2 = np_gen1:gsub("SEP", "/"), np_gen2:gsub("SEP", "/")
local k
repeat -- /./ -> /
path,k = path:gsub(np_pat2,'/',1)
path, k = path:gsub(np_pat2, "/", 1)
until k == 0
repeat -- A/../ -> (empty)
path,k = path:gsub(np_pat1,'',1)
path, k = path:gsub(np_pat1, "", 1)
until k == 0
if path == '' then path = '.' end
if path == "" then
path = "."
end
return path
end
@@ -25,8 +27,12 @@ function utils.compensate(tile, tileX, tileY, tileW, tileH)
local compx = 0
local compy = 0
if tile.sx < 0 then compx = tileW end
if tile.sy < 0 then compy = tileH end
if tile.sx < 0 then
compx = tileW
end
if tile.sy < 0 then
compy = tileH
end
if tile.r > 0 then
tileX = tileX + tileH - compy
@@ -51,13 +57,17 @@ end
-- We just don't know.
function utils.get_tiles(imageW, tileW, margin, spacing)
imageW = imageW - margin
imageW = imageW - margin
local n = 0
while imageW >= tileW do
imageW = imageW - tileW
if n ~= 0 then imageW = imageW - spacing end
if imageW >= 0 then n = n + 1 end
if n ~= 0 then
imageW = imageW - spacing
end
if imageW >= 0 then
n = n + 1
end
end
return n
@@ -65,8 +75,8 @@ end
-- Decompress tile layer data
function utils.get_decompressed_data(data)
local ffi = require "ffi"
local d = {}
local ffi = require("ffi")
local d = {}
local decoded = ffi.cast("uint32_t*", data)
for i = 0, data:len() / ffi.sizeof("uint32_t") do
@@ -79,8 +89,8 @@ end
-- Convert a Tiled ellipse object to a LOVE polygon
function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
local ceil = math.ceil
local cos = math.cos
local sin = math.sin
local cos = math.cos
local sin = math.sin
local function calc_segments(segments)
local function vdist(a, b)
@@ -95,7 +105,7 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
segments = segments or 64
local vertices = {}
local v = { 1, 2, ceil(segments/4-1), ceil(segments/4) }
local v = { 1, 2, ceil(segments / 4 - 1), ceil(segments / 4) }
local m
if love and love.physics then
@@ -106,8 +116,8 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
for _, i in ipairs(v) do
local angle = (i / segments) * math.pi * 2
local px = x + w / 2 + cos(angle) * w / 2
local py = y + h / 2 + sin(angle) * h / 2
local px = x + w / 2 + cos(angle) * w / 2
local py = y + h / 2 + sin(angle) * h / 2
table.insert(vertices, { x = px / m, y = py / m })
end
@@ -117,7 +127,7 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
-- Box2D threshold
if dist1 < 0.0025 or dist2 < 0.0025 then
return calc_segments(segments-2)
return calc_segments(segments - 2)
end
return segments
@@ -130,8 +140,8 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
for i = 0, segments do
local angle = (i / segments) * math.pi * 2
local px = x + w / 2 + cos(angle) * w / 2
local py = y + h / 2 + sin(angle) * h / 2
local px = x + w / 2 + cos(angle) * w / 2
local py = y + h / 2 + sin(angle) * h / 2
table.insert(vertices, { x = px, y = py })
end
@@ -141,30 +151,26 @@ end
function utils.rotate_vertex(map, vertex, x, y, cos, sin, oy)
if map.orientation == "isometric" then
x, y = utils.convert_isometric_to_screen(map, x, y)
x, y = utils.convert_isometric_to_screen(map, x, y)
vertex.x, vertex.y = utils.convert_isometric_to_screen(map, vertex.x, vertex.y)
end
vertex.x = vertex.x - x
vertex.y = vertex.y - y
return
x + cos * vertex.x - sin * vertex.y,
y + sin * vertex.x + cos * vertex.y - (oy or 0)
return x + cos * vertex.x - sin * vertex.y, y + sin * vertex.x + cos * vertex.y - (oy or 0)
end
--- Project isometric position to cartesian position
function utils.convert_isometric_to_screen(map, x, y)
local mapW = map.width
local tileW = map.tilewidth
local tileH = map.tileheight
local tileX = x / tileH
local tileY = y / tileH
local mapW = map.width
local tileW = map.tilewidth
local tileH = map.tileheight
local tileX = x / tileH
local tileY = y / tileH
local offsetX = mapW * tileW / 2
return
(tileX - tileY) * tileW / 2 + offsetX,
(tileX + tileY) * tileH / 2
return (tileX - tileY) * tileW / 2 + offsetX, (tileX + tileY) * tileH / 2
end
function utils.hex_to_color(hex)
@@ -175,16 +181,14 @@ function utils.hex_to_color(hex)
return {
r = tonumber(hex:sub(1, 2), 16) / 255,
g = tonumber(hex:sub(3, 4), 16) / 255,
b = tonumber(hex:sub(5, 6), 16) / 255
b = tonumber(hex:sub(5, 6), 16) / 255,
}
end
function utils.pixel_function(_, _, r, g, b, a)
local mask = utils._TC
if r == mask.r and
g == mask.g and
b == mask.b then
if r == mask.r and g == mask.g and b == mask.b then
return r, g, b, 0
end
@@ -205,7 +209,7 @@ end
function utils.deepCopy(t)
local copy = {}
for k,v in pairs(t) do
for k, v in pairs(t) do
if type(v) == "table" then
v = utils.deepCopy(v)
end
+1136 -929
View File
File diff suppressed because it is too large Load Diff
+1317 -1152
View File
File diff suppressed because it is too large Load Diff
+117 -84
View File
@@ -1,10 +1,69 @@
require 'constants'
Object = require("libs/classic")
require("constants")
WF = require("libs/windfield")
STI = require("libs/sti")
World = WF.newWorld(0, 0) --no gravity
--World:setQueryDebugDrawing(true) -- Draws the area of a query for 10 frames
World:addCollisionClass("Player1")
World:addCollisionClass("Bullet1")
World:addCollisionClass("Player2")
World:addCollisionClass("Bullet2")
World:addCollisionClass("Wall")
World:addCollisionClass("PowerUp")
require("gui")
require("powerups/powerup")
require("powerups/speed")
require("restart")
require("truncate")
require("player")
require("bullet")
require("mapsloader")
require("Game/UpdateGame")
require("Menu/UpdateMenu")
require("Pause/UpdatePause")
require("Win/UpdateWin")
require("Game/DrawGame")
require("Menu/DrawMenu")
require("Pause/DrawPause")
require("Win/DrawWin")
require("Game/GameKeyPressed")
require("Menu/MenuKeyPressed")
require("Pause/PauseKeyPressed")
require("Win/WinKeyPressed")
--Fonts used in the game
GameFont = love.graphics.newFont("assets/Daydream.ttf", 60)
DebugFont = love.graphics.newFont("assets/Daydream.ttf", 12)
MenuFont = love.graphics.newFont("assets/Daydream.ttf", 45)
Walls = {}
-- Music streaming
musicMenu = love.audio.newSource("music/menu.mp3", "stream") or nil
musicBattle = love.audio.newSource("music/battle.mp3", "stream") or nil
--musicStory = love.audio.newSource("music/story.mp3", "stream") or nil
musicPause = musicBattle:clone()
musicPause:setFilter({
type = "lowpass",
volume = 0.7,
highgain = 0.4,
})
function love.run()
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
if love.load then
love.load(love.arg.parseGameArguments(arg), arg)
end
-- We don't want the first frame's dt to include time taken by love.load.
if love.timer then love.timer.step() end
if love.timer then
love.timer.step()
end
local dt = 0
@@ -13,111 +72,83 @@ function love.run()
-- Process events.
if love.event then
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
for name, a, b, c, d, e, f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
end
end
love.handlers[name](a,b,c,d,e,f)
love.handlers[name](a, b, c, d, e, f)
end
end
-- Update dt, as we'll be passing it to update
if love.timer then dt = love.timer.step() end
if love.timer then
dt = love.timer.step()
end
-- Call update and draw
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
if love.update then
love.update(dt)
end -- will pass 0 if love.timer is disabled
if love.graphics and love.graphics.isActive() then
love.graphics.origin()
love.graphics.clear(love.graphics.getBackgroundColor())
if love.draw then love.draw() end
if love.draw then
love.draw()
end
love.graphics.present()
end
if love.timer then love.timer.sleep(0.001) end
if love.timer then
love.timer.sleep(0.001)
end
end
end
function love.resized()
--TOD0: fix scaling!
end
function love.load()
Object = require("libs/classic")
require("player")
require("bullet")
-- Set a random seed
love.math.setRandomSeed(love.timer.getTime())
-- Figure out the X_SCALE and Y_SCALE
local curWidth, curHeight = love.graphics.getDimensions()
_G.X_SCALE = truncate(curWidth / GAME_WORLD_DIM_WIDTH, 3)
_G.Y_SCALE = truncate(curHeight / GAME_WORLD_DIM_HEIGHT, 3)
WF = require("libs/windfield")
STI = require("libs/sti")
require("Game/UpdateGame")
require("Menu/UpdateMenu")
require("Pause/UpdatePause")
require("Game/DrawGame")
require("Menu/DrawMenu")
require("Pause/DrawPause")
require("Game/GameKeyPressed")
require("Menu/MenuKeyPressed")
require("Pause/PauseKeyPressed")
require("mapsloader")
--WindField
World = WF.newWorld(0, 0) --no gravity
World:setQueryDebugDrawing(true) -- Draws the area of a query for 10 frames
World:addCollisionClass("Player1")
World:addCollisionClass("Bullet1")
World:addCollisionClass("Player2")
World:addCollisionClass("Bullet2")
World:addCollisionClass("Wall")
World:addCollisionClass("New") -- Used to make sure the bullet doesn't collide with the player that shot it
--STI Map
loadMap(1)
--Fonts used in the game
GameFont = love.graphics.newFont("assets/Daydream.ttf", 60)
DebugFont = love.graphics.newFont("assets/Daydream.ttf", 12)
MenuFont = love.graphics.newFont("assets/Daydream.ttf", 45)
--Game consts
--Game values (reset after each load)
HEALTH = 3
DELAY = 0.5
MAX = 6 --MAX number of bullets|
P1_DELAY = 0.5
P2_DELAY = 0.5
--Bullet lists
Bullets1 = {}
Bullets2 = {}
--PowerUp stuff
PowerUps = {}
PUTimeToPlace = _G.PU_TIMER
DebugFlag = false
EnableKeyPress1 = true
KeyPressTime1 = 0
KeyDelay1 = DELAY
KeyDelay1 = P1_DELAY
EnableKeyPress2 = true
KeyPressTime2 = 0
KeyDelay2 = DELAY
KeyDelay2 = P2_DELAY
local playerSpeed = 12000
UserPlayer1 = Player(1, 1000, 100, HEALTH, "assets/player1.png", playerSpeed)
UserPlayer2 = Player(2, 200, 300, HEALTH, "assets/player2.png", playerSpeed)
-- Music streaming
musicMenu = love.audio.newSource("music/menu.mp3", "stream")
musicBattle = love.audio.newSource("music/battle.mp3", "stream")
musicStory = love.audio.newSource("music/story.mp3", "stream")
musicPause = musicBattle:clone()
musicPause:setFilter{
type = 'lowpass',
volume = 0.3,
highgain = 0.4,
}
--TODO: two player speeds for upgrades
UserPlayer1 = Player(1, 1000, 100, HEALTH, "assets/player1.png", 12000)
UserPlayer2 = Player(2, 200, 300, HEALTH, "assets/player2.png", 12000)
--STI Map loading
LoadMap(_G.CUR_LEVEL)
end
function love.keypressed(key)
@@ -130,14 +161,16 @@ function love.keypressed(key)
if _G.GAMESTATE == "GAME" then
GameKeyPressed(key)
end
if _G.GAMESTATE == "WIN" then
WinKeyPressed(key)
end
end
function love.update(dt)
if _G.GAMESTATE == "MENU" then
UpdateMenu(dt)
-- Handle music
if not musicMenu:isPlaying() then
if not musicMenu:isPlaying() and not _G.MUTED then
musicMenu:setVolume(0.5)
love.audio.play(musicMenu)
end
@@ -145,9 +178,9 @@ function love.update(dt)
if _G.GAMESTATE == "PAUSE" then
UpdatePause(dt)
-- Handle music
if not musicPause:isPlaying() then
--musicBattle:setVolume(0)
--musicPause:setVolume(0.5)
if not musicPause:isPlaying() and not _G.MUTED then
musicBattle:setVolume(0)
musicPause:setVolume(0.5)
love.audio.play(musicBattle)
love.audio.play(musicPause)
end
@@ -155,13 +188,16 @@ function love.update(dt)
if _G.GAMESTATE == "GAME" then
UpdateGame(dt)
-- Handle music
if not musicBattle:isPlaying() then
--musicBattle:setVolume(0.5)
--musicPause:setVolume(0)
if not musicBattle:isPlaying() and not _G.MUTED then
musicBattle:setVolume(0.5)
musicPause:setVolume(0)
love.audio.play(musicBattle)
love.audio.play(musicPause)
end
end
if _G.GAMESTATE == "WIN" then
UpdateWin(dt)
end
end
function love.draw()
@@ -173,11 +209,8 @@ function love.draw()
end
if _G.GAMESTATE == "GAME" then
DrawGame()
if DebugFlag then
love.graphics.setFont(DebugFont)
love.graphics.print("Debug Mode", 1200, 850)
love.graphics.print("" .. GAMESTATE, 200, 200)
end
end
if _G.GAMESTATE == "WIN" then
DrawWin()
end
end
+290
View File
@@ -0,0 +1,290 @@
return {
version = "1.10",
luaversion = "5.1",
tiledversion = "1.11.0",
class = "",
orientation = "orthogonal",
renderorder = "right-down",
width = 25,
height = 15,
tilewidth = 64,
tileheight = 64,
nextlayerid = 4,
nextobjectid = 16,
properties = {},
tilesets = {
{
name = "floor",
firstgid = 1,
class = "",
tilewidth = 64,
tileheight = 64,
spacing = 0,
margin = 0,
columns = 9,
image = "../assets/tileset.png",
imagewidth = 576,
imageheight = 384,
objectalignment = "unspecified",
tilerendersize = "tile",
fillmode = "stretch",
tileoffset = {
x = 0,
y = 0
},
grid = {
orientation = "orthogonal",
width = 64,
height = 64
},
properties = {},
wangsets = {},
tilecount = 54,
tiles = {}
}
},
layers = {
{
type = "tilelayer",
x = 0,
y = 0,
width = 25,
height = 15,
id = 1,
name = "floor",
class = "",
visible = true,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
encoding = "lua",
data = {
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21
}
},
{
type = "tilelayer",
x = 0,
y = 0,
width = 25,
height = 15,
id = 2,
name = "inner walls",
class = "",
visible = true,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
encoding = "lua",
data = {
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, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 28, 29, 29, 29, 29, 29, 30, 0, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 37, 38, 38, 38, 38, 38, 39, 0, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 46, 47, 38, 38, 38, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 28, 29, 30, 0, 0, 0, 0, 28, 29, 30, 0, 0, 0, 0,
0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0,
0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0,
0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0,
0, 0, 0, 0, 46, 47, 48, 0, 0, 0, 0, 46, 47, 48, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 38, 38, 38, 29, 30, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 30, 0, 0, 37, 38, 38, 38, 38, 38, 39, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 0, 0, 46, 47, 47, 47, 47, 47, 48, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 48, 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
}
},
{
type = "objectgroup",
draworder = "topdown",
id = 3,
name = "Walls",
class = "",
visible = false,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
objects = {
{
id = 1,
name = "",
type = "",
shape = "rectangle",
x = 128,
y = 128,
width = 448,
height = 192,
rotation = 0,
visible = true,
properties = {}
},
{
id = 2,
name = "",
type = "",
shape = "rectangle",
x = 256,
y = 320,
width = 192,
height = 320,
rotation = 0,
visible = true,
properties = {}
},
{
id = 3,
name = "",
type = "",
shape = "rectangle",
x = 704,
y = 80,
width = 192,
height = 176,
rotation = 0,
visible = true,
properties = {}
},
{
id = 4,
name = "",
type = "",
shape = "rectangle",
x = 704,
y = 320,
width = 192,
height = 320,
rotation = 0,
visible = true,
properties = {}
},
{
id = 5,
name = "",
type = "",
shape = "rectangle",
x = 704,
y = 704,
width = 192,
height = 192,
rotation = 0,
visible = true,
properties = {}
},
{
id = 6,
name = "",
type = "",
shape = "rectangle",
x = 1024,
y = 640,
width = 448,
height = 192,
rotation = 0,
visible = true,
properties = {}
},
{
id = 7,
name = "",
type = "",
shape = "rectangle",
x = 1152,
y = 320,
width = 192,
height = 320,
rotation = 0,
visible = true,
properties = {}
},
{
id = 9,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 0,
width = 1184,
height = 16,
rotation = 0,
visible = true,
properties = {}
},
{
id = 10,
name = "",
type = "",
shape = "rectangle",
x = 1184,
y = 0,
width = 416,
height = 16,
rotation = 0,
visible = true,
properties = {}
},
{
id = 11,
name = "",
type = "",
shape = "rectangle",
x = 1584,
y = 0,
width = 16,
height = 960,
rotation = 0,
visible = true,
properties = {}
},
{
id = 12,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 944,
width = 1600,
height = 16,
rotation = 0,
visible = true,
properties = {}
},
{
id = 13,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 0,
width = 16,
height = 960,
rotation = 0,
visible = true,
properties = {}
}
}
}
}
}
+61
View File
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="25" height="15" tilewidth="64" tileheight="64" infinite="0" nextlayerid="4" nextobjectid="16">
<editorsettings>
<export target="map2.lua" format="lua"/>
</editorsettings>
<tileset firstgid="1" name="floor" tilewidth="64" tileheight="64" tilecount="54" columns="9">
<image source="../assets/tileset.png" width="576" height="384"/>
</tileset>
<layer id="1" name="floor" width="25" height="15">
<data encoding="csv">
1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21
</data>
</layer>
<layer id="2" name="inner walls" width="25" height="15">
<data encoding="csv">
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,28,29,30,0,0,0,0,0,0,0,0,0,0,0,
0,0,28,29,29,29,29,29,30,0,0,37,38,39,0,0,0,0,0,0,0,0,0,0,0,
0,0,37,38,38,38,38,38,39,0,0,46,47,48,0,0,0,0,0,0,0,0,0,0,0,
0,0,46,47,38,38,38,47,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,37,38,39,0,0,0,0,28,29,30,0,0,0,0,28,29,30,0,0,0,0,
0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,
0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,
0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,37,38,39,0,0,0,0,
0,0,0,0,46,47,48,0,0,0,0,46,47,48,0,0,0,0,37,38,39,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,29,38,38,38,29,30,0,0,
0,0,0,0,0,0,0,0,0,0,0,28,29,30,0,0,37,38,38,38,38,38,39,0,0,
0,0,0,0,0,0,0,0,0,0,0,37,38,39,0,0,46,47,47,47,47,47,48,0,0,
0,0,0,0,0,0,0,0,0,0,0,46,47,48,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
</data>
</layer>
<objectgroup id="3" name="Walls" visible="0">
<object id="1" x="128" y="128" width="448" height="192"/>
<object id="2" x="256" y="320" width="192" height="320"/>
<object id="3" x="704" y="80" width="192" height="176"/>
<object id="4" x="704" y="320" width="192" height="320"/>
<object id="5" x="704" y="704" width="192" height="192"/>
<object id="6" x="1024" y="640" width="448" height="192"/>
<object id="7" x="1152" y="320" width="192" height="320"/>
<object id="9" x="0" y="0" width="1184" height="16"/>
<object id="10" x="1184" y="0" width="416" height="16"/>
<object id="11" x="1584" y="0" width="16" height="960"/>
<object id="12" x="0" y="944" width="1600" height="16"/>
<object id="13" x="0" y="0" width="16" height="960"/>
</objectgroup>
</map>
+368
View File
@@ -0,0 +1,368 @@
return {
version = "1.10",
luaversion = "5.1",
tiledversion = "1.11.0",
class = "",
orientation = "orthogonal",
renderorder = "right-down",
width = 25,
height = 15,
tilewidth = 64,
tileheight = 64,
nextlayerid = 4,
nextobjectid = 23,
properties = {},
tilesets = {
{
name = "tileset",
firstgid = 1,
class = "",
tilewidth = 64,
tileheight = 64,
spacing = 0,
margin = 0,
columns = 9,
image = "../assets/tileset.png",
imagewidth = 576,
imageheight = 384,
objectalignment = "unspecified",
tilerendersize = "tile",
fillmode = "stretch",
tileoffset = {
x = 0,
y = 0
},
grid = {
orientation = "orthogonal",
width = 64,
height = 64
},
properties = {},
wangsets = {},
tilecount = 54,
tiles = {}
}
},
layers = {
{
type = "tilelayer",
x = 0,
y = 0,
width = 25,
height = 15,
id = 1,
name = "floor",
class = "",
visible = true,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
encoding = "lua",
data = {
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21
}
},
{
type = "tilelayer",
x = 0,
y = 0,
width = 25,
height = 15,
id = 2,
name = "inner walls",
class = "",
visible = true,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
encoding = "lua",
data = {
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, 33, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 31, 0, 0, 0,
0, 42, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 54, 40, 0, 0, 0,
0, 51, 52, 53, 0, 0, 0, 0, 0, 31, 31, 31, 0, 0, 0, 0, 0, 42, 43, 44, 54, 11, 0, 0, 0,
0, 0, 0, 0, 0, 0, 11, 11, 11, 40, 40, 40, 0, 0, 0, 0, 0, 51, 52, 53, 31, 11, 0, 0, 0,
0, 0, 0, 0, 0, 0, 32, 32, 32, 33, 34, 35, 31, 31, 0, 0, 0, 54, 54, 31, 40, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 41, 41, 41, 42, 43, 44, 40, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52, 53, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 33, 34, 34, 34, 35, 0, 0, 0, 0, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 42, 43, 43, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0,
0, 0, 0, 42, 43, 43, 43, 44, 0, 0, 0, 0, 0, 0, 0, 33, 34, 34, 34, 34, 35, 0, 0, 0, 0,
0, 0, 0, 51, 52, 52, 52, 53, 0, 0, 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 44, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52, 52, 52, 52, 53, 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
}
},
{
type = "objectgroup",
draworder = "topdown",
id = 3,
name = "Walls",
class = "",
visible = false,
opacity = 1,
offsetx = 0,
offsety = 0,
parallaxx = 1,
parallaxy = 1,
properties = {},
objects = {
{
id = 1,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 0,
width = 1600,
height = 16,
rotation = 0,
visible = true,
properties = {}
},
{
id = 2,
name = "",
type = "",
shape = "rectangle",
x = 1584,
y = 0,
width = 16,
height = 960,
rotation = 0,
visible = true,
properties = {}
},
{
id = 3,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 944,
width = 1600,
height = 16,
rotation = 0,
visible = true,
properties = {}
},
{
id = 4,
name = "",
type = "",
shape = "rectangle",
x = 0,
y = 0,
width = 16,
height = 960,
rotation = 0,
visible = true,
properties = {}
},
{
id = 5,
name = "",
type = "",
shape = "rectangle",
x = 112,
y = 64,
width = 96,
height = 192,
rotation = 0,
visible = true,
properties = {}
},
{
id = 6,
name = "",
type = "",
shape = "rectangle",
x = 400,
y = 368,
width = 160,
height = 64,
rotation = 0,
visible = true,
properties = {}
},
{
id = 7,
name = "",
type = "",
shape = "rectangle",
x = 576,
y = 208,
width = 192,
height = 96,
rotation = 0,
visible = true,
properties = {}
},
{
id = 8,
name = "",
type = "",
shape = "rectangle",
x = 608,
y = 336,
width = 128,
height = 160,
rotation = 0,
visible = true,
properties = {}
},
{
id = 10,
name = "",
type = "",
shape = "rectangle",
x = 768,
y = 336,
width = 128,
height = 96,
rotation = 0,
visible = true,
properties = {}
},
{
id = 11,
name = "",
type = "",
shape = "rectangle",
x = 768,
y = 496,
width = 128,
height = 64,
rotation = 0,
visible = true,
properties = {}
},
{
id = 13,
name = "",
type = "",
shape = "rectangle",
x = 240,
y = 528,
width = 224,
height = 224,
rotation = 0,
visible = true,
properties = {}
},
{
id = 14,
name = "",
type = "",
shape = "rectangle",
x = 1008,
y = 656,
width = 272,
height = 144,
rotation = 0,
visible = true,
properties = {}
},
{
id = 15,
name = "",
type = "",
shape = "rectangle",
x = 1168,
y = 592,
width = 160,
height = 32,
rotation = 0,
visible = true,
properties = {}
},
{
id = 16,
name = "",
type = "",
shape = "rectangle",
x = 1120,
y = 144,
width = 128,
height = 160,
rotation = 0,
visible = true,
properties = {}
},
{
id = 17,
name = "",
type = "",
shape = "rectangle",
x = 1104,
y = 336,
width = 96,
height = 32,
rotation = 0,
visible = true,
properties = {}
},
{
id = 19,
name = "",
type = "",
shape = "rectangle",
x = 1216,
y = 336,
width = 64,
height = 96,
rotation = 0,
visible = true,
properties = {}
},
{
id = 20,
name = "",
type = "",
shape = "rectangle",
x = 1280,
y = 80,
width = 64,
height = 288,
rotation = 0,
visible = true,
properties = {}
},
{
id = 22,
name = "",
type = "",
shape = "rectangle",
x = 1344,
y = 80,
width = 64,
height = 96,
rotation = 0,
visible = true,
properties = {}
}
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="25" height="15" tilewidth="64" tileheight="64" infinite="0" nextlayerid="4" nextobjectid="23">
<editorsettings>
<export target="map3.lua" format="lua"/>
</editorsettings>
<tileset firstgid="1" name="tileset" tilewidth="64" tileheight="64" tilecount="54" columns="9">
<image source="../assets/tileset.png" width="576" height="384"/>
</tileset>
<layer id="1" name="floor" width="25" height="15">
<data encoding="csv">
1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,
19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21
</data>
</layer>
<layer id="2" name="inner walls" width="25" height="15">
<data encoding="csv">
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,33,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,31,0,0,0,
0,42,43,44,0,0,0,0,0,0,0,0,0,0,0,0,0,33,34,35,54,40,0,0,0,
0,51,52,53,0,0,0,0,0,31,31,31,0,0,0,0,0,42,43,44,54,11,0,0,0,
0,0,0,0,0,0,11,11,11,40,40,40,0,0,0,0,0,51,52,53,31,11,0,0,0,
0,0,0,0,0,0,32,32,32,33,34,35,31,31,0,0,0,54,54,31,40,0,0,0,0,
0,0,0,0,0,0,41,41,41,42,43,44,40,40,0,0,0,0,0,40,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,51,52,53,32,32,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,33,34,34,34,35,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,42,43,43,43,44,0,0,0,0,0,0,0,0,0,0,54,54,54,0,0,0,0,
0,0,0,42,43,43,43,44,0,0,0,0,0,0,0,33,34,34,34,34,35,0,0,0,0,
0,0,0,51,52,52,52,53,0,0,0,0,0,0,0,42,43,43,43,43,44,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,52,52,52,52,53,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
</data>
</layer>
<objectgroup id="3" name="Walls" visible="0">
<object id="1" x="0" y="0" width="1600" height="16"/>
<object id="2" x="1584" y="0" width="16" height="960"/>
<object id="3" x="0" y="944" width="1600" height="16"/>
<object id="4" x="0" y="0" width="16" height="960"/>
<object id="5" x="112" y="64" width="96" height="192"/>
<object id="6" x="400" y="368" width="160" height="64"/>
<object id="7" x="576" y="208" width="192" height="96"/>
<object id="8" x="608" y="336" width="128" height="160"/>
<object id="10" x="768" y="336" width="128" height="96"/>
<object id="11" x="768" y="496" width="128" height="64"/>
<object id="13" x="240" y="528" width="224" height="224"/>
<object id="14" x="1008" y="656" width="272" height="144"/>
<object id="15" x="1168" y="592" width="160" height="32"/>
<object id="16" x="1120" y="144" width="128" height="160"/>
<object id="17" x="1104" y="336" width="96" height="32"/>
<object id="19" x="1216" y="336" width="64" height="96"/>
<object id="20" x="1280" y="80" width="64" height="288"/>
<object id="22" x="1344" y="80" width="64" height="96"/>
</objectgroup>
</map>
+4 -2
View File
@@ -1,4 +1,4 @@
function loadMap(lvl)
function LoadMap(lvl)
local mapfilelocation = "maps/"
local extention = ".lua"
local mapname = mapfilelocation .. "map" .. lvl .. extention
@@ -8,9 +8,11 @@ function loadMap(lvl)
if GameMap.layers["Walls"] then
for _, obj in ipairs(GameMap.layers["Walls"].objects) do
local wall = World:newRectangleCollider(obj.x, obj.y, obj.width, obj.height)
-- local wall =
-- World:newRectangleCollider(obj.x * _G.X_SCALE, obj.y * _G.Y_SCALE, obj.width * _G.X_SCALE, obj.height * _G.Y_SCALE)
wall:setType("static")
table.insert(Walls, wall)
Walls[#Walls]:setCollisionClass("Wall")
end
end
end
end
+94 -78
View File
@@ -1,21 +1,28 @@
Player = Object:extend()
cos = math.cos
sin = math.sin --optimisation
local cos = math.cos
local sin = math.sin --optimisation
local max = math.max --optimisation
-- Constructor for the Player class
function Player:new(p, x, y, health, image, speed, max)
function Player:new(p, x, y, health, image, speed)
self.p = p
self.image = love.graphics.newImage(image)
self.x = x
self.y = y
self.health = health
self.speed = speed
self.max = max
self.bulletSpeed = _G.DEFAULT_B_SPEED
self.width = self.image:getWidth()
self.height = self.image:getHeight()
--Power up flag
self.PUName = ""
self.PUTime = 0
self.PUOn = false
-- Collision Stuff
self.collider = World:newRectangleCollider(x, y, 64, 64)
--self.collider = World:newRectangleCollider(x, y, 50, 62)
self.collider = World:newCircleCollider(x, y, 24 * X_SCALE)
self.collider:setFixedRotation(true)
if self.p == 1 then
@@ -26,7 +33,9 @@ function Player:new(p, x, y, health, image, speed, max)
-- Rotation Stuff
self.rotation = math.rad(90)
self.rotSpeed = 2
self.rotSpeed = 3
--self.scaleX = 1 * _G.X_SCALE
--self.scaleY = 1 * _G.Y_SCALE
self.scaleX = 1
self.scaleY = 1
self.originX = self.width / 2
@@ -35,91 +44,98 @@ function Player:new(p, x, y, health, image, speed, max)
--Velocity
self.vx = 0
self.vy = 0
-- Bullets shot
self.shot = 0
end
-- Method to handle shooting
function Player:shoot(bulletSpeed)
local offsetX = cos(self.rotation) * self.width * 1.5
local offsetY = sin(self.rotation) * self.height * 1.5
local bulletX = self.x + offsetX
local bulletY = self.y + offsetY
local newBullet = Bullet(bulletX, bulletY, self.p, bulletSpeed, self.rotation)
return newBullet
if self.shot <= 10 then
self.shot = self.shot + 1
local offsetX = cos(self.rotation) * self.width * 1.5
local offsetY = sin(self.rotation) * self.height * 1.5
local bulletX = self.x + offsetX
local bulletY = self.y + offsetY
local newBullet = Bullet(bulletX, bulletY, self.p, bulletSpeed, self.rotation)
return newBullet
else
return nil
end
end
function handleKeys(dt)
function Player:handleKeys(up, down, left, right, dt)
self.vx, self.vy = 0, 0 --reset every frame
if love.keyboard.isDown(up) then
self.vx = cos(self.rotation) * (self.speed * dt)
self.vy = sin(self.rotation) * (self.speed * dt)
end
if love.keyboard.isDown(down) then
self.vx = cos(self.rotation) * (self.speed / 2 * dt) * -1
self.vy = sin(self.rotation) * (self.speed / 2 * dt) * -1
end
if love.keyboard.isDown(left) then
self.rotation = self.rotation - (self.rotSpeed * dt)
end
if love.keyboard.isDown(right) then
self.rotation = self.rotation + (self.rotSpeed * dt)
end
self.collider:setLinearVelocity(self.vx, self.vy)
end
function Player:updateCol()
if self.p == 1 then
self.x = self.collider:getX()
self.y = self.collider:getY()
elseif self.p == 2 then
self.x = self.collider:getX()
self.y = self.collider:getY()
end
end
function Player:getPowerUp(powerup)
self.PUName = powerup.name
self.PUTime = powerup.time
end
function Player:powerup()
self.PUOn = true
if self.PUName == "speed" then
--print("" .. self.PUName .. " for " .. self.PUTime)
self.speed = self.speed * 2.5
self.rotSpeed = self.rotSpeed * 1.5
end
end
-- Update method for the Player class
function Player:update(dt)
if _G.GAMESTATE == "GAME" then
self.vx = 0
self.vy = 0
local bulletSpeed = 20000
if self.PUOn then
self.PUTime = self.PUTime - dt
if self.p == 1 then
-- Handle player 1 controls
if love.keyboard.isDown("w") then
self.vx = cos(self.rotation) * (self.speed * dt)
self.vy = sin(self.rotation) * (self.speed * dt)
elseif love.keyboard.isDown("s") then
self.vx = cos(self.rotation) * (self.speed * dt) * -1
self.vy = sin(self.rotation) * (self.speed * dt) * -1
elseif love.keyboard.isDown("a") then
self.rotation = self.rotation - (self.rotSpeed * dt)
elseif love.keyboard.isDown("d") then
self.rotation = self.rotation + (self.rotSpeed * dt)
end
if max(0, self.PUTime) <= 0 then
-- Reset the player
self.PUName = "none"
self.PUTime = 0
self.PUOn = false
self.speed = _G.DEFAULT_P_SPEED
end
end
if EnableKeyPress1 == true and self.p == 1 then
if love.keyboard.isDown("space") then
local newBullet = self:shoot(self.bulletSpeed)
table.insert(Bullets1, newBullet)
KeyPressTime1 = KeyDelay1
EnableKeyPress1 = false
end
end
self.collider:setLinearVelocity(self.vx, self.vy)
-- Check for collision with walls
if self.collider:enter("Wall") then
print("Player 1 collided with wall")
end
if EnableKeyPress1 == true and GAMESTATE == "GAME" then
if love.keyboard.isDown("space") then
local newBullet = self:shoot(bulletSpeed)
table.insert(Bullets1, newBullet)
KeyPressTime1 = KeyDelay1
EnableKeyPress1 = false
end
end
self.x = self.collider:getX()
self.y = self.collider:getY()
elseif self.p == 2 then
-- Handle player 2 controls
if love.keyboard.isDown("up") then
self.vx = cos(self.rotation) * (self.speed * dt)
self.vy = sin(self.rotation) * (self.speed * dt)
elseif love.keyboard.isDown("down") then
self.vx = cos(self.rotation) * (self.speed * dt) * -1
self.vy = sin(self.rotation) * (self.speed * dt) * -1
elseif love.keyboard.isDown("left") then
self.rotation = self.rotation - (self.rotSpeed * dt)
elseif love.keyboard.isDown("right") then
self.rotation = self.rotation + (self.rotSpeed * dt)
end
self.collider:setLinearVelocity(self.vx, self.vy)
-- Check for collision with walls
if self.collider:enter("Wall") then
print("Player 2 collided with wall")
end
if EnableKeyPress2 == true then
if love.keyboard.isDown("return") then
local newBullet = self:shoot(bulletSpeed)
table.insert(Bullets2, newBullet)
KeyPressTime2 = KeyDelay2
EnableKeyPress2 = false
end
end
if EnableKeyPress2 == true and self.p == 2 then
if love.keyboard.isDown("return") then
local newBullet = self:shoot(self.bulletSpeed)
table.insert(Bullets2, newBullet)
KeyPressTime2 = KeyDelay2
EnableKeyPress2 = false
end
self.x = self.collider:getX()
self.y = self.collider:getY()
end
end
+70
View File
@@ -0,0 +1,70 @@
PowerUp = Object:extend()
-- PowerUp is the super class for all power-ups
-- found in the game
function PowerUp:new(name, x, y, image, time, lifetime)
self.name = name
self.x = x
self.y = y
self.image = love.graphics.newImage(image)
self.time = time
self.lifetime = lifetime
self.width = self.image:getWidth()
self.height = self.image:getHeight()
self.rotation = 1
self.scaleX = 1
self.scaleY = 1
self.originX = self.width / 2
self.originY = self.height / 2
-- Collider
self.collider = World:newRectangleCollider(x, y, 20, 20)
self.collider:setCollisionClass("PowerUp")
self.collider:setType("static")
self.collider:setPosition(self.x, self.y)
end
-- TODO: clean up colliosn on reset
-- make image draw
-- more stuff
-- see you later
function PowerUp:apply(player) end
function PowerUp:remove(player) end
function PowerUp:update(dt)
--check if the power up is past its lifetime
--spinnnnnn
self.rotation = self.rotation + 1.5 * dt
--grown and shrink
--[[
if self.scaleX >= 1.0 then
self.scaleX = self.scaleX - 0.2 * dt
elseif self.scaleX <= 1.8 then
self.scaleX = self.scaleX + 0.2 * dt
end
]]
self.x = self.collider:getX()
self.y = self.collider:getY()
end
function PowerUp:draw()
for _, _ in ipairs(PowerUps) do
love.graphics.draw(
self.image,
self.x,
self.y,
self.rotation,
self.scaleX,
self.scaleY,
self.originX,
self.originY
)
end
end
+81
View File
@@ -0,0 +1,81 @@
-- Functions to handle restarting
-- all objects
-- Used in map switching and restarting!
function ClearWalls(walls)
for i = #walls, 1, -1 do
walls[i]:destroy()
end
end
function ClearPowerUps(powerup)
for i, v in ipairs(powerup) do
v.collider:destroy()
end
end
function StopAllMusic()
-- TODO: maybe find a way
-- to find all 'streaming'
-- sounds and then stop them all!
musicBattle:stop()
musicMenu:stop()
musicPause:stop()
--musicStory:stop() -- Unused
end
function ClearPlayerCollision()
UserPlayer1.collider:destroy()
UserPlayer2.collider:destroy()
end
function ClearBullets(bullets)
for i, v in ipairs(bullets) do
v.collider:destroy()
end
end
local function setNewLevelFromRandom(count)
local level = math.random(1, count)
_G.CUR_LEVEL = level
end
local function getLevelCount()
local levelcount = 0
local suf = ".lua"
local files = love.filesystem.getDirectoryItems("maps/")
for _, file in ipairs(files) do
if string.find(file, suf) then
levelcount = levelcount + 1
--print(k .. ". " .. file) --outputs something like "1. main.lua"
end
end
return levelcount
end
function RestartGame()
setNewLevelFromRandom(getLevelCount())
--reset wins
_G.P1_WIN = false
_G.P2_WIN = false
-- Stop the music
--StopAllMusic()
-- Clear the players collision
ClearPlayerCollision()
-- Work through and delete all bullets
ClearBullets(Bullets1)
ClearBullets(Bullets2)
--Clear Walls
ClearWalls(Walls)
--ClearPowerUps
ClearPowerUps(PowerUps)
-- Done!
end
+6
View File
@@ -0,0 +1,6 @@
function truncate(number, decdigits)
number = number * (10 ^ decdigits)
number = math.floor(number)
number = number / (10 ^ decdigits)
return number
end