editor progress, generic keybinds, player coyote value, cursed book entity, level changes, camera adjustments
After Width: | Height: | Size: 118 B |
After Width: | Height: | Size: 98 B |
After Width: | Height: | Size: 117 B |
After Width: | Height: | Size: 111 B |
After Width: | Height: | Size: 124 B |
After Width: | Height: | Size: 119 B |
After Width: | Height: | Size: 140 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 140 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 143 B |
After Width: | Height: | Size: 137 B |
After Width: | Height: | Size: 143 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 99 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 123 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 134 B |
Before Width: | Height: | Size: 114 B |
Before Width: | Height: | Size: 92 B After Width: | Height: | Size: 92 B |
Before Width: | Height: | Size: 89 B After Width: | Height: | Size: 89 B |
Before Width: | Height: | Size: 88 B After Width: | Height: | Size: 88 B |
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
|
@ -20,6 +20,6 @@ function Camera:positionCenterAt(x,y,cx,cy)
|
|||
end
|
||||
|
||||
function Camera:positionAt(x,y)
|
||||
self.pos.x = math.floor(x/self.width)*self.width
|
||||
self.pos.y = math.floor(y/self.height)*self.height
|
||||
self.pos.x = math.floor((x/self.width)*self.width)
|
||||
self.pos.y = math.floor((y/self.height)*self.height)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
function DebugUI()
|
||||
|
||||
local mouse_x, mouse_y = love.mouse.getPosition()
|
||||
|
||||
for _, light in pairs(Lights) do
|
||||
love.graphics.print(light.pos.x,light.pos.x,light.pos.y)
|
||||
love.graphics.print(light.pos.y,light.pos.x,light.pos.y+20)
|
||||
|
@ -15,11 +17,15 @@ end
|
|||
love.graphics.print("velocity: {"..main_Player.vel.x..", "..main_Player.vel.y.."}",10*textScale,80*textScale, 0, textScale)
|
||||
love.graphics.print("scale: {"..main_Player.sprite_scale.x..", "..main_Player.sprite_scale.y.."}",10*textScale,100*textScale, 0, textScale)
|
||||
love.graphics.print("states: \"isOnGround\": "..tostring(main_Player.isOnGround),10*textScale,120*textScale, 0, textScale)
|
||||
love.graphics.print("\"coyoteValue\": "..tostring(main_Player.coyoteValue),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("[Cursor]",10*textScale,220*textScale, 0, textScale)
|
||||
love.graphics.print("position: {"..mouse_x+Camera.pos.x..", "..mouse_y+Camera.pos.y.."}",10*textScale,240*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)
|
||||
|
||||
|
@ -33,23 +39,9 @@ end
|
|||
|
||||
function DebugEntities()
|
||||
for _, particle in pairs(LoadedParticles) do
|
||||
-- draw center CYAN
|
||||
love.graphics.setColor(0,1,1)
|
||||
love.graphics.circle("fill", -Camera.pos.x + particle.pos.x, -Camera.pos.y + particle.pos.y, 1)
|
||||
|
||||
particle:Debug()
|
||||
end
|
||||
for _, enty in pairs(LoadedEntities) do
|
||||
-- draw center GREEN
|
||||
love.graphics.setColor(0,1,0)
|
||||
love.graphics.circle("fill", -Camera.pos.x + enty.pos.x, -Camera.pos.y + enty.pos.y, 1)
|
||||
-- draw collision box PURPLE
|
||||
love.graphics.setColor(1,0,1)
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
-Camera.pos.x + enty.pos.x + enty.boxCollision.from.x,
|
||||
-Camera.pos.y + enty.pos.y + enty.boxCollision.from.y,
|
||||
-Camera.pos.x + enty.pos.x + enty.boxCollision.to.x -(-Camera.pos.x + enty.pos.x + enty.boxCollision.from.x),
|
||||
-Camera.pos.y + enty.pos.y + enty.boxCollision.to.y -(-Camera.pos.y + enty.pos.y + enty.boxCollision.from.y)
|
||||
)
|
||||
enty:Debug()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,6 +46,7 @@ function EditorDraw()
|
|||
GridDisplay()
|
||||
GameworldDrawForeground()
|
||||
GameworldDrawEnd()
|
||||
EditorDoEdit()
|
||||
|
||||
DrawSelectingPaletteTile()
|
||||
if palette then
|
||||
|
@ -54,35 +55,39 @@ function EditorDraw()
|
|||
end
|
||||
|
||||
function EditorDoEdit()
|
||||
if love.mouse.isDown(1) then
|
||||
local vertical = 1+math.floor((mouse.pos.y+Camera.pos.y)/(tileProperties.scale*tileProperties.height))
|
||||
local horizontal = 1+math.floor((mouse.pos.x+Camera.pos.x)/(tileProperties.scale*tileProperties.width))
|
||||
local h, v = GetCanvasSize()
|
||||
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
local horizontal = 1 + math.floor(((mouse_x/game.scale) / tileProperties.width) + (Camera.pos.x / tileProperties.width))
|
||||
local vertical = 1 + math.floor(((mouse_y/game.scale) / tileProperties.height) + (Camera.pos.y / tileProperties.height))
|
||||
local expand_h = 0
|
||||
local expand_v = 0
|
||||
local LevelWidth = LevelGetTileWidth()
|
||||
local LevelHeight = LevelGetTileHeight()
|
||||
|
||||
if horizontal > h then
|
||||
expand_h = horizontal-h
|
||||
elseif horizontal <= 0 then
|
||||
expand_h = horizontal-1
|
||||
if horizontal > LevelWidth then
|
||||
expand_h = horizontal-LevelWidth
|
||||
elseif horizontal < 0 then
|
||||
expand_h = horizontal
|
||||
end
|
||||
|
||||
if vertical > v then
|
||||
expand_v = math.sign(vertical-v)
|
||||
elseif vertical <= 0 then
|
||||
expand_v = math.sign(vertical-1)
|
||||
if vertical > LevelHeight then
|
||||
expand_v = vertical-LevelHeight
|
||||
elseif vertical < 0 then
|
||||
expand_v = vertical
|
||||
end
|
||||
love.graphics.print("> " .. horizontal .. ", " .. vertical)
|
||||
love.graphics.print("> " .. LevelWidth .. "(" .. expand_h .. "), " .. LevelHeight .. "(".. expand_v .. ")", 0, 10)
|
||||
|
||||
if Level[vertical] ~= nil
|
||||
and Level[vertical][horizontal] ~= nil
|
||||
if Keybind:HasPressed(Keybind.generic.lclick) and not palette then
|
||||
if LevelTiles[vertical] ~= nil
|
||||
and LevelTiles[vertical][horizontal] ~= nil
|
||||
and love.keyboard.isDown("lshift") ~= true
|
||||
and love.keyboard.isDown("lctrl") ~= true
|
||||
and selecting_tile ~= nil
|
||||
then
|
||||
Level[vertical][horizontal] = tile_carrying
|
||||
elseif love.keyboard.isDown("lshift") and not expanded then
|
||||
expanded = true
|
||||
ExpandCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
InstanceTile(vertical,horizontal,selecting_tile)
|
||||
--[[
|
||||
elseif love.keyboard.isDown("lshift") then
|
||||
--ExpandCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
|
||||
if expand_h < 0 then
|
||||
Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width
|
||||
|
@ -91,24 +96,22 @@ function EditorDoEdit()
|
|||
Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height
|
||||
end
|
||||
|
||||
elseif love.keyboard.isDown("lctrl") and not expanded then
|
||||
expanded = true
|
||||
ReduceCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
elseif love.keyboard.isDown("lctrl") then
|
||||
--ReduceCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
|
||||
if expand_h < 0 then
|
||||
Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width
|
||||
end
|
||||
if expand_v < 0 then
|
||||
Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height
|
||||
end]]
|
||||
end
|
||||
end
|
||||
elseif love.mouse.isDown(1) ~= true then
|
||||
expanded = false
|
||||
LevelReloadTiles()
|
||||
end
|
||||
end
|
||||
|
||||
function DrawSelectingPaletteTile()
|
||||
if selecting_tile ~= nil then
|
||||
if selecting_tile ~= nil and selecting_tile ~= 0 then
|
||||
|
||||
local mouse_x = tileProperties.width * math.floor((love.mouse.getX()/game.scale) / tileProperties.width) - Camera.pos.x % tileProperties.width
|
||||
local mouse_y = tileProperties.height * math.floor((love.mouse.getY()/game.scale) / tileProperties.height) - Camera.pos.y % tileProperties.height
|
||||
|
@ -154,7 +157,7 @@ function EditorDoPalette()
|
|||
1,
|
||||
1
|
||||
)
|
||||
if love.mouse.isDown(1) then
|
||||
if Keybind:CheckDown(Keybind.generic.lclick) then
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
|
||||
|
@ -165,13 +168,15 @@ function EditorDoPalette()
|
|||
then
|
||||
selecting_tile = position_x + ((position_y-1) * width)
|
||||
|
||||
love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y)
|
||||
else
|
||||
--selecting_tile = nil
|
||||
love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y, 0, 20)
|
||||
end
|
||||
end
|
||||
|
||||
if selecting_tile ~= nil and i == selecting_tile then
|
||||
if Keybind:CheckDown(Keybind.generic.rclick) then
|
||||
selecting_tile = 0
|
||||
end
|
||||
|
||||
if selecting_tile ~= nil and selecting_tile ~= 0 and i == selecting_tile then
|
||||
love.graphics.setColor(1,0,1,1)
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
CursedBook = Entity:New(x,y)
|
||||
|
||||
function CursedBook:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
-- behaviour
|
||||
o.pos = {x = x, y = y}
|
||||
o.speed = 0.01
|
||||
o.range = 20
|
||||
o.target = {x = x, y = y}
|
||||
|
||||
o.status = 0
|
||||
-- 0 - sleep
|
||||
-- 1 - getting up
|
||||
-- 2 - flying
|
||||
-- 3 - attack windup
|
||||
-- 4 - attack
|
||||
o.spawn_range = 100
|
||||
o.attack_range = 50
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation.cursed_book.spawn)
|
||||
o.sprite_tint = {0.7,0.7,0.7}
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
|
||||
-- light
|
||||
o.light_range = 500
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.light_range,2,HEX2RGB("#fe00d1"))
|
||||
|
||||
table.insert(LoadedEntities,o)
|
||||
o.id = #LoadedEntities
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function CursedBook:Smart()
|
||||
self.target.x = main_Player.pos.x - main_Player.target_offset.x
|
||||
self.target.y = main_Player.pos.y - main_Player.target_offset.y
|
||||
local distance_x = self.target.x - self.pos.x
|
||||
local distance_y = self.target.y - self.pos.y
|
||||
local angle = GetAngleFromVector(distance_x,distance_y)
|
||||
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
|
||||
|
||||
if self.status == 0 then
|
||||
if distance < self.spawn_range then
|
||||
self.status = 1
|
||||
end
|
||||
elseif self.status == -1 then
|
||||
if distance < self.range then
|
||||
self.vel.x = 0
|
||||
self.vel.y = 0
|
||||
else
|
||||
self.vel.x = math.cos(angle)*self.speed*distance
|
||||
self.vel.y = math.sin(angle)*self.speed*distance
|
||||
end
|
||||
elseif self.status == 2 then
|
||||
if distance < self.attack_range then
|
||||
self.status = 3
|
||||
end
|
||||
elseif self.status == 4 then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function CursedBook:HandleAnimation()
|
||||
if self.status == 1 then
|
||||
if self.body.path == "assets/entities/cursed_book/spawn" then
|
||||
self.body.speed = 1/3
|
||||
local tint = 0.7 + 0.3 * (self.body.frame-1)/self.body.frames
|
||||
self.sprite_tint = {tint,tint,tint}
|
||||
if self.body.frame == self.body.frames then
|
||||
self.status = 2
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.flying)
|
||||
self.sprite_tint = {1,1,1}
|
||||
--self:getBoundingBox(self.body,2,2,-2,-2)
|
||||
self:centerOffset(self.body)
|
||||
end
|
||||
end
|
||||
elseif self.status == 3 then
|
||||
if self.body.path == "assets/entities/cursed_book/flying" then
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.attack_transition)
|
||||
self.body.speed = 1/3
|
||||
self:centerOffset(self.body)
|
||||
if self.body.frame == self.body.frames then
|
||||
self.status = 4
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.attack_loop)
|
||||
self:centerOffset(self.body)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
end
|
||||
|
||||
function CursedBook:DoPhysics()
|
||||
if self.isFlying then
|
||||
local random_x = math.random(-4, 4)/100
|
||||
local random_y = math.random(-4, 4)/100
|
||||
self.vel.x = self.vel.x + random_x
|
||||
self.vel.y = self.vel.y + random_y
|
||||
end
|
||||
-- move
|
||||
|
||||
self:CollisionMove()
|
||||
self:LightAdjust()
|
||||
end
|
||||
|
||||
function CursedBook:Debug()
|
||||
-- draw center GREEN
|
||||
love.graphics.setColor(0,1,0)
|
||||
love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.spawn_range)
|
||||
love.graphics.setColor(1,0,0)
|
||||
love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.attack_range)
|
||||
Entity.Debug(self)
|
||||
end
|
|
@ -3,6 +3,7 @@ Fairy = Entity:New(x,y)
|
|||
function Fairy:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
-- behaviour
|
||||
o.pos = {x = x, y = y}
|
||||
o.speed = 0.23
|
||||
o.range = 20
|
||||
|
@ -13,9 +14,13 @@ Fairy = Entity:New(x,y)
|
|||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
|
||||
-- light
|
||||
o.light_range = 80
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.light_range,nil,HEX2RGB("#fed100"))
|
||||
|
||||
o.lightRange = 0
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange)
|
||||
-- timer
|
||||
o.particle_timer = 0
|
||||
o.particle_time = 5
|
||||
|
||||
table.insert(LoadedEntities,o)
|
||||
o.id = #LoadedEntities
|
||||
|
@ -26,8 +31,6 @@ Fairy = Entity:New(x,y)
|
|||
end
|
||||
|
||||
function Fairy:Smart()
|
||||
self.light.pos.x = self.pos.x-self.target_offset.x
|
||||
self.light.pos.y = self.pos.y-self.target_offset.y
|
||||
|
||||
self.target.x = main_Player.pos.x - main_Player.target_offset.x
|
||||
self.target.y = main_Player.pos.y - main_Player.target_offset.y - 10
|
||||
|
@ -39,18 +42,27 @@ function Fairy:Smart()
|
|||
self.vel.x = 0
|
||||
self.vel.y = 0
|
||||
else
|
||||
self.vel.x = math.cos(angle)*self.speed*distance/(8*game.scale)
|
||||
self.vel.y = math.sin(angle)*self.speed*distance/(8*game.scale)
|
||||
self.vel.x = math.cos(angle)*self.speed*distance/8
|
||||
self.vel.y = math.sin(angle)*self.speed*distance/8
|
||||
|
||||
end
|
||||
self.particle_timer = self.particle_timer + 1
|
||||
if self.particle_timer >= self.particle_time then
|
||||
self.particle_timer = 0
|
||||
|
||||
local particle_data = {
|
||||
animation = animation.particle.fairy,
|
||||
direction = angle-math.rad(180),
|
||||
speed = self.speed*distance/(16*game.scale),
|
||||
light = 85
|
||||
animation = animation.particle.simple,
|
||||
sprite_tint = HEX2RGB("#fe00d1"),
|
||||
direction = angle-math.rad(180+math.random(60)-30),
|
||||
speed = 0.8*(distance/50),
|
||||
speed_increase = -0.01,
|
||||
}
|
||||
|
||||
Particle:New(self.pos.x,self.pos.y,particle_data)
|
||||
Particle:New(
|
||||
self.pos.x,
|
||||
self.pos.y,
|
||||
particle_data
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function Fairy:HandleAnimation()
|
||||
|
@ -60,11 +72,12 @@ function Fairy:HandleAnimation()
|
|||
end
|
||||
|
||||
function Fairy:DoPhysics()
|
||||
|
||||
local random_x = math.random(-4, 4)/100
|
||||
local random_y = math.random(-4, 4)/100
|
||||
self.vel.x = self.vel.x + random_x
|
||||
self.vel.y = self.vel.y + random_y
|
||||
-- move
|
||||
|
||||
self:CollisionMove()
|
||||
self:LightAdjust()
|
||||
end
|
||||
|
|
|
@ -26,17 +26,24 @@ Particle = Entity:New(x,y)
|
|||
y = o.speed * math.sin(o.direction)
|
||||
}
|
||||
|
||||
o.speed_increase = particle_data.speed_increase or 0
|
||||
|
||||
if particle_data.light ~= nil then
|
||||
o.lightRange = particle_data.light
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange)
|
||||
local flicker = particle_data.light_flicker or nil
|
||||
local color = particle_data.light_color or nil
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange,flicker,color)
|
||||
end
|
||||
|
||||
-- animations
|
||||
if particle_data.animation ~= nil then
|
||||
o.body = Animation:New(particle_data.animation)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
if not o.animation_active then
|
||||
o.body.speed = 0
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(LoadedParticles,o)
|
||||
o.id = #LoadedParticles
|
||||
|
@ -62,16 +69,32 @@ function Particle:Kill()
|
|||
end
|
||||
|
||||
function Particle:HandleAnimation()
|
||||
self.body:Animate()
|
||||
self.timer = self.timer + current_dt
|
||||
self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time
|
||||
if self.light ~= nil then
|
||||
self:LightAdjust()
|
||||
self.light.range = self.lightRange * self.sprite_alpha/2
|
||||
end
|
||||
if self.sprite_alpha < 0 then self:Kill() end
|
||||
if self.body ~= nil then
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
end
|
||||
end
|
||||
|
||||
function Particle:DoPhysics()
|
||||
self:Move()
|
||||
-- adjust speed
|
||||
if self.speed_increase ~= 0 then
|
||||
self.speed = self.speed + self.speed_increase
|
||||
self.vel.x = self.speed * math.cos(self.direction)
|
||||
self.vel.y = self.speed * math.sin(self.direction)
|
||||
end
|
||||
-- move
|
||||
self:CollisionMove()
|
||||
end
|
||||
|
||||
function Particle:Debug()
|
||||
-- draw center CYAN
|
||||
love.graphics.setColor(0,1,1)
|
||||
love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1)
|
||||
end
|
||||
|
|
|
@ -7,36 +7,39 @@
|
|||
Player.coins = 0
|
||||
|
||||
-- physics
|
||||
o.moveSpeed = 1.3
|
||||
o.zeroSpeed = 0.01
|
||||
o.move_x = 0
|
||||
o.moveSpeed = 1.3 -- gameworld pixels
|
||||
o.zeroSpeed = 0.01 -- gameworld pixels
|
||||
o.move_x = 0 -- gameworld pixels
|
||||
|
||||
o.airFriction = 0.01
|
||||
o.groundFriction = 0.3
|
||||
o.airFriction = 0.01 -- gameworld pixels
|
||||
o.groundFriction = 0.3 -- gameworld pixels
|
||||
|
||||
o.jumpImpulse = 3.5
|
||||
o.jumpImpulse = 3.5 -- gameworld pixels
|
||||
|
||||
o.dashCooldownTime = 0.1
|
||||
o.dashCooldownTimer = 0
|
||||
o.coyoteAmount = 5 -- int
|
||||
o.coyoteValue = 5 -- frames
|
||||
|
||||
o.dashTimer = 0
|
||||
o.dashTime = 0.15
|
||||
o.dashDistance = 40
|
||||
o.dashSpeed = o.dashDistance / (o.dashTime*60)
|
||||
o.dashCount = 1
|
||||
o.dashCooldownTime = 0.1 -- seconds
|
||||
o.dashCooldownTimer = 0 -- seconds
|
||||
|
||||
o.dashTimer = 0 -- seconds
|
||||
o.dashTime = 0.15 -- seconds
|
||||
o.dashDistance = 40 -- gameworld pixels
|
||||
o.dashSpeed = o.dashDistance / (o.dashTime*60) -- pixels
|
||||
o.dashCount = 1 -- int
|
||||
o.dashAmount = 0 -- int
|
||||
|
||||
o.boxCollision = {
|
||||
from = {x = -8, y = -16},
|
||||
to = {x = 8, y = 0}
|
||||
from = {x = -8, y = -16}, --gameworld pixels
|
||||
to = {x = 8, y = 0} -- gameworld pixels
|
||||
}
|
||||
|
||||
o.lightRange = 0--32
|
||||
o.lightRange = 344 -- screen pixels
|
||||
|
||||
-- status
|
||||
o.isDashing = false
|
||||
o.isJumping = false
|
||||
o.isOnGround = 0
|
||||
o.coyoteValue = 5
|
||||
o.isOnGround = true
|
||||
o.isOnLadder = false
|
||||
o.canJump = true
|
||||
o.canFall = true
|
||||
|
@ -48,7 +51,7 @@
|
|||
o.body = Animation:New(animation.nancy.idle)
|
||||
o.mask = Animation:New(animation.moth_mask.idle)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body, 3,-3,0,-1)
|
||||
o:getBoundingBox(o.body,0,3,-1,-3)
|
||||
|
||||
-- lights
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange)
|
||||
|
@ -85,12 +88,19 @@ function Player:Smart()
|
|||
self.vel.x = self.vel.x
|
||||
|
||||
if Keybind:CheckDown(Keybind.move.jump) then
|
||||
if self.isOnGround then
|
||||
if self.coyoteValue > 0 then
|
||||
self.vel.y = -self.jumpImpulse
|
||||
self.coyoteValue = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.isOnGround then
|
||||
self.coyoteValue = self.coyoteAmount
|
||||
elseif self.coyoteValue > 0 then
|
||||
self.coyoteValue = self.coyoteValue - 1
|
||||
end
|
||||
|
||||
self.dashCooldownTimer = math.max(0,self.dashCooldownTimer - current_dt)
|
||||
if Keybind:CheckDown(Keybind.move.dash) then
|
||||
if self.dashCooldownTimer == 0
|
||||
|
@ -118,14 +128,14 @@ function Player:Smart()
|
|||
end
|
||||
|
||||
function Player:DoPhysics()
|
||||
|
||||
-- reset state
|
||||
self.isOnGround = false
|
||||
|
||||
-- adjust timers
|
||||
self.dashTimer = self.dashTimer - current_dt
|
||||
|
||||
-- DASH STATE
|
||||
if self.dashTimer > 0 then
|
||||
|
||||
-- dash particle
|
||||
local particle_data = {
|
||||
animation = self.body,
|
||||
sprite_tint = HEX2RGB("#fed100"),
|
||||
|
@ -137,9 +147,11 @@ function Player:DoPhysics()
|
|||
}
|
||||
Particle:New(self.pos.x,self.pos.y,particle_data)
|
||||
self.dashCooldownTimer = self.dashCooldownTime
|
||||
-- dash movement
|
||||
self.vel.x = self.dashSpeed * math.cos(self.dashDirection)
|
||||
self.vel.y = self.dashSpeed * math.sin(self.dashDirection)
|
||||
else
|
||||
-- not in dash; fall normally
|
||||
self.dashTimer = 0
|
||||
self.vel.y = self.vel.y + gravity
|
||||
end
|
||||
|
@ -155,7 +167,7 @@ function Player:DoPhysics()
|
|||
else
|
||||
if self.vel.y > 0 then
|
||||
self.isOnGround = true
|
||||
self.dashCount = 1
|
||||
self.dashCount = self.dashAmount
|
||||
self.vel.y = 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,9 +39,20 @@ end
|
|||
function Entity:CollisionMove()
|
||||
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
else
|
||||
self.vel.x = 0
|
||||
end
|
||||
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
else
|
||||
self.vel.y = 0
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:LightAdjust()
|
||||
if self.light ~= nil then
|
||||
self.light.pos.x = self.pos.x
|
||||
self.light.pos.y = self.pos.y
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -80,7 +91,7 @@ function Entity:centerOffset(animation,x,y)
|
|||
self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y
|
||||
end
|
||||
|
||||
function Entity:getBoundingBox(animation,left,right,top,bottom)
|
||||
function Entity:getBoundingBox(animation,top,left,bottom,right)
|
||||
local left = left or 0
|
||||
local right = right or 0
|
||||
local top = top or 0
|
||||
|
@ -125,9 +136,24 @@ function Entity:isCollidingAtAll(x,y)
|
|||
return result
|
||||
end
|
||||
|
||||
function Entity:Debug()
|
||||
-- draw center GREEN
|
||||
love.graphics.setColor(0,1,0)
|
||||
love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1)
|
||||
-- draw collision box PURPLE
|
||||
love.graphics.setColor(1,0,1)
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
-Camera.pos.x + self.pos.x + self.boxCollision.from.x,
|
||||
-Camera.pos.y + self.pos.y + self.boxCollision.from.y,
|
||||
-Camera.pos.x + self.pos.x + self.boxCollision.to.x -(-Camera.pos.x + self.pos.x + self.boxCollision.from.x),
|
||||
-Camera.pos.y + self.pos.y + self.boxCollision.to.y -(-Camera.pos.y + self.pos.y + self.boxCollision.from.y)
|
||||
)
|
||||
end
|
||||
require "data/scripts/entities/kupo"
|
||||
require "data/scripts/entities/arrow"
|
||||
require "data/scripts/entities/decoration"
|
||||
require "data/scripts/entities/player"
|
||||
require "data/scripts/entities/fairy"
|
||||
require "data/scripts/entities/cursed_book"
|
||||
require "data/scripts/entities/particle"
|
||||
|
|
|
@ -1,16 +1,33 @@
|
|||
-- animationsç
|
||||
-- all these are linear animations, maybe in the future make proper animations?
|
||||
animation = {
|
||||
particle = {
|
||||
fairy = {
|
||||
path = "assets/entities/particle/fairy",
|
||||
frames = 4,
|
||||
speed = 1/4
|
||||
},
|
||||
player_dash = {
|
||||
path = "assets/entities/particle/player_dash",
|
||||
cursed_book = {
|
||||
attack_loop = {
|
||||
path = "assets/entities/cursed_book/attack_loop",
|
||||
frames = 1,
|
||||
speed = 0
|
||||
},
|
||||
attack_transition = {
|
||||
path = "assets/entities/cursed_book/attack_transition",
|
||||
frames = 5,
|
||||
speed = 1/16
|
||||
},
|
||||
flying = {
|
||||
path = "assets/entities/cursed_book/flying",
|
||||
frames = 11,
|
||||
speed = 1/16
|
||||
},
|
||||
spawn = {
|
||||
path = "assets/entities/cursed_book/spawn",
|
||||
frames = 5,
|
||||
speed = 0
|
||||
}
|
||||
},
|
||||
particle = {
|
||||
simple = {
|
||||
path = "assets/entities/particle/simple",
|
||||
frames = 4,
|
||||
speed = 1/4
|
||||
}
|
||||
},
|
||||
fairy = {
|
||||
|
|
|
@ -18,8 +18,8 @@ end
|
|||
function GameDraw()
|
||||
|
||||
GameworldDrawPrepare()
|
||||
GameworldDrawBackground()
|
||||
GameworldDrawParticles()
|
||||
GameworldDrawBackground()
|
||||
GameworldDrawEntities()
|
||||
GameworldDrawForeground()
|
||||
GameworldDrawEnd()
|
||||
|
|
|
@ -3,6 +3,7 @@ Keybind.move = {}
|
|||
Keybind.menu = {}
|
||||
Keybind.debug = {}
|
||||
Keybind.editor = {}
|
||||
Keybind.generic = {}
|
||||
|
||||
function Keybind:CheckDown(action)
|
||||
for _, keyname in pairs(action.keys) do
|
||||
|
@ -66,6 +67,10 @@ function Keybind:Default()
|
|||
Keybind.debug.editor = { keys = {"f4"}}
|
||||
-- Editor
|
||||
Keybind.editor.palette = { keys = {"tab"}}
|
||||
|
||||
-- Generic
|
||||
Keybind.generic.lclick = { keys = {1}}
|
||||
Keybind.generic.rclick = { keys = {2}}
|
||||
end
|
||||
|
||||
-- Set default values at start
|
||||
|
|
|
@ -1,39 +1,54 @@
|
|||
function LevelLoadTiles()
|
||||
|
||||
LevelData = dofile("Mothback/data/levels/"..currLevel..".lua")
|
||||
|
||||
-- tiles data
|
||||
TileData = dofile("Mothback/data/tileset/library.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 or, if multiple tiles {id, id, id,} or
|
||||
overlay = render another tile id or, if multiple tiles {id, id, id,}, choose at random
|
||||
overlay_depth = foreground/background overlay depth
|
||||
type = collision type
|
||||
]]
|
||||
|
||||
|
||||
-- Level data
|
||||
LevelData = dofile("Mothback/data/levels/"..currLevel..".lua")
|
||||
|
||||
-- tiles data
|
||||
TileData = dofile("Mothback/data/tileset/library.lua")
|
||||
|
||||
LevelTiles = LevelData.tiles
|
||||
LevelData.Width = LevelGetWidth()
|
||||
LevelData.Height = LevelGetHeight()
|
||||
LevelUpdateDimensions()
|
||||
LevelIndexTiles()
|
||||
TileCreateObjects()
|
||||
end
|
||||
|
||||
function LevelGetHeight()
|
||||
return #LevelTiles * tileProperties.height
|
||||
function LevelReloadTiles()
|
||||
LevelUpdateDimensions()
|
||||
TileCreateObjects()
|
||||
end
|
||||
|
||||
function LevelGetWidth()
|
||||
function LevelUpdateDimensions()
|
||||
LevelData.Width = LevelGetWidth()
|
||||
LevelData.Height = LevelGetHeight()
|
||||
end
|
||||
|
||||
function LevelGetTileHeight()
|
||||
return #LevelTiles
|
||||
end
|
||||
|
||||
function LevelGetTileWidth()
|
||||
local width = 0
|
||||
for i = 1, #LevelTiles do
|
||||
if width < #LevelTiles[i] then width = #LevelTiles[i] end
|
||||
end
|
||||
return width * tileProperties.width
|
||||
return width
|
||||
end
|
||||
|
||||
function LevelGetHeight()
|
||||
return LevelGetTileHeight() * tileProperties.height
|
||||
end
|
||||
|
||||
function LevelGetWidth()
|
||||
return LevelGetTileWidth() * tileProperties.width
|
||||
end
|
||||
|
||||
function LevelIndexTiles()
|
||||
|
@ -53,8 +68,17 @@ function LevelIndexTiles()
|
|||
)
|
||||
end
|
||||
end
|
||||
TileDataInitialize()
|
||||
|
||||
-- initialize tile data
|
||||
-- instance level tiles according to the Properties
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
InstanceTile(i,j,LevelTiles[i][j])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TileDataInitialize()
|
||||
for _, Properties in pairs(TileData) do
|
||||
if Properties.animation ~= nil then
|
||||
Properties.tileset = love.graphics.newImage("assets/terrain/"..Properties.animation..".png")
|
||||
|
@ -85,11 +109,9 @@ function LevelIndexTiles()
|
|||
Properties.image_count = image_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- instance level tiles according to the Properties
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
local id = LevelTiles[i][j]
|
||||
function InstanceTile(i,j,id)
|
||||
LevelTiles[i][j] = {}
|
||||
local tile = LevelTiles[i][j]
|
||||
tile.id = id
|
||||
|
@ -109,9 +131,6 @@ function LevelIndexTiles()
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TileGetType(tile)
|
||||
|
|
|
@ -5,7 +5,7 @@ function CreateDarkness()
|
|||
return love.graphics.newCanvas(game.width/game.scale, game.height/game.scale)
|
||||
end
|
||||
|
||||
function CreateLight(x,y,range,lum,flicker)
|
||||
function CreateLight(x,y,range,flicker,color,lum)
|
||||
local o = {}
|
||||
o.pos = {
|
||||
x = x,
|
||||
|
@ -13,11 +13,13 @@ function CreateLight(x,y,range,lum,flicker)
|
|||
}
|
||||
o.range = range
|
||||
o.lum = lum or 1
|
||||
o.color = color or {1,1,1}
|
||||
o.flicker_value = flicker or 2
|
||||
o.flicker = 0
|
||||
o.dim = 0
|
||||
o.flicker_speed = flicker_speed or 60/12
|
||||
o.flicker_time = 0
|
||||
|
||||
table.insert(Lights,o)
|
||||
o.id = #Lights
|
||||
return o
|
||||
|
@ -52,9 +54,9 @@ function DoLights()
|
|||
end
|
||||
end
|
||||
love.graphics.setBlendMode("replace")
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
for _, light in pairs(Lights) do
|
||||
if light.range ~= 0 then
|
||||
love.graphics.setColor(light.color[1],light.color[2],light.color[3],1)
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
(light.pos.x - Camera.pos.x) / game.scale,
|
||||
|
|
9
main.lua
|
@ -46,10 +46,11 @@ function love.load()
|
|||
|
||||
main_Player = Player:New(75,50)
|
||||
|
||||
Kupo:New(100,150)
|
||||
Kupo:New(300,150)
|
||||
Decoration:New(200,89,animation.decoration.candelabra,80)
|
||||
Fairy:New(200,88)
|
||||
--Kupo:New(100,150)
|
||||
--Kupo:New(300,150)
|
||||
--Decoration:New(200,89,animation.decoration.candelabra,80)
|
||||
--Fairy:New(200,88)
|
||||
--CursedBook:New(180,68)
|
||||
|
||||
gravity = 0.2
|
||||
end
|
||||
|
|