editor progress, generic keybinds, player coyote value, cursed book entity, level changes, camera adjustments

This commit is contained in:
lustlion 2022-01-29 08:49:45 +01:00
parent 90ed1f6460
commit a1bf842cef
41 changed files with 387 additions and 154 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

View File

Before

Width:  |  Height:  |  Size: 92 B

After

Width:  |  Height:  |  Size: 92 B

View File

Before

Width:  |  Height:  |  Size: 89 B

After

Width:  |  Height:  |  Size: 89 B

View File

Before

Width:  |  Height:  |  Size: 88 B

After

Width:  |  Height:  |  Size: 88 B

View File

Before

Width:  |  Height:  |  Size: 97 B

After

Width:  |  Height:  |  Size: 97 B

View File

@ -20,6 +20,6 @@ function Camera:positionCenterAt(x,y,cx,cy)
end end
function Camera:positionAt(x,y) function Camera:positionAt(x,y)
self.pos.x = math.floor(x/self.width)*self.width self.pos.x = math.floor((x/self.width)*self.width)
self.pos.y = math.floor(y/self.height)*self.height self.pos.y = math.floor((y/self.height)*self.height)
end end

View File

@ -1,5 +1,7 @@
function DebugUI() function DebugUI()
local mouse_x, mouse_y = love.mouse.getPosition()
for _, light in pairs(Lights) do for _, light in pairs(Lights) do
love.graphics.print(light.pos.x,light.pos.x,light.pos.y) 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) 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("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("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("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("[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("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("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(textScale,10*textScale,240*textScale, 0, textScale)
love.graphics.print("Level: "..levelNum.." / "..#levelList.." \""..currLevel.."\"",10*textScale,260*textScale, 0, textScale) love.graphics.print("Level: "..levelNum.." / "..#levelList.." \""..currLevel.."\"",10*textScale,260*textScale, 0, textScale)
@ -33,23 +39,9 @@ end
function DebugEntities() function DebugEntities()
for _, particle in pairs(LoadedParticles) do for _, particle in pairs(LoadedParticles) do
-- draw center CYAN particle:Debug()
love.graphics.setColor(0,1,1)
love.graphics.circle("fill", -Camera.pos.x + particle.pos.x, -Camera.pos.y + particle.pos.y, 1)
end end
for _, enty in pairs(LoadedEntities) do for _, enty in pairs(LoadedEntities) do
-- draw center GREEN enty:Debug()
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)
)
end end
end end

View File

@ -46,6 +46,7 @@ function EditorDraw()
GridDisplay() GridDisplay()
GameworldDrawForeground() GameworldDrawForeground()
GameworldDrawEnd() GameworldDrawEnd()
EditorDoEdit()
DrawSelectingPaletteTile() DrawSelectingPaletteTile()
if palette then if palette then
@ -54,35 +55,39 @@ function EditorDraw()
end end
function EditorDoEdit() function EditorDoEdit()
if love.mouse.isDown(1) then local mouse_x = love.mouse.getX()
local vertical = 1+math.floor((mouse.pos.y+Camera.pos.y)/(tileProperties.scale*tileProperties.height)) local mouse_y = love.mouse.getY()
local horizontal = 1+math.floor((mouse.pos.x+Camera.pos.x)/(tileProperties.scale*tileProperties.width)) local horizontal = 1 + math.floor(((mouse_x/game.scale) / tileProperties.width) + (Camera.pos.x / tileProperties.width))
local h, v = GetCanvasSize() 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()
local expand_h = 0 if horizontal > LevelWidth then
local expand_v = 0 expand_h = horizontal-LevelWidth
elseif horizontal < 0 then
expand_h = horizontal
end
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 horizontal > h then if Keybind:HasPressed(Keybind.generic.lclick) and not palette then
expand_h = horizontal-h if LevelTiles[vertical] ~= nil
elseif horizontal <= 0 then and LevelTiles[vertical][horizontal] ~= nil
expand_h = horizontal-1
end
if vertical > v then
expand_v = math.sign(vertical-v)
elseif vertical <= 0 then
expand_v = math.sign(vertical-1)
end
if Level[vertical] ~= nil
and Level[vertical][horizontal] ~= nil
and love.keyboard.isDown("lshift") ~= true and love.keyboard.isDown("lshift") ~= true
and love.keyboard.isDown("lctrl") ~= true and love.keyboard.isDown("lctrl") ~= true
and selecting_tile ~= nil
then then
Level[vertical][horizontal] = tile_carrying InstanceTile(vertical,horizontal,selecting_tile)
elseif love.keyboard.isDown("lshift") and not expanded then --[[
expanded = true elseif love.keyboard.isDown("lshift") then
ExpandCanvas(math.sign(expand_h),math.sign(expand_v)) --ExpandCanvas(math.sign(expand_h),math.sign(expand_v))
if expand_h < 0 then if expand_h < 0 then
Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width 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 Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height
end end
elseif love.keyboard.isDown("lctrl") and not expanded then elseif love.keyboard.isDown("lctrl") then
expanded = true --ReduceCanvas(math.sign(expand_h),math.sign(expand_v))
ReduceCanvas(math.sign(expand_h),math.sign(expand_v))
if expand_h < 0 then if expand_h < 0 then
Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width
end end
if expand_v < 0 then if expand_v < 0 then
Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height
end end]]
end end
elseif love.mouse.isDown(1) ~= true then LevelReloadTiles()
expanded = false
end end
end end
function DrawSelectingPaletteTile() 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_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 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,
1 1
) )
if love.mouse.isDown(1) then if Keybind:CheckDown(Keybind.generic.lclick) then
local mouse_x = love.mouse.getX() local mouse_x = love.mouse.getX()
local mouse_y = love.mouse.getY() local mouse_y = love.mouse.getY()
@ -165,13 +168,15 @@ function EditorDoPalette()
then then
selecting_tile = position_x + ((position_y-1) * width) selecting_tile = position_x + ((position_y-1) * width)
love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y) love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y, 0, 20)
else
--selecting_tile = nil
end end
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.setColor(1,0,1,1)
love.graphics.rectangle( love.graphics.rectangle(
"line", "line",

View File

@ -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

View File

@ -3,6 +3,7 @@ Fairy = Entity:New(x,y)
function Fairy:New(x,y) function Fairy:New(x,y)
local o = Entity:New(x,y) local o = Entity:New(x,y)
-- behaviour
o.pos = {x = x, y = y} o.pos = {x = x, y = y}
o.speed = 0.23 o.speed = 0.23
o.range = 20 o.range = 20
@ -13,9 +14,13 @@ Fairy = Entity:New(x,y)
o:centerOffset(o.body) o:centerOffset(o.body)
o:getBoundingBox(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 -- timer
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) o.particle_timer = 0
o.particle_time = 5
table.insert(LoadedEntities,o) table.insert(LoadedEntities,o)
o.id = #LoadedEntities o.id = #LoadedEntities
@ -26,8 +31,6 @@ Fairy = Entity:New(x,y)
end end
function Fairy:Smart() 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.x = main_Player.pos.x - main_Player.target_offset.x
self.target.y = main_Player.pos.y - main_Player.target_offset.y - 10 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.x = 0
self.vel.y = 0 self.vel.y = 0
else else
self.vel.x = math.cos(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*game.scale) self.vel.y = math.sin(angle)*self.speed*distance/8
end end
self.particle_timer = self.particle_timer + 1
if self.particle_timer >= self.particle_time then
self.particle_timer = 0
local particle_data = { local particle_data = {
animation = animation.particle.fairy, animation = animation.particle.simple,
direction = angle-math.rad(180), sprite_tint = HEX2RGB("#fe00d1"),
speed = self.speed*distance/(16*game.scale), direction = angle-math.rad(180+math.random(60)-30),
light = 85 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 end
function Fairy:HandleAnimation() function Fairy:HandleAnimation()
@ -60,11 +72,12 @@ function Fairy:HandleAnimation()
end end
function Fairy:DoPhysics() function Fairy:DoPhysics()
local random_x = math.random(-4, 4)/100 local random_x = math.random(-4, 4)/100
local random_y = math.random(-4, 4)/100 local random_y = math.random(-4, 4)/100
self.vel.x = self.vel.x + random_x self.vel.x = self.vel.x + random_x
self.vel.y = self.vel.y + random_y self.vel.y = self.vel.y + random_y
-- move -- move
self:CollisionMove() self:CollisionMove()
self:LightAdjust()
end end

View File

@ -26,16 +26,23 @@ Particle = Entity:New(x,y)
y = o.speed * math.sin(o.direction) y = o.speed * math.sin(o.direction)
} }
o.speed_increase = particle_data.speed_increase or 0
if particle_data.light ~= nil then if particle_data.light ~= nil then
o.lightRange = particle_data.light 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 end
-- animations -- animations
o.body = Animation:New(particle_data.animation) if particle_data.animation ~= nil then
o:centerOffset(o.body) o.body = Animation:New(particle_data.animation)
if not o.animation_active then o:centerOffset(o.body)
o.body.speed = 0 o:getBoundingBox(o.body)
if not o.animation_active then
o.body.speed = 0
end
end end
table.insert(LoadedParticles,o) table.insert(LoadedParticles,o)
@ -62,16 +69,32 @@ function Particle:Kill()
end end
function Particle:HandleAnimation() function Particle:HandleAnimation()
self.body:Animate()
self.timer = self.timer + current_dt self.timer = self.timer + current_dt
self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time
if self.light ~= nil then if self.light ~= nil then
self:LightAdjust()
self.light.range = self.lightRange * self.sprite_alpha/2 self.light.range = self.lightRange * self.sprite_alpha/2
end end
if self.sprite_alpha < 0 then self:Kill() end if self.sprite_alpha < 0 then self:Kill() end
self:Draw(self.body) if self.body ~= nil then
self.body:Animate()
self:Draw(self.body)
end
end end
function Particle:DoPhysics() 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 end

View File

@ -7,37 +7,40 @@
Player.coins = 0 Player.coins = 0
-- physics -- physics
o.moveSpeed = 1.3 o.moveSpeed = 1.3 -- gameworld pixels
o.zeroSpeed = 0.01 o.zeroSpeed = 0.01 -- gameworld pixels
o.move_x = 0 o.move_x = 0 -- gameworld pixels
o.airFriction = 0.01 o.airFriction = 0.01 -- gameworld pixels
o.groundFriction = 0.3 o.groundFriction = 0.3 -- gameworld pixels
o.jumpImpulse = 3.5 o.jumpImpulse = 3.5 -- gameworld pixels
o.dashCooldownTime = 0.1 o.coyoteAmount = 5 -- int
o.dashCooldownTimer = 0 o.coyoteValue = 5 -- frames
o.dashTimer = 0 o.dashCooldownTime = 0.1 -- seconds
o.dashTime = 0.15 o.dashCooldownTimer = 0 -- seconds
o.dashDistance = 40
o.dashSpeed = o.dashDistance / (o.dashTime*60) o.dashTimer = 0 -- seconds
o.dashCount = 1 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 = { o.boxCollision = {
from = {x = -8, y = -16}, from = {x = -8, y = -16}, --gameworld pixels
to = {x = 8, y = 0} to = {x = 8, y = 0} -- gameworld pixels
} }
o.lightRange = 0--32 o.lightRange = 344 -- screen pixels
-- status -- status
o.isDashing = false o.isDashing = false
o.isJumping = false o.isJumping = false
o.isOnGround = 0 o.isOnGround = true
o.coyoteValue = 5 o.isOnLadder = false
o.isOnLadder = false
o.canJump = true o.canJump = true
o.canFall = true o.canFall = true
o.canFriction = true o.canFriction = true
@ -48,7 +51,7 @@
o.body = Animation:New(animation.nancy.idle) o.body = Animation:New(animation.nancy.idle)
o.mask = Animation:New(animation.moth_mask.idle) o.mask = Animation:New(animation.moth_mask.idle)
o:centerOffset(o.body) o:centerOffset(o.body)
o:getBoundingBox(o.body, 3,-3,0,-1) o:getBoundingBox(o.body,0,3,-1,-3)
-- lights -- lights
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange)
@ -85,12 +88,19 @@ function Player:Smart()
self.vel.x = self.vel.x self.vel.x = self.vel.x
if Keybind:CheckDown(Keybind.move.jump) then if Keybind:CheckDown(Keybind.move.jump) then
if self.isOnGround then if self.coyoteValue > 0 then
self.vel.y = -self.jumpImpulse self.vel.y = -self.jumpImpulse
self.coyoteValue = 0
end end
end 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) self.dashCooldownTimer = math.max(0,self.dashCooldownTimer - current_dt)
if Keybind:CheckDown(Keybind.move.dash) then if Keybind:CheckDown(Keybind.move.dash) then
if self.dashCooldownTimer == 0 if self.dashCooldownTimer == 0
@ -118,14 +128,14 @@ function Player:Smart()
end end
function Player:DoPhysics() function Player:DoPhysics()
-- reset state
self.isOnGround = false self.isOnGround = false
-- adjust timers
self.dashTimer = self.dashTimer - current_dt self.dashTimer = self.dashTimer - current_dt
-- DASH STATE -- DASH STATE
if self.dashTimer > 0 then if self.dashTimer > 0 then
-- dash particle
local particle_data = { local particle_data = {
animation = self.body, animation = self.body,
sprite_tint = HEX2RGB("#fed100"), sprite_tint = HEX2RGB("#fed100"),
@ -137,9 +147,11 @@ function Player:DoPhysics()
} }
Particle:New(self.pos.x,self.pos.y,particle_data) Particle:New(self.pos.x,self.pos.y,particle_data)
self.dashCooldownTimer = self.dashCooldownTime self.dashCooldownTimer = self.dashCooldownTime
-- dash movement
self.vel.x = self.dashSpeed * math.cos(self.dashDirection) self.vel.x = self.dashSpeed * math.cos(self.dashDirection)
self.vel.y = self.dashSpeed * math.sin(self.dashDirection) self.vel.y = self.dashSpeed * math.sin(self.dashDirection)
else else
-- not in dash; fall normally
self.dashTimer = 0 self.dashTimer = 0
self.vel.y = self.vel.y + gravity self.vel.y = self.vel.y + gravity
end end
@ -155,7 +167,7 @@ function Player:DoPhysics()
else else
if self.vel.y > 0 then if self.vel.y > 0 then
self.isOnGround = true self.isOnGround = true
self.dashCount = 1 self.dashCount = self.dashAmount
self.vel.y = 0 self.vel.y = 0
end end
end end

View File

@ -39,9 +39,20 @@ end
function Entity:CollisionMove() function Entity:CollisionMove()
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then 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 self.pos.x = self.pos.x + self.vel.x
else
self.vel.x = 0
end end
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then 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 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
end end
@ -80,7 +91,7 @@ function Entity:centerOffset(animation,x,y)
self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y
end end
function Entity:getBoundingBox(animation,left,right,top,bottom) function Entity:getBoundingBox(animation,top,left,bottom,right)
local left = left or 0 local left = left or 0
local right = right or 0 local right = right or 0
local top = top or 0 local top = top or 0
@ -125,9 +136,24 @@ function Entity:isCollidingAtAll(x,y)
return result return result
end 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/kupo"
require "data/scripts/entities/arrow" require "data/scripts/entities/arrow"
require "data/scripts/entities/decoration" require "data/scripts/entities/decoration"
require "data/scripts/entities/player" require "data/scripts/entities/player"
require "data/scripts/entities/fairy" require "data/scripts/entities/fairy"
require "data/scripts/entities/cursed_book"
require "data/scripts/entities/particle" require "data/scripts/entities/particle"

View File

@ -1,16 +1,33 @@
-- animationsç -- animationsç
-- all these are linear animations, maybe in the future make proper animations? -- all these are linear animations, maybe in the future make proper animations?
animation = { animation = {
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 = { particle = {
fairy = { simple = {
path = "assets/entities/particle/fairy", path = "assets/entities/particle/simple",
frames = 4, frames = 4,
speed = 1/4 speed = 1/4
},
player_dash = {
path = "assets/entities/particle/player_dash",
frames = 1,
speed = 0
} }
}, },
fairy = { fairy = {

View File

@ -18,8 +18,8 @@ end
function GameDraw() function GameDraw()
GameworldDrawPrepare() GameworldDrawPrepare()
GameworldDrawBackground()
GameworldDrawParticles() GameworldDrawParticles()
GameworldDrawBackground()
GameworldDrawEntities() GameworldDrawEntities()
GameworldDrawForeground() GameworldDrawForeground()
GameworldDrawEnd() GameworldDrawEnd()

View File

@ -3,6 +3,7 @@ Keybind.move = {}
Keybind.menu = {} Keybind.menu = {}
Keybind.debug = {} Keybind.debug = {}
Keybind.editor = {} Keybind.editor = {}
Keybind.generic = {}
function Keybind:CheckDown(action) function Keybind:CheckDown(action)
for _, keyname in pairs(action.keys) do for _, keyname in pairs(action.keys) do
@ -66,6 +67,10 @@ function Keybind:Default()
Keybind.debug.editor = { keys = {"f4"}} Keybind.debug.editor = { keys = {"f4"}}
-- Editor -- Editor
Keybind.editor.palette = { keys = {"tab"}} Keybind.editor.palette = { keys = {"tab"}}
-- Generic
Keybind.generic.lclick = { keys = {1}}
Keybind.generic.rclick = { keys = {2}}
end end
-- Set default values at start -- Set default values at start

View File

@ -1,39 +1,54 @@
function LevelLoadTiles() function LevelLoadTiles()
LevelData = dofile("Mothback/data/levels/"..currLevel..".lua")
-- tiles data
TileData = dofile("Mothback/data/tileset/library.lua")
--[[ --[[
on level format: on level format:
id = tile identifier id = tile identifier
depth = order in the render depth = order in the render
force = rendering other tile instead of the one in this position 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 overlay_depth = foreground/background overlay depth
type = collision type type = collision type
]] ]]
-- Level data
LevelData = dofile("Mothback/data/levels/"..currLevel..".lua")
-- tiles data
TileData = dofile("Mothback/data/tileset/library.lua")
LevelTiles = LevelData.tiles LevelTiles = LevelData.tiles
LevelData.Width = LevelGetWidth() LevelUpdateDimensions()
LevelData.Height = LevelGetHeight()
LevelIndexTiles() LevelIndexTiles()
TileCreateObjects() TileCreateObjects()
end end
function LevelGetHeight() function LevelReloadTiles()
return #LevelTiles * tileProperties.height LevelUpdateDimensions()
TileCreateObjects()
end end
function LevelGetWidth() function LevelUpdateDimensions()
LevelData.Width = LevelGetWidth()
LevelData.Height = LevelGetHeight()
end
function LevelGetTileHeight()
return #LevelTiles
end
function LevelGetTileWidth()
local width = 0 local width = 0
for i = 1, #LevelTiles do for i = 1, #LevelTiles do
if width < #LevelTiles[i] then width = #LevelTiles[i] end if width < #LevelTiles[i] then width = #LevelTiles[i] end
end end
return width * tileProperties.width return width
end
function LevelGetHeight()
return LevelGetTileHeight() * tileProperties.height
end
function LevelGetWidth()
return LevelGetTileWidth() * tileProperties.width
end end
function LevelIndexTiles() function LevelIndexTiles()
@ -53,8 +68,17 @@ function LevelIndexTiles()
) )
end end
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 for _, Properties in pairs(TileData) do
if Properties.animation ~= nil then if Properties.animation ~= nil then
Properties.tileset = love.graphics.newImage("assets/terrain/"..Properties.animation..".png") Properties.tileset = love.graphics.newImage("assets/terrain/"..Properties.animation..".png")
@ -85,33 +109,28 @@ function LevelIndexTiles()
Properties.image_count = image_count Properties.image_count = image_count
end end
end end
end
-- instance level tiles according to the Properties function InstanceTile(i,j,id)
for i = 1, #LevelTiles do LevelTiles[i][j] = {}
for j = 1, #LevelTiles[i] do local tile = LevelTiles[i][j]
local id = LevelTiles[i][j] tile.id = id
LevelTiles[i][j] = {}
local tile = LevelTiles[i][j]
tile.id = id
for _, Properties in pairs(TileData) do for _, Properties in pairs(TileData) do
if Properties.id == tile.id then if Properties.id == tile.id then
if type(Properties.overlay) == "table" then if type(Properties.overlay) == "table" then
tile.display_overlay = Properties.overlay[math.random(#Properties.overlay)] tile.display_overlay = Properties.overlay[math.random(#Properties.overlay)]
else else
tile.display_overlay = Properties.overlay tile.display_overlay = Properties.overlay
end end
if type(Properties.force) == "table" then if type(Properties.force) == "table" then
tile.display = Properties.force[math.random(#Properties.force)] tile.display = Properties.force[math.random(#Properties.force)]
else else
tile.display = Properties.force tile.display = Properties.force
end
end end
end end
end end
end
end end
function TileGetType(tile) function TileGetType(tile)

View File

@ -5,7 +5,7 @@ function CreateDarkness()
return love.graphics.newCanvas(game.width/game.scale, game.height/game.scale) return love.graphics.newCanvas(game.width/game.scale, game.height/game.scale)
end end
function CreateLight(x,y,range,lum,flicker) function CreateLight(x,y,range,flicker,color,lum)
local o = {} local o = {}
o.pos = { o.pos = {
x = x, x = x,
@ -13,11 +13,13 @@ function CreateLight(x,y,range,lum,flicker)
} }
o.range = range o.range = range
o.lum = lum or 1 o.lum = lum or 1
o.color = color or {1,1,1}
o.flicker_value = flicker or 2 o.flicker_value = flicker or 2
o.flicker = 0 o.flicker = 0
o.dim = 0 o.dim = 0
o.flicker_speed = flicker_speed or 60/12 o.flicker_speed = flicker_speed or 60/12
o.flicker_time = 0 o.flicker_time = 0
table.insert(Lights,o) table.insert(Lights,o)
o.id = #Lights o.id = #Lights
return o return o
@ -52,9 +54,9 @@ function DoLights()
end end
end end
love.graphics.setBlendMode("replace") love.graphics.setBlendMode("replace")
love.graphics.setColor(1,1,1,1)
for _, light in pairs(Lights) do for _, light in pairs(Lights) do
if light.range ~= 0 then if light.range ~= 0 then
love.graphics.setColor(light.color[1],light.color[2],light.color[3],1)
love.graphics.circle( love.graphics.circle(
"fill", "fill",
(light.pos.x - Camera.pos.x) / game.scale, (light.pos.x - Camera.pos.x) / game.scale,

View File

@ -46,10 +46,11 @@ function love.load()
main_Player = Player:New(75,50) main_Player = Player:New(75,50)
Kupo:New(100,150) --Kupo:New(100,150)
Kupo:New(300,150) --Kupo:New(300,150)
Decoration:New(200,89,animation.decoration.candelabra,80) --Decoration:New(200,89,animation.decoration.candelabra,80)
Fairy:New(200,88) --Fairy:New(200,88)
--CursedBook:New(180,68)
gravity = 0.2 gravity = 0.2
end end