upload so it isnt lost now
This commit is contained in:
1
data/levels/2.json
Normal file
1
data/levels/2.json
Normal file
@@ -0,0 +1 @@
|
||||
[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[202,202,202,202,202,202,202,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,202,0,202,202,202,202,202,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,202,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,202,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,202,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,202,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,202,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,202,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,202,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,202,202,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],[157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,106,106,106,106,106,106,106,106,109,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,119,119,119,119,119,119,119,119,130,109,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,119,119,119,119,119,119,119,119,119,130,109,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,119,119,119,119,119,119,119,119,119,119,130,109,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,119,119,119,119,119,119,119,119,119,119,119,130,106,106,106,106,106,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,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,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]]
|
||||
1
data/levels/3.json
Normal file
1
data/levels/3.json
Normal file
File diff suppressed because one or more lines are too long
1
data/levels/ewae.json
Normal file
1
data/levels/ewae.json
Normal file
@@ -0,0 +1 @@
|
||||
[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,162,163,163,163,164,0,0,0,0,0,0,0,0,0],[154,155,0,0,0,0,144,145,145,146,176,176,176,144,145,145,146,0,0,0,0,152,153],[175,182,177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,169,177],[0,168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,165,0],[0,168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,165,0],[0,168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,165,0],[0,181,0,162,164,0,0,0,0,0,0,0,0,0,0,0,0,0,162,164,0,178,0],[0,0,0,175,177,0,0,0,0,0,0,0,0,0,0,0,0,0,175,177,0,0,0],[0,0,0,0,0,0,144,145,145,145,145,145,145,145,145,145,146,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
|
||||
1
data/levels/level1.json
Normal file
1
data/levels/level1.json
Normal file
File diff suppressed because one or more lines are too long
1
data/levels/tileset.json
Normal file
1
data/levels/tileset.json
Normal file
@@ -0,0 +1 @@
|
||||
[[107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,105],[120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118],[120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191,192,118],[122,167,182,1,2,3,4,5,6,7,8,9,10,11,12,13,208,205,121],[119,180,168,14,15,16,17,18,19,20,21,22,23,24,25,26,204,218,119],[119,180,168,27,28,29,30,31,32,33,34,35,36,37,38,39,204,218,119],[119,180,168,40,41,42,43,44,45,46,47,48,49,50,51,52,204,218,119],[119,180,168,53,54,55,56,57,58,59,60,61,62,63,64,65,204,218,119],[119,180,182,66,67,68,69,70,71,72,73,74,75,76,77,78,208,218,119],[119,180,168,79,80,81,82,83,84,85,86,87,88,89,90,91,204,218,119],[119,180,168,92,93,94,95,96,97,98,99,100,101,102,103,104,204,218,119],[119,180,168,105,106,107,108,109,110,111,112,113,114,115,116,117,204,218,119],[119,180,182,118,119,120,121,122,123,124,125,126,127,128,129,130,208,218,119],[119,180,168,131,132,133,134,135,136,137,138,139,140,141,142,143,204,218,119],[119,180,168,144,145,146,147,148,149,150,151,152,153,154,155,156,204,218,119],[119,180,168,157,158,159,160,161,162,163,164,165,166,167,168,169,204,218,119],[119,180,182,170,171,172,173,174,175,176,177,178,179,180,181,182,208,218,119],[119,180,168,183,184,185,186,187,188,189,190,191,192,193,194,195,204,218,119],[119,180,168,196,197,198,199,200,201,202,203,204,205,206,207,208,204,218,119],[119,180,168,209,210,211,212,213,214,215,216,217,218,219,220,221,204,218,119],[119,180,182,222,223,224,225,226,227,228,229,230,231,232,233,234,208,218,119],[119,180,168,235,236,237,238,239,240,241,242,243,244,245,246,247,204,218,119],[119,180,168,248,249,250,251,252,253,254,255,256,257,258,259,260,204,218,119],[119,180,168,261,262,263,264,265,266,267,268,269,270,271,272,273,204,218,119],[119,180,182,274,275,276,277,278,279,280,281,282,283,284,285,286,208,218,119],[119,180,168,287,288,289,290,291,292,293,294,295,296,297,298,299,204,218,119],[119,180,168,300,301,302,303,304,305,306,307,308,309,310,311,312,204,218,119],[119,120,181,0,0,0,0,0,0,0,0,0,0,0,0,0,217,118,119],[119,122,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,121,119],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119]]
|
||||
17
data/scripts.lua
Normal file
17
data/scripts.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
-- enums
|
||||
require "data/scripts/enums"
|
||||
|
||||
-- support functions
|
||||
require "data/scripts/math"
|
||||
require "data/scripts/in_out"
|
||||
json = require "data/scripts/json"
|
||||
-- classes
|
||||
require "data/scripts/entity"
|
||||
require "data/scripts/collision"
|
||||
require "data/scripts/level"
|
||||
-- data
|
||||
require "data/scripts/camera"
|
||||
require "data/scripts/objects"
|
||||
-- UI functions
|
||||
require "data/scripts/debug"
|
||||
require "data/scripts/pause"
|
||||
21
data/scripts/camera.lua
Normal file
21
data/scripts/camera.lua
Normal file
@@ -0,0 +1,21 @@
|
||||
Camera = {
|
||||
pos = {x = 0, y = 0},
|
||||
width = 0,
|
||||
height = 0
|
||||
}
|
||||
|
||||
function Camera:CenterAt(x,y,cx,cy)
|
||||
self.pos.x = x-self.width/2
|
||||
self.pos.y = y-self.height/2
|
||||
if not (cx == nil or cy == nil) then
|
||||
if self.pos.x < 0 then self.pos.x = 0 end
|
||||
if self.pos.x > cx then self.pos.x = cx end
|
||||
if self.pos.y < 0 then self.pos.y = 0 end
|
||||
if self.pos.y > cy then self.pos.y = cy end
|
||||
end
|
||||
end
|
||||
|
||||
function Camera:ScreenAt(x,y,width,height)
|
||||
self.pos.x = math.floor(x/width)*width
|
||||
self.pos.y = math.floor(y/height)*height
|
||||
end
|
||||
76
data/scripts/collision.lua
Normal file
76
data/scripts/collision.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
Collision = {}
|
||||
--[[
|
||||
Collision
|
||||
|
||||
[bool] isDisabled
|
||||
> if true used for collision
|
||||
|
||||
[bool] isActive
|
||||
> if true, this collision is active (on collision, duh)
|
||||
|
||||
[bool] isColliding
|
||||
> if true, this collision is colliding
|
||||
|
||||
[2d pos] from - x, y
|
||||
> top right corner of collision box
|
||||
|
||||
[2d pos] to - x, y
|
||||
> bottom left corner of collision box
|
||||
|
||||
[int] width
|
||||
> width of collision box
|
||||
|
||||
[int] height
|
||||
> height of collision box
|
||||
--]]
|
||||
|
||||
-- can also be called with only ox and oy, where they become the width and height instead
|
||||
function Collision:new(ox,oy,tx,ty)
|
||||
local o = {isColliding = false, isDisabled = false, isActive = false}
|
||||
|
||||
if tx ~= nil and ty ~= nil then
|
||||
o.from = {x = ox, y = oy}
|
||||
o.to = {x = tx, y = ty}
|
||||
|
||||
o.width = o.to.x - o.from.x
|
||||
o.height = o.to.y - o.from.y
|
||||
else
|
||||
o.width = ox
|
||||
o.height = oy
|
||||
|
||||
o.from = {x = 0, y = 0}
|
||||
o.to = {x = 0, y = 0}
|
||||
end
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function Collision:CenterAt(x, y)
|
||||
self.from.x = x-self.width/2
|
||||
self.from.y = y-self.height/2
|
||||
self.to.x = x+self.width/2
|
||||
self.to.y = y+self.height/2
|
||||
end
|
||||
|
||||
function Collision:PlaceAt(x, y)
|
||||
self.from.x = x or self.from.x
|
||||
self.from.y = y or self.from.y
|
||||
self.to.x = self.from.x + self.width
|
||||
self.to.y = self.from.x + self.height
|
||||
end
|
||||
|
||||
function Collision:Draw(color)
|
||||
if self.isColliding == true then
|
||||
love.graphics.setColor(0,1,0,0.5)
|
||||
elseif self.isActive == 1 then
|
||||
love.graphics.setColor(0,1,1,0.5)
|
||||
elseif color == 1 then
|
||||
love.graphics.setColor(1,0,0,0.5)
|
||||
elseif color == 2 then
|
||||
love.graphics.setColor(0,1,1,0.5)
|
||||
end
|
||||
love.graphics.rectangle("fill",self.from.x-Camera.pos.x, self.from.y-Camera.pos.y, self.width, self.height)
|
||||
end
|
||||
27
data/scripts/debug.lua
Normal file
27
data/scripts/debug.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
function DebugUI()
|
||||
love.graphics.print("time: "..fps_total..", fps: "..fps_draw..", frametime: "..math.floor(current_dt* 1000).."ms", 10*textScale, 0*textScale, 0, textScale)
|
||||
|
||||
love.graphics.setColor(1,1,1)
|
||||
-- lots of variables
|
||||
love.graphics.print("[main_player]",10*textScale,40*textScale, 0, textScale)
|
||||
love.graphics.print("position: {"..main_player.pos.x..", "..main_player.pos.y.."}",10*textScale,60*textScale, 0, textScale)
|
||||
love.graphics.print("velocity: {"..main_player.vel.x..", "..main_player.vel.y.."}",10*textScale,80*textScale, 0, textScale)
|
||||
love.graphics.print("scale: {"..main_player.scale.x..", "..main_player.scale.y.."}",10*textScale,100*textScale, 0, textScale)
|
||||
love.graphics.print("sprite: "..tostring(main_player.sprite)..", anim_speed: "..main_player.anim_speed,10*textScale,120*textScale, 0, textScale)
|
||||
love.graphics.print("booleans: \"isOnGround\": "..tostring(main_player.isOnGround),10*textScale,140*textScale, 0, textScale)
|
||||
|
||||
love.graphics.print("[Camera]",10*textScale,160*textScale, 0, textScale)
|
||||
love.graphics.print("position: {"..Camera.pos.x..", "..Camera.pos.y.."}",10*textScale,180*textScale, 0, textScale)
|
||||
love.graphics.print("size: {"..Camera.width..", "..Camera.height.."}",10*textScale,200*textScale, 0, textScale)
|
||||
|
||||
love.graphics.print(textScale,10*textScale,240*textScale, 0, textScale)
|
||||
love.graphics.print("Level: "..levelNum.." / "..#levelList.." \""..currLevel.."\"",10*textScale,260*textScale, 0, textScale)
|
||||
|
||||
-- player isOnGroundCheck
|
||||
love.graphics.setColor(1,0,0)
|
||||
love.graphics.points(-Camera.pos.x + main_player.pos.x, -Camera.pos.y + main_player.pos.y)
|
||||
end
|
||||
|
||||
function DebugColisions()
|
||||
objects.DrawCollisions()
|
||||
end
|
||||
205
data/scripts/entities/player.lua
Normal file
205
data/scripts/entities/player.lua
Normal file
@@ -0,0 +1,205 @@
|
||||
player = entity:newEntity(x,y)
|
||||
|
||||
function InitPlayer(id)
|
||||
player.health = 3
|
||||
player.coins = 0
|
||||
|
||||
-- physics
|
||||
player.vel = {
|
||||
x = 0,
|
||||
y = 0
|
||||
}
|
||||
-- constants
|
||||
player.acc = 90
|
||||
player.friction = 20
|
||||
player.gravity = 9.81
|
||||
player.climbHeight = 3
|
||||
player.jumpForce = 5
|
||||
player.maxSpeed = 600
|
||||
player.jumpMaxSpeed = 9.5
|
||||
player.zeroSpeed = 0.001
|
||||
-- bools
|
||||
player.isJumping = false
|
||||
player.isOnGround = false
|
||||
player.isOnLadder = false
|
||||
player.canJump = true
|
||||
player.canFall = true
|
||||
player.canFriction = true
|
||||
|
||||
-- sprite
|
||||
player.offset = {x = -8, y = -16}
|
||||
end
|
||||
|
||||
function player:DoInput()
|
||||
-- PLATFORMER INPUT
|
||||
if self.isOnGround then
|
||||
-- apply friction
|
||||
|
||||
-- horizontal input (slide~~)
|
||||
if love.keyboard.isDown('a',"left") then
|
||||
self.vel.x = self.vel.x - self.acc*current_dt
|
||||
end
|
||||
if love.keyboard.isDown('d',"right") then
|
||||
self.vel.x = self.vel.x + self.acc*current_dt
|
||||
end
|
||||
if self.canJump then
|
||||
-- vertical input (jump!)
|
||||
if love.keyboard.isDown("up", "w") and self.isJumping ~= true then
|
||||
self.vel.y = self.vel.y - self.jumpForce
|
||||
self.isOnGround = false
|
||||
self.isJumping = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- fall if down input on platforms
|
||||
if not isThereCollisionAt(
|
||||
self.pos.x,
|
||||
self.pos.y + self.vel.y
|
||||
) and not isThereLadderAt(
|
||||
self.pos.x,
|
||||
self.pos.y + self.vel.y
|
||||
) and isTherePlatformAt(
|
||||
self.pos.x,
|
||||
self.pos.y + self.vel.y
|
||||
) and love.keyboard.isDown("down", "s")
|
||||
then
|
||||
self.pos.y = self.pos.y + tileProperties.height/3
|
||||
self.isOnGround = false
|
||||
end
|
||||
end
|
||||
|
||||
function player:HandleAnimation()
|
||||
|
||||
-- flip sprite to look in the direction is moving
|
||||
if self.vel.x ~= 0 then self.flip.x = math.sign(self.vel.x) end
|
||||
|
||||
-- animation manager
|
||||
if self.isOnLadder then
|
||||
self:LoadAnimation(animation.nancy.jump)
|
||||
elseif not self.isOnGround and self.isJumping and self.vel.y > 1.25 then
|
||||
self:LoadAnimation(animation.nancy.fall)
|
||||
elseif not self.isOnGround and self.vel.y < 0 then
|
||||
self:LoadAnimation(animation.nancy.jump)
|
||||
elseif self.vel.x ~= 0 then
|
||||
self:LoadAnimation(animation.nancy.run)
|
||||
else
|
||||
self:LoadAnimation(animation.nancy.idle)
|
||||
end
|
||||
|
||||
-- special case: idle animation gets slower by time
|
||||
if self.anim_path == animation.nancy.idle.path then
|
||||
if self.anim_speed < 0.5 then self.anim_speed = self.anim_speed + 0.001 end
|
||||
end
|
||||
end
|
||||
|
||||
function player:DoPhysics()
|
||||
-- reset physics resolution
|
||||
self.canFall = true
|
||||
self.canJump = true
|
||||
self.canFriction = true
|
||||
-- reset flags
|
||||
self.isOnGround = false
|
||||
self.isOnLadder = false
|
||||
-- truncate to max & min values
|
||||
if math.abs(self.vel.x) > self.maxSpeed then
|
||||
self.vel.x = self.maxSpeed * math.sign(self.vel.x)
|
||||
end
|
||||
if math.abs(self.vel.y) > self.maxSpeed then
|
||||
self.vel.y = self.maxSpeed * math.sign(self.vel.y)
|
||||
end
|
||||
if math.abs(self.vel.x) < self.zeroSpeed then
|
||||
self.vel.x = 0
|
||||
end
|
||||
if math.abs(self.vel.y) < self.zeroSpeed then
|
||||
self.vel.y = 0
|
||||
end
|
||||
|
||||
-- if on air, say so!
|
||||
if self.vel.y > 5 then
|
||||
self.isJumping = true
|
||||
end
|
||||
|
||||
-- if its on ground, then say so.
|
||||
if self.vel.y > 0 then
|
||||
if isThereAnyCollisionAt(
|
||||
self.pos.x,
|
||||
self.pos.y + self.vel.y
|
||||
) then
|
||||
self.isOnGround = true
|
||||
self.isJumping = false
|
||||
end
|
||||
end
|
||||
-- horizontal collisions
|
||||
if isThereAnyCollisionAt(self.pos.x + self.vel.x, self.pos.y) then
|
||||
-- checks for ladders
|
||||
if isThereLadderAt(self.pos.x + self.vel.x, self.pos.y)
|
||||
and self.vel.x ~= 0
|
||||
and not isThereLadderAt(self.pos.x, self.pos.y)
|
||||
then
|
||||
self.vel.y = 0
|
||||
self.vel.x = 0
|
||||
|
||||
self.pos.y = self.pos.y - 4*game.scale * current_dt
|
||||
|
||||
self.canFall = false
|
||||
self.canJump = false
|
||||
self.canFriction = false
|
||||
|
||||
self.isOnLadder = true
|
||||
self.isOnGround = true
|
||||
end
|
||||
|
||||
-- checks for slopes
|
||||
for i = 1, self.climbHeight do
|
||||
if not isThereCollisionAt(self.pos.x + self.vel.x, self.pos.y - i * game.scale)
|
||||
and self.isOnGround then
|
||||
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
self.pos.y = self.pos.y - i * game.scale
|
||||
|
||||
self.canFriction = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- hey, you arent permanently stopped while collisioning, just lose a bit of force!
|
||||
if self.canFriction then
|
||||
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction/15, 1))
|
||||
end
|
||||
else
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
end
|
||||
|
||||
-- vertical collision
|
||||
if self.vel.y > 0
|
||||
and isThereAnyCollisionAt(self.pos.x, self.pos.y + self.vel.y) then
|
||||
self.isOnGround = true
|
||||
self.isJumping = false
|
||||
self.vel.y = 0
|
||||
else
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
end
|
||||
|
||||
-- drop.
|
||||
if self.canFall then
|
||||
self.vel.y = self.vel.y + 2*self.gravity * current_dt
|
||||
end
|
||||
|
||||
-- friction hard in ground, soft in air
|
||||
if self.isOnGround then
|
||||
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction, 1))
|
||||
else
|
||||
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction/20, 1))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function player:newPlayer(x,y)
|
||||
local o = entity:newEntity(x,y)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
return o
|
||||
end
|
||||
65
data/scripts/entity.lua
Normal file
65
data/scripts/entity.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
entity = {class = "entity", anim_subframe = 0, anim_frame = 0, anim_imgs = {}, offset = {x = 0, y = 0}, scale = {x = 1, y = 1}, flip = { x = 1, y = 1}}
|
||||
|
||||
function entity:newEntity(x,y)
|
||||
o = {}
|
||||
o.pos = {x = x, y = y}
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function entity:Move(target, speed) -- target = {tx int, ty int} / speed = int
|
||||
|
||||
end
|
||||
|
||||
function entity:Draw()
|
||||
if self.sprite ~= nil then
|
||||
love.graphics.draw(
|
||||
self.sprite,
|
||||
self.pos.x - Camera.pos.x + self.offset.x * game.scale * self.scale.x * self.flip.x,
|
||||
self.pos.y - Camera.pos.y + self.offset.y * game.scale * self.scale.y * self.flip.y,
|
||||
0,
|
||||
game.scale * self.scale.x * self.flip.x,
|
||||
game.scale * self.scale.y * self.flip.y
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function entity:Animate()
|
||||
if game_paused ~= true then
|
||||
-- try to animate
|
||||
self.anim_subframe = self.anim_subframe + current_dt
|
||||
|
||||
if self.anim_subframe >= self.anim_speed then
|
||||
self.anim_frame = self.anim_frame + 1
|
||||
self.anim_subframe = self.anim_subframe - self.anim_speed
|
||||
end
|
||||
|
||||
-- cycle
|
||||
if self.anim_frame >= self.anim_frames+1 then
|
||||
self.anim_frame = self.anim_frame - self.anim_frames
|
||||
end
|
||||
|
||||
-- change
|
||||
self.sprite = self.anim_imgs[self.anim_frame]
|
||||
end
|
||||
end
|
||||
|
||||
function entity:LoadAnimation(anim,frames,speed)
|
||||
if self.anim_path ~= anim and self.anim_path ~= anim.path then
|
||||
if frames ~= nil and speed ~= nil then
|
||||
self.anim_path = anim or nil
|
||||
self.anim_frames = frames or 4
|
||||
self.anim_speed = speed or frames
|
||||
else
|
||||
self.anim_path = anim.path
|
||||
self.anim_frames = anim.frames
|
||||
self.anim_speed = anim.speed
|
||||
end
|
||||
|
||||
self.anim_imgs = anim.imgs
|
||||
end
|
||||
end
|
||||
|
||||
require "data/scripts/entities/player"
|
||||
61
data/scripts/enums.lua
Normal file
61
data/scripts/enums.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
image = {
|
||||
background = love.graphics.newImage("assets/terrain/background.png"),
|
||||
cartridge = {
|
||||
nancy = love.graphics.newImage("assets/menu/nancy.png")
|
||||
}
|
||||
}
|
||||
-- animations
|
||||
animation = {
|
||||
nancy = {
|
||||
idle = {
|
||||
path = "assets/characters/nancy/idle",
|
||||
frames = 4,
|
||||
speed = 1/8,
|
||||
imgs = {}
|
||||
},
|
||||
run = {
|
||||
path = "assets/characters/nancy/run",
|
||||
frames = 6,
|
||||
speed = 1/8,
|
||||
imgs = {}
|
||||
},
|
||||
fall = {
|
||||
path = "assets/characters/nancy/fall",
|
||||
frames = 3,
|
||||
speed = 1/8,
|
||||
imgs = {}
|
||||
},
|
||||
jump = {
|
||||
path = "assets/characters/nancy/jump",
|
||||
frames = 3,
|
||||
speed = 1/8,
|
||||
imgs = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, object in pairs(animation) do
|
||||
for _, anim in pairs(object) do
|
||||
for i = 1, anim.frames do
|
||||
table.insert(anim.imgs,love.graphics.newImage(anim.path..tostring(i)..".png"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
levelProperties = {
|
||||
pos = {
|
||||
x = 0,
|
||||
y = 0
|
||||
},
|
||||
offset = {
|
||||
x = 0,
|
||||
y = 0
|
||||
}
|
||||
}
|
||||
|
||||
tileProperties = {
|
||||
width = 16,
|
||||
height = 16,
|
||||
scale = game.scale,
|
||||
tileset = love.graphics.newImage("assets/terrain/tileset.png")
|
||||
}
|
||||
14
data/scripts/in_out.lua
Normal file
14
data/scripts/in_out.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
function doOutput(table)
|
||||
local file = io.open("map.json", "w")
|
||||
io.output(file)
|
||||
io.write(json.encode(table))
|
||||
io.close(file)
|
||||
end
|
||||
|
||||
function getInput(filename)
|
||||
local file = io.open(filename, "r")
|
||||
io.input(file)
|
||||
local content = io.read()
|
||||
io.close(file)
|
||||
return content
|
||||
end
|
||||
388
data/scripts/json.lua
Normal file
388
data/scripts/json.lua
Normal file
@@ -0,0 +1,388 @@
|
||||
--
|
||||
-- json.lua
|
||||
--
|
||||
-- Copyright (c) 2020 rxi
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
-- 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 json = { _version = "0.1.2" }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local encode
|
||||
|
||||
local escape_char_map = {
|
||||
[ "\\" ] = "\\",
|
||||
[ "\"" ] = "\"",
|
||||
[ "\b" ] = "b",
|
||||
[ "\f" ] = "f",
|
||||
[ "\n" ] = "n",
|
||||
[ "\r" ] = "r",
|
||||
[ "\t" ] = "t",
|
||||
}
|
||||
|
||||
local escape_char_map_inv = { [ "/" ] = "/" }
|
||||
for k, v in pairs(escape_char_map) do
|
||||
escape_char_map_inv[v] = k
|
||||
end
|
||||
|
||||
|
||||
local function escape_char(c)
|
||||
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
|
||||
end
|
||||
|
||||
|
||||
local function encode_nil(val)
|
||||
return "null"
|
||||
end
|
||||
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if rawget(val, 1) ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= "number" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then
|
||||
error("invalid table: sparse array")
|
||||
end
|
||||
-- Encode
|
||||
for i, v in ipairs(val) do
|
||||
table.insert(res, encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
|
||||
local type_func_map = {
|
||||
[ "nil" ] = encode_nil,
|
||||
[ "table" ] = encode_table,
|
||||
[ "string" ] = encode_string,
|
||||
[ "number" ] = encode_number,
|
||||
[ "boolean" ] = tostring,
|
||||
}
|
||||
|
||||
|
||||
encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then
|
||||
return f(val, stack)
|
||||
end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.encode(val)
|
||||
return ( encode(val) )
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do
|
||||
res[ select(i, ...) ] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {
|
||||
[ "true" ] = true,
|
||||
[ "false" ] = false,
|
||||
[ "null" ] = nil,
|
||||
}
|
||||
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do
|
||||
if set[str:sub(i, i)] ~= negate then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error( string.format("%s at line %d col %d", msg, line_count, col_count) )
|
||||
end
|
||||
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = math.floor
|
||||
if n <= 0x7f then
|
||||
return string.char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return string.char(f(n / 64) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
|
||||
f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
end
|
||||
error( string.format("invalid unicode codepoint '%x'", n) )
|
||||
end
|
||||
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber( s:sub(1, 4), 16 )
|
||||
local n2 = tonumber( s:sub(7, 10), 16 )
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function parse_string(str, i)
|
||||
local res = ""
|
||||
local j = i + 1
|
||||
local k = j
|
||||
|
||||
while j <= #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
|
||||
elseif x == 92 then -- `\`: Escape
|
||||
res = res .. str:sub(k, j - 1)
|
||||
j = j + 1
|
||||
local c = str:sub(j, j)
|
||||
if c == "u" then
|
||||
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1)
|
||||
or str:match("^%x%x%x%x", j + 1)
|
||||
or decode_error(str, j - 1, "invalid unicode escape in string")
|
||||
res = res .. parse_unicode_escape(hex)
|
||||
j = j + #hex
|
||||
else
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
res = res .. escape_char_map_inv[c]
|
||||
end
|
||||
k = j + 1
|
||||
|
||||
elseif x == 34 then -- `"`: End of string
|
||||
res = res .. str:sub(k, j - 1)
|
||||
return res, j + 1
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then
|
||||
decode_error(str, i, "invalid number '" .. s .. "'")
|
||||
end
|
||||
return n, x
|
||||
end
|
||||
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local char_func_map = {
|
||||
[ '"' ] = parse_string,
|
||||
[ "0" ] = parse_number,
|
||||
[ "1" ] = parse_number,
|
||||
[ "2" ] = parse_number,
|
||||
[ "3" ] = parse_number,
|
||||
[ "4" ] = parse_number,
|
||||
[ "5" ] = parse_number,
|
||||
[ "6" ] = parse_number,
|
||||
[ "7" ] = parse_number,
|
||||
[ "8" ] = parse_number,
|
||||
[ "9" ] = parse_number,
|
||||
[ "-" ] = parse_number,
|
||||
[ "t" ] = parse_literal,
|
||||
[ "f" ] = parse_literal,
|
||||
[ "n" ] = parse_literal,
|
||||
[ "[" ] = parse_array,
|
||||
[ "{" ] = parse_object,
|
||||
}
|
||||
|
||||
|
||||
parse = function(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then
|
||||
return f(str, idx)
|
||||
end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.decode(str)
|
||||
if type(str) ~= "string" then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then
|
||||
decode_error(str, idx, "trailing garbage")
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
return json
|
||||
493
data/scripts/level.lua
Normal file
493
data/scripts/level.lua
Normal file
@@ -0,0 +1,493 @@
|
||||
function LoadTiles()
|
||||
LevelInfo = {}
|
||||
Tiles = dofile("Mothback/data/tiles.lua")
|
||||
--[[
|
||||
on level format:
|
||||
|
||||
id = tile identifier
|
||||
depth = order in the render
|
||||
force = rendering other tile instead of the one in this position
|
||||
overlay = render another tile id
|
||||
overlay_depth = foreground/background overlay depth
|
||||
type = collision type
|
||||
|
||||
]]
|
||||
LevelTiles = json.decode(getInput("Mothback/data/levels/"..currLevel..".json"))
|
||||
LevelInfo.Width = GetLevelWidth()
|
||||
LevelInfo.Height = #LevelTiles * tileProperties.height
|
||||
IndexLevelTiles()
|
||||
LoadTileObjects()
|
||||
end
|
||||
|
||||
function GetLevelWidth()
|
||||
local width = 0
|
||||
for i = 1, #LevelTiles do
|
||||
if width < #LevelTiles[i] then width = #LevelTiles[i] end
|
||||
end
|
||||
return width * tileProperties.width
|
||||
end
|
||||
|
||||
function IndexLevelTiles()
|
||||
TileIndex = {}
|
||||
|
||||
-- number of tiles in tileset!
|
||||
local width = tileProperties.tileset:getPixelWidth()/tileProperties.width
|
||||
local height = tileProperties.tileset:getPixelHeight()/tileProperties.height
|
||||
for i = 0, height do
|
||||
for j = 0, width do
|
||||
TileIndex[i*width+j+1] = love.graphics.newQuad(
|
||||
j*tileProperties.width,
|
||||
i*tileProperties.height,
|
||||
tileProperties.width,
|
||||
tileProperties.height,
|
||||
tileProperties.tileset:getDimensions()
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for _, properties in pairs(Tiles) do
|
||||
if properties.animation ~= nil then
|
||||
properties.tileset = love.graphics.newImage("assets/terrain/"..properties.animation..".png")
|
||||
properties.imgs = {}
|
||||
properties.current_image = 1
|
||||
properties.current_subimage = 1
|
||||
|
||||
local tileset = properties.tileset
|
||||
local width = tileset:getPixelWidth()/tileProperties.width
|
||||
local height = tileset:getPixelHeight()/tileProperties.height
|
||||
local image_count = 0
|
||||
|
||||
for i = 0, height-1 do
|
||||
for j = 0, width-1 do
|
||||
local quad =
|
||||
love.graphics.newQuad(
|
||||
j*tileProperties.width,
|
||||
i*tileProperties.height,
|
||||
tileProperties.width,
|
||||
tileProperties.height,
|
||||
tileset:getDimensions()
|
||||
)
|
||||
image_count = image_count + 1
|
||||
|
||||
table.insert(properties.imgs,quad)
|
||||
|
||||
end
|
||||
end
|
||||
properties.image_count = image_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TilesDisplayFront()
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if LevelTiles[i][j] ~= 0 then
|
||||
|
||||
local depth = getTileDepth(LevelTiles[i][j])
|
||||
DrawTile(
|
||||
LevelTiles[i][j],
|
||||
tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x,
|
||||
tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y,
|
||||
"foreground"
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TilesDisplayBack()
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if LevelTiles[i][j] ~= 0 then
|
||||
|
||||
local depth = getTileDepth(LevelTiles[i][j])
|
||||
DrawTile(
|
||||
LevelTiles[i][j],
|
||||
tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x,
|
||||
tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y,
|
||||
"background"
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function getTileType(tile_id)
|
||||
for _, properties in ipairs(Tiles) do
|
||||
if properties.id == tile_id then
|
||||
return properties.type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function getTileDepth(tile_id)
|
||||
for _, properties in ipairs(Tiles) do
|
||||
if properties.id == tile_id then
|
||||
return properties.depth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GridDisplay()
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x,
|
||||
tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y,
|
||||
tileProperties.scale * tileProperties.width,
|
||||
tileProperties.scale * tileProperties.height
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LoadTileObjects()
|
||||
objects.collisions = {}
|
||||
objects.platforms = {}
|
||||
objects.ladders = {}
|
||||
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if LevelTiles[i][j] ~= 0 then
|
||||
|
||||
local type = getTileType(LevelTiles[i][j])
|
||||
|
||||
local base_x = tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.height)
|
||||
local base_y = tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height)
|
||||
|
||||
if type == "whole" then
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "half" then
|
||||
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "platform" then
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
)
|
||||
table.insert(objects.platforms,plat)
|
||||
|
||||
elseif type == "ramp2_bot_left_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * 2 * tileProperties.scale,
|
||||
base_y + k * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
-- fill lower half
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "ramp2_bot_left_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * 2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
|
||||
elseif type == "ramp2_top_left_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
-- fill higher half
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "ramp2_top_left_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
|
||||
elseif type == "ramp2_bot_right_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
-- fill lower half
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "ramp2_bot_right_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
|
||||
elseif type == "ramp2_top_right_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
|
||||
elseif type == "ramp2_top_right_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
-- fill higher half
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,col)
|
||||
|
||||
elseif type == "ramp1_bot_left" then
|
||||
|
||||
for k = 1, 16 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * tileProperties.scale,
|
||||
base_y + k * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.collisions,slope)
|
||||
|
||||
end
|
||||
|
||||
elseif type == "ladder_right" then
|
||||
|
||||
local ladder = Collision:new(
|
||||
base_x + (tileProperties.width-4)* tileProperties.scale,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.ladders,ladder)
|
||||
|
||||
elseif type == "ladder_platform_right" then
|
||||
|
||||
local ladder = Collision:new(
|
||||
base_x + (tileProperties.width-4)* tileProperties.scale,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.ladders,ladder)
|
||||
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
)
|
||||
table.insert(objects.platforms,plat)
|
||||
|
||||
elseif type == "ladder_left" then
|
||||
|
||||
|
||||
local ladder = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.scale * 4,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.ladders,ladder)
|
||||
|
||||
elseif type == "ladder_platform_left" then
|
||||
|
||||
|
||||
local ladder = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.scale * 4,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
)
|
||||
table.insert(objects.ladders,ladder)
|
||||
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
)
|
||||
table.insert(objects.platforms,plat)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AnimateTiles()
|
||||
for _, properties in pairs(Tiles) do
|
||||
if properties.animation ~= nil then
|
||||
-- calculate subimage
|
||||
properties.current_subimage = properties.current_subimage + current_dt
|
||||
-- cycle image
|
||||
if properties.current_subimage >= properties.delay then
|
||||
properties.current_subimage = properties.current_subimage - properties.delay
|
||||
properties.current_image = properties.current_image + 1
|
||||
end
|
||||
|
||||
if properties.current_image > properties.image_count then
|
||||
properties.current_image = properties.current_image - properties.image_count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DrawTile(tile_id,x,y,depth)
|
||||
for _, properties in pairs(Tiles) do
|
||||
if tile_id == properties.id then
|
||||
if properties.animation ~= nil then
|
||||
if properties.imgs[properties.current_image] ~= nil
|
||||
and properties.depth == depth
|
||||
then love.graphics.draw(
|
||||
properties.tileset,
|
||||
properties.imgs[properties.current_image],
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
) end
|
||||
elseif properties.depth == depth then
|
||||
if properties.force ~= nil then
|
||||
love.graphics.draw(
|
||||
tileProperties.tileset,
|
||||
TileIndex[properties.force],
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
)
|
||||
else
|
||||
love.graphics.draw(
|
||||
tileProperties.tileset,
|
||||
TileIndex[properties.id],
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if properties.overlay ~= nil then
|
||||
if properties.overlay_depth == depth or properties.overlay_depth == nil and properties.depth == depth then
|
||||
if properties.overlay_animated then
|
||||
for _, overlay_properties in pairs(Tiles) do
|
||||
if overlay_properties.id == properties.overlay then
|
||||
love.graphics.draw(
|
||||
overlay_properties.tileset,
|
||||
overlay_properties.imgs[overlay_properties.current_image],
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
love.graphics.draw(
|
||||
tileProperties.tileset,
|
||||
TileIndex[properties.overlay],
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
9
data/scripts/math.lua
Normal file
9
data/scripts/math.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
function math.sign(x)
|
||||
if x<0 then
|
||||
return -1
|
||||
elseif x>0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
106
data/scripts/objects.lua
Normal file
106
data/scripts/objects.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
objects = {
|
||||
entities = {},
|
||||
|
||||
collisions = {},
|
||||
platforms = {},
|
||||
ladders = {}
|
||||
}
|
||||
|
||||
|
||||
-- level functions
|
||||
function objects.DrawCollisions()
|
||||
for _, col in pairs(objects.collisions) do
|
||||
col:Draw(1)
|
||||
end
|
||||
|
||||
for _, plat in pairs(objects.platforms) do
|
||||
if plat.disable == true then plat:Draw(2) end
|
||||
if plat.disable == false then plat:Draw(1) end
|
||||
end
|
||||
|
||||
for _, ladder in pairs(objects.ladders) do
|
||||
ladder:Draw(2)
|
||||
end
|
||||
end
|
||||
|
||||
-- returns true if theres a collision at that point. also marks collisioned tile as collision true
|
||||
function isThereCollisionAt(x,y)
|
||||
local result = false
|
||||
for _, col in pairs(objects.collisions) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function isTherePlatformAt(x,y)
|
||||
local result = false
|
||||
for _, col in pairs(objects.platforms) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y and col.disable ~= true then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function isThereLadderAt(x,y)
|
||||
local result = false
|
||||
for _, col in pairs(objects.ladders) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y and col.disable ~= true then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function isThereAnyCollisionAt(x,y)
|
||||
local result = false
|
||||
if not result then
|
||||
for _, col in pairs(objects.collisions) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not result then
|
||||
for _, col in pairs(objects.ladders) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y and col.disable ~= true then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not result then
|
||||
for _, col in pairs(objects.platforms) do
|
||||
if x >= col.from.x and x <= col.to.x and y >= col.from.y and y <= col.to.y and col.disable ~= true then
|
||||
result = true
|
||||
col.collision = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
-- flags
|
||||
function SetCollisionFlags(player)
|
||||
for _, col in pairs(objects.collisions) do
|
||||
col.collision = false
|
||||
end
|
||||
|
||||
for _, plat in pairs(objects.platforms) do
|
||||
plat.collision = false
|
||||
if player.pos.y < plat.from.y then
|
||||
plat.disable = false
|
||||
else
|
||||
plat.disable = true
|
||||
end
|
||||
end
|
||||
|
||||
for _, ladder in pairs(objects.ladders) do
|
||||
ladder.collision = false
|
||||
end
|
||||
end
|
||||
60
data/scripts/pause.lua
Normal file
60
data/scripts/pause.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
function PauseUI()
|
||||
--Parameters
|
||||
local pauseWidth = 640
|
||||
local pauseHeight = 480
|
||||
local pauseX = (game.width/2)-(pauseWidth/2)
|
||||
local pauseY = (game.height/2)-(pauseHeight/2)
|
||||
local mouse_x, mouse_y = love.mouse.getPosition()
|
||||
|
||||
--Base items
|
||||
love.graphics.setColor(0,0,0,0.3)
|
||||
love.graphics.rectangle("fill", 0, 0, game.width, game.height)
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
love.graphics.rectangle("fill", pauseX, pauseY, pauseWidth, pauseHeight)
|
||||
--Close buttom
|
||||
love.graphics.setColor(1,0,0,1)
|
||||
love.graphics.rectangle("fill", pauseX+pauseWidth-40, pauseY+10, 30, 30)
|
||||
if love.mouse.isDown(1) then
|
||||
if mouse_x >= pauseX+pauseWidth-40
|
||||
and mouse_y >= pauseY+10
|
||||
and mouse_x <= pauseX+pauseWidth-10
|
||||
and mouse_y <= pauseY+40 then
|
||||
do_pause = false
|
||||
end
|
||||
end
|
||||
if pausepage == 1 then
|
||||
--Game list button
|
||||
love.graphics.setColor(0.5,0.5,0.5,1)
|
||||
love.graphics.rectangle("fill", pauseX+(pauseWidth/2)-150, pauseY+100, 300, 40)
|
||||
love.graphics.setColor(0,0.5,0.5,1)
|
||||
love.graphics.printf("GAMES", pauseX+(pauseWidth/2), pauseY+100, 150, "left",0,3)
|
||||
if love.mouse.isDown(1) then
|
||||
if mouse_x >= pauseX+(pauseWidth/2)-150
|
||||
and mouse_y >= pauseY+100
|
||||
and mouse_x <= pauseX+(pauseWidth/2)+150
|
||||
and mouse_y <= pauseY+140 then
|
||||
pausepage = 2
|
||||
end
|
||||
end
|
||||
elseif pausepage == 2 then
|
||||
--Back button
|
||||
love.graphics.setColor(0.5,0.5,0.5,1)
|
||||
love.graphics.rectangle("fill", pauseX+10, pauseY+10, 30, 30)
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.printf("<", pauseX+10, pauseY+10, 30, "left", 0, 2)
|
||||
if love.mouse.isDown(1) then
|
||||
if mouse_x >= pauseX+10
|
||||
and mouse_y >= pauseY+10
|
||||
and mouse_x <= pauseX+40
|
||||
and mouse_y <= pauseY+40 then
|
||||
pausepage = 1
|
||||
end
|
||||
end
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
for i=1,2 do
|
||||
for j=1,3 do
|
||||
love.graphics.draw(image.cartridge.nancy, j*110, i*85, 0, 100/image.cartridge.nancy:getPixelWidth(), 80/image.cartridge.nancy:getPixelHeight())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
1180
data/tiles.lua
Normal file
1180
data/tiles.lua
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user