feat: initial terrain collision system

Fixes #79
This commit is contained in:
Kazhnuz 2021-04-18 12:34:30 +02:00
parent b16665a2b0
commit 32c72c18e9
5 changed files with 170 additions and 97 deletions

View file

@ -1,62 +1,87 @@
return { return {
["non-solid"] = { highpriority = {"ice"},
{ list = {
terrainType = "normal", ["non-solid"] = {
forceAction = nil, {
level=0, forceAction = nil,
height=0, level=0,
canJump = true height=0,
} canJump = true
}, }
ice = {
{
terrainType = "forceAction",
forceAction = "slide",
level=0,
height=0,
canJump = false
}
},
water = {
{
terrainType = "forceAction",
forceAction = "fall",
level=-32,
height=0,
damage = 10,
speedFactor = 0,
}, },
{ ice = {
terrainType = "normal", {
forceAction = nil, forceAction = "slide",
level=-10, level=0,
height=0, height=0,
mustHaveAction = "swim", canJump = false,
mustDoAction = nil, speedFactor = 1.2,
speedFactor = 0.8, }
canJump = true,
damage = 0,
}, },
{ water = {
terrainType = "normal", {
forceAction = nil, level=-32,
level=0, height=0,
height=0, fallDamage = 10,
mustHaveAction = "run", speedFactor = 0,
mustDoAction = "run", canJump = false,
speedFactor = 1, },
canJump = true, {
damage = 0, forceAction = nil,
} level=-10,
}, height=0,
grass = { mustHaveAction = "swim",
{ mustDoAction = nil,
terrainType = "normal", speedFactor = 0.5,
forceAction = nil, canJump = true,
level=0, damage = 0,
height=16, },
speedFactor = 0.75, {
canJump = false, forceAction = nil,
level=0,
height=0,
mustHaveAction = "run",
mustDoAction = "run",
speedFactor = 1,
canJump = true,
damage = 0,
}
},
hole = {
{
level=-32,
height=0,
fallDamage = 10,
speedFactor = 0,
canJump = false,
},
},
lava = {
{
level=-32,
height=0,
fallDamage = 20,
speedFactor = 0,
canJump = false,
},
},
swamp = {
{
forceAction = nil,
level=-8,
height=0,
speedFactor = 0.66,
canJump = false,
}
},
grass = {
{
forceAction = nil,
level=0,
height=8,
speedFactor = 0.66,
canJump = false,
}
} }
} }
} }

View file

@ -10,7 +10,7 @@ function Gizmo:new(world, x, y, w, h, overrides)
local h = h or 16; local h = h or 16;
Gizmo.super.new(self, world, "gizmo", x, y, w, h, false) Gizmo.super.new(self, world, "gizmo", x, y, w, h, false)
self.overrides = overrides self.overrides = overrides
self.drawDebugBox = true self.drawDebugBox = false
self.event = defaultEvent self.event = defaultEvent
end end

View file

@ -11,6 +11,10 @@ ACTIONS["power"] = {"punch"}
function PlayerActions:initActions() function PlayerActions:initActions()
self.currentAction = "idle" self.currentAction = "idle"
self.canJump = true
self.canAct = true
self.speedFactor = 1
self.forceAction = nil
end end
function PlayerActions:canDoAction(action) function PlayerActions:canDoAction(action)
@ -19,44 +23,75 @@ function PlayerActions:canDoAction(action)
return (classCanDoAction and playerCanDoAction) return (classCanDoAction and playerCanDoAction)
end end
function PlayerActions:act()
if (self.forceAction ~= nil) then
self:forcedAction()
else
self:actionMove()
self:actionJump()
self:actionSwitch()
self:actionRun()
self:actionPunch()
end
end
function PlayerActions:forcedAction()
local charSpeed = BASE_SPEED * self.speedFactor
if (self.forceAction == "slide") then
if (self.xsp ~= 0 or self.ysp ~= 0) then
if (self.currentAction == "run") then
charSpeed = charSpeed * RUN_FACTOR
end
self.xsp, self.ysp = utils.math.lengthdir(charSpeed, math.rad(self.charsetManager.angle[self.charDir]))
self.xsp = -self.xsp
else
self:actionMove()
end
end
end
function PlayerActions:actionMove() function PlayerActions:actionMove()
local charSpeed = BASE_SPEED * self.speedFactor
if (self.currentAction == "punch") then if (self.currentAction == "punch") then
return return
end end
if (self.currentAction == "jumpdash" or self.currentAction == "run") then if (self.currentAction == "jumpdash" or self.currentAction == "run") then
self.xsp, self.ysp = utils.math.lengthdir(BASE_SPEED * RUN_FACTOR, math.rad(self.charsetManager.angle[self.charDir])) self.xsp, self.ysp = utils.math.lengthdir(charSpeed * RUN_FACTOR, math.rad(self.charsetManager.angle[self.charDir]))
self.xsp = -self.xsp self.xsp = -self.xsp
if (utils.table.contain({"up", "down"}, self.charDir)) then if (utils.table.contain({"up", "down"}, self.charDir)) then
if self.keys["left"].isDown then if self.keys["left"].isDown then
self.xsp = -BASE_SPEED self.xsp = -charSpeed
end end
if self.keys["right"].isDown then if self.keys["right"].isDown then
self.xsp = BASE_SPEED self.xsp = charSpeed
end end
else else
if self.keys["up"].isDown then if self.keys["up"].isDown then
self.ysp = -BASE_SPEED self.ysp = -charSpeed
end end
if self.keys["down"].isDown then if self.keys["down"].isDown then
self.ysp = BASE_SPEED self.ysp = charSpeed
end end
end end
else else
if self.keys["up"].isDown then if self.keys["up"].isDown then
self.ysp = -BASE_SPEED self.ysp = -charSpeed
self.charDir = "up" self.charDir = "up"
end end
if self.keys["down"].isDown then if self.keys["down"].isDown then
self.ysp = BASE_SPEED self.ysp = charSpeed
self.charDir = "down" self.charDir = "down"
end end
if self.keys["left"].isDown then if self.keys["left"].isDown then
self.xsp = -BASE_SPEED self.xsp = -charSpeed
self.charDir = "left" self.charDir = "left"
end end
if self.keys["right"].isDown then if self.keys["right"].isDown then
self.xsp = BASE_SPEED self.xsp = charSpeed
self.charDir = "right" self.charDir = "right"
end end
end end
@ -64,7 +99,7 @@ end
function PlayerActions:actionJump() function PlayerActions:actionJump()
if self.keys["B"].isPressed then if self.keys["B"].isPressed then
if (self.onGround) then if (self.onGround and self.canJump) then
self:goUpward(JMP_STRENGHT) self:goUpward(JMP_STRENGHT)
self.assets.sfx["jump"]:play() self.assets.sfx["jump"]:play()
if (self.currentAction == "run") then if (self.currentAction == "run") then
@ -101,7 +136,7 @@ end
function PlayerActions:actionRun() function PlayerActions:actionRun()
if self.keys["C"].isPressed then if self.keys["C"].isPressed then
if (self:canDoAction("run")) then if (self:canDoAction("run") and self.speedFactor > 0) then
self.assets.sfx["dash"]:play() self.assets.sfx["dash"]:play()
if (utils.table.contain({"run", "idle"}, self.currentAction)) then if (utils.table.contain({"run", "idle"}, self.currentAction)) then
self.currentAction = "run" self.currentAction = "run"

View file

@ -14,17 +14,18 @@ Player:implement(Actions)
Player:implement(Charset) Player:implement(Charset)
Player:implement(Map) Player:implement(Map)
local FRICTION = 480 * 3 local FRICTION = 480 * 3
local GRAV = 10 local GRAV = 10
local DEFAULT_GROUND_LEVEL = 0 local DEFAULT_GROUND_LEVEL = 0
local DEFAULT_GROUND_HEIGHT = 0 local DEFAULT_GROUND_HEIGHT = 0
local RESPAWN_LIMIT = -32
function Player:new(world, x, y, id) function Player:new(world, x, y, id)
Player.super.new(self, world, "player", x, y, 16, 16, true) Player.super.new(self, world, "player", x, y, 16, 16, true)
self.groundLevel = DEFAULT_GROUND_LEVEL self.groundLevel = DEFAULT_GROUND_LEVEL
self.groundHeight = DEFAULT_GROUND_HEIGHT self.groundHeight = DEFAULT_GROUND_HEIGHT
self.z = self.groundLevel self.z = self.groundLevel
self.grav = GRAV
self.tweens = TweenManager(self) self.tweens = TweenManager(self)
self.onGround = true self.onGround = true
@ -41,11 +42,7 @@ function Player:updateStart(dt)
self.tweens:update(dt) self.tweens:update(dt)
self:updateTerrain() self:updateTerrain()
self:actionMove() self:act()
self:actionJump()
self:actionSwitch()
self:actionRun()
self:actionPunch()
self.world:getTileTypeAtPoint(self.x, self.y) self.world:getTileTypeAtPoint(self.x, self.y)
@ -77,6 +74,10 @@ function Player:checkGround()
self.z = self.groundLevel self.z = self.groundLevel
self.zsp = 0 self.zsp = 0
self:endJump() self:endJump()
if (self.z <= RESPAWN_LIMIT) then
self.x = self.lastPos.x
self.y = self.lastPos.y
end
end end
end end

View file

@ -21,8 +21,8 @@ function PlayerInteractions:initInteractions()
self.terrain.name = "" self.terrain.name = ""
self.terrain.data = {} self.terrain.data = {}
self.lastPos = {} self.lastPos = {}
self.lastPos.x = math.floor(self.x/16) * 16 self.lastPos.x = self.x
self.lastPos.y = math.floor(self.y/16) * 16 self.lastPos.y = self.y
end end
function PlayerInteractions:updateInteraction() function PlayerInteractions:updateInteraction()
@ -73,12 +73,8 @@ end
function PlayerInteractions:updateTerrain() function PlayerInteractions:updateTerrain()
local newTerrain = self:getCurrentTerrain() local newTerrain = self:getCurrentTerrain()
self.terrain.name = newTerrain
if (self.terrain.name ~= newTerrain) then self:updateTerrainData()
print(newTerrain)
self.terrain.name = newTerrain
self:updateTerrainData()
end
if (newTerrain == "non-solid") then if (newTerrain == "non-solid") then
self:updateLastPosition() self:updateLastPosition()
end end
@ -87,25 +83,27 @@ end
function PlayerInteractions:updateLastPosition() function PlayerInteractions:updateLastPosition()
local canUpdate = true local canUpdate = true
for _, coord in ipairs(TERRAIN_CHECKER) do for _, coord in ipairs(TERRAIN_CHECKER) do
local newTerrain = self.world:getTileTypeAtPoint(self.x + coord.x, self.y + coord.y) local xx, yy = coord.x, coord.y
if (xx == MIN_X) then xx=0 else xx=16 end
if (yy == MIN_Y) then yy=0 else yy=16 end
local newTerrain = self.world:getTileTypeAtPoint(self.x + xx, self.y + yy)
if (newTerrain ~= "non-solid") then if (newTerrain ~= "non-solid") then
self.canUpdate = false canUpdate = false
break;
end end
end end
if (canUpdate) then if (canUpdate and self.onGround) then
self.lastPos = {} self.lastPos = {}
self.lastPos.x = math.floor(self.x/16) * 16 self.lastPos.x = self.x
self.lastPos.y = math.floor(self.y/16) * 16 self.lastPos.y = self.y
end end
end end
function PlayerInteractions:updateTerrainData() function PlayerInteractions:updateTerrainData()
local dataPack = terrainData[self.terrain.name] local dataPack = terrainData.list[self.terrain.name]
local newData = terrainData["non-solid"][1] local newData = terrainData.list["non-solid"][1]
if (dataPack == nil) then if (dataPack == nil) then
dataPack = terrainData["non-solid"] dataPack = terrainData.list["non-solid"]
end end
for id, data in ipairs(dataPack) do for id, data in ipairs(dataPack) do
@ -119,7 +117,6 @@ function PlayerInteractions:updateTerrainData()
if (useThisData) then if (useThisData) then
newData = data newData = data
print(id)
end end
end end
@ -127,16 +124,31 @@ function PlayerInteractions:updateTerrainData()
end end
function PlayerInteractions:setTerrainData(data) function PlayerInteractions:setTerrainData(data)
--TODO self.groundLevel = data.level or 0
self.groundHeight = data.height or 0
if (self.onGround) then
self.speedFactor = data.speedFactor or 1
self.canJump = data.canJump ~= false
self.forceAction = data.forceAction
end
self.terrain.data = data
end end
function PlayerInteractions:getCurrentTerrain() function PlayerInteractions:getCurrentTerrain()
local terrain = self.terrain.name local terrain = ""
local highpriority = terrainData.highpriority
for _, coord in ipairs(TERRAIN_CHECKER) do for _, coord in ipairs(TERRAIN_CHECKER) do
local newTerrain = self.world:getTileTypeAtPoint(self.x + coord.x, self.y + coord.y) local newTerrain = self.world:getTileTypeAtPoint(self.x + coord.x, self.y + coord.y)
terrain = newTerrain if (utils.table.contain(highpriority, newTerrain)) then
if (newTerrain == "non-solid") then terrain = newTerrain
break; elseif (newTerrain == "non-solid") then
if (not utils.table.contain(highpriority, terrain)) then
terrain = newTerrain
end
else
if (not (utils.table.contain(highpriority, terrain) or terrain == "non-solid")) then
terrain = newTerrain
end
end end
end end
return terrain return terrain