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 {
["non-solid"] = {
{
terrainType = "normal",
forceAction = nil,
level=0,
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,
highpriority = {"ice"},
list = {
["non-solid"] = {
{
forceAction = nil,
level=0,
height=0,
canJump = true
}
},
{
terrainType = "normal",
forceAction = nil,
level=-10,
height=0,
mustHaveAction = "swim",
mustDoAction = nil,
speedFactor = 0.8,
canJump = true,
damage = 0,
ice = {
{
forceAction = "slide",
level=0,
height=0,
canJump = false,
speedFactor = 1.2,
}
},
{
terrainType = "normal",
forceAction = nil,
level=0,
height=0,
mustHaveAction = "run",
mustDoAction = "run",
speedFactor = 1,
canJump = true,
damage = 0,
}
},
grass = {
{
terrainType = "normal",
forceAction = nil,
level=0,
height=16,
speedFactor = 0.75,
canJump = false,
water = {
{
level=-32,
height=0,
fallDamage = 10,
speedFactor = 0,
canJump = false,
},
{
forceAction = nil,
level=-10,
height=0,
mustHaveAction = "swim",
mustDoAction = nil,
speedFactor = 0.5,
canJump = true,
damage = 0,
},
{
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;
Gizmo.super.new(self, world, "gizmo", x, y, w, h, false)
self.overrides = overrides
self.drawDebugBox = true
self.drawDebugBox = false
self.event = defaultEvent
end

View file

@ -11,6 +11,10 @@ ACTIONS["power"] = {"punch"}
function PlayerActions:initActions()
self.currentAction = "idle"
self.canJump = true
self.canAct = true
self.speedFactor = 1
self.forceAction = nil
end
function PlayerActions:canDoAction(action)
@ -19,44 +23,75 @@ function PlayerActions:canDoAction(action)
return (classCanDoAction and playerCanDoAction)
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()
local charSpeed = BASE_SPEED * self.speedFactor
if (self.currentAction == "punch") then
return
end
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
if (utils.table.contain({"up", "down"}, self.charDir)) then
if self.keys["left"].isDown then
self.xsp = -BASE_SPEED
self.xsp = -charSpeed
end
if self.keys["right"].isDown then
self.xsp = BASE_SPEED
self.xsp = charSpeed
end
else
if self.keys["up"].isDown then
self.ysp = -BASE_SPEED
self.ysp = -charSpeed
end
if self.keys["down"].isDown then
self.ysp = BASE_SPEED
self.ysp = charSpeed
end
end
else
if self.keys["up"].isDown then
self.ysp = -BASE_SPEED
self.ysp = -charSpeed
self.charDir = "up"
end
if self.keys["down"].isDown then
self.ysp = BASE_SPEED
self.ysp = charSpeed
self.charDir = "down"
end
if self.keys["left"].isDown then
self.xsp = -BASE_SPEED
self.xsp = -charSpeed
self.charDir = "left"
end
if self.keys["right"].isDown then
self.xsp = BASE_SPEED
self.xsp = charSpeed
self.charDir = "right"
end
end
@ -64,7 +99,7 @@ end
function PlayerActions:actionJump()
if self.keys["B"].isPressed then
if (self.onGround) then
if (self.onGround and self.canJump) then
self:goUpward(JMP_STRENGHT)
self.assets.sfx["jump"]:play()
if (self.currentAction == "run") then
@ -101,7 +136,7 @@ end
function PlayerActions:actionRun()
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()
if (utils.table.contain({"run", "idle"}, self.currentAction)) then
self.currentAction = "run"

View file

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

View file

@ -21,8 +21,8 @@ function PlayerInteractions:initInteractions()
self.terrain.name = ""
self.terrain.data = {}
self.lastPos = {}
self.lastPos.x = math.floor(self.x/16) * 16
self.lastPos.y = math.floor(self.y/16) * 16
self.lastPos.x = self.x
self.lastPos.y = self.y
end
function PlayerInteractions:updateInteraction()
@ -73,12 +73,8 @@ end
function PlayerInteractions:updateTerrain()
local newTerrain = self:getCurrentTerrain()
if (self.terrain.name ~= newTerrain) then
print(newTerrain)
self.terrain.name = newTerrain
self:updateTerrainData()
end
self.terrain.name = newTerrain
self:updateTerrainData()
if (newTerrain == "non-solid") then
self:updateLastPosition()
end
@ -87,25 +83,27 @@ end
function PlayerInteractions:updateLastPosition()
local canUpdate = true
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
self.canUpdate = false
break;
canUpdate = false
end
end
if (canUpdate) then
if (canUpdate and self.onGround) then
self.lastPos = {}
self.lastPos.x = math.floor(self.x/16) * 16
self.lastPos.y = math.floor(self.y/16) * 16
self.lastPos.x = self.x
self.lastPos.y = self.y
end
end
function PlayerInteractions:updateTerrainData()
local dataPack = terrainData[self.terrain.name]
local newData = terrainData["non-solid"][1]
local dataPack = terrainData.list[self.terrain.name]
local newData = terrainData.list["non-solid"][1]
if (dataPack == nil) then
dataPack = terrainData["non-solid"]
dataPack = terrainData.list["non-solid"]
end
for id, data in ipairs(dataPack) do
@ -119,7 +117,6 @@ function PlayerInteractions:updateTerrainData()
if (useThisData) then
newData = data
print(id)
end
end
@ -127,16 +124,31 @@ function PlayerInteractions:updateTerrainData()
end
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
function PlayerInteractions:getCurrentTerrain()
local terrain = self.terrain.name
local terrain = ""
local highpriority = terrainData.highpriority
for _, coord in ipairs(TERRAIN_CHECKER) do
local newTerrain = self.world:getTileTypeAtPoint(self.x + coord.x, self.y + coord.y)
terrain = newTerrain
if (newTerrain == "non-solid") then
break;
if (utils.table.contain(highpriority, newTerrain)) then
terrain = newTerrain
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
return terrain