intdesjam_misc/plat.lua

130 lines
4.6 KiB
Lua

local DEFAULT_PLATFORM_COLOR = {255,255,255}
local GRAVITY_CONSTANT = 100
local AIR_RES_CONSTANT = 1
local VERY_SMALL_NUM = 0.01
local function platform_below_platform (platform, system)
return system:isPointOccupied(platform.x, platform.y + platform.h + VERY_SMALL_NUM, platform) or system:isPointOccupied(platform.x + platform.w, platform.y + platform.h + VERY_SMALL_NUM, platform)
end
--------------------------------------------------------------------------------
local PlayerController = {}
PlayerController.__index = PlayerController
function PlayerController.new (target, controls)
assert(controls.jump and controls.left and controls.right )
local self = setmetatable({}, PlayerController)
self.target = target
self.controls = controls
return self
end
function PlayerController:update (dt, system)
local not_jumping = platform_below_platform(self.target, system)
if love.keyboard.isDown( self.controls.jump ) and not_jumping then
self.target.dy = - 220
elseif love.keyboard.isDown( self.controls.left ) then
self.target.dx = self.target.dx - 15
elseif love.keyboard.isDown( self.controls.right ) then
self.target.dx = self.target.dx + 15
end
end
--------------------------------------------------------------------------------
local Platform = {}
Platform.__index = Platform
function Platform.new (t)
local self = setmetatable(t, Platform)
assert(self.x and self.y and self.w and self.y)
self.color = self.color or DEFAULT_PLATFORM_COLOR
return self
end
--------------------------------------------------------------------------------
local PlatformSystem = {}
PlatformSystem.__index = PlatformSystem
function PlatformSystem.new ()
local self = setmetatable({}, PlatformSystem)
self.platforms = {}
self.controllers = {}
return self
end
function PlatformSystem:addPlatform (x, y, w, h)
self.platforms[#self.platforms + 1] = Platform.new {
x = x, y = y, w = w, h = h
}
end
function PlatformSystem:addPlayer ( x, y, w, h, controls )
local platform = Platform.new {
x = x, y = y, w = w, h = h,
movable = true, dx = 0, dy = 0
}
self.platforms[#self.platforms + 1] = platform
self.controllers[#self.controllers + 1] = PlayerController.new(platform, controls)
return platform
end
function PlatformSystem:isPointOccupied (x, y, except)
for _, platform in ipairs(self.platforms) do
if platform.x <= x and x <= platform.x + platform.w and platform.y <= y and y <= platform.y + platform.h and platform ~= except then
return platform
end
end
return false
end
function PlatformSystem:updatePlatform (platform, dt)
local ndx, ndy = platform.dx * (1 - AIR_RES_CONSTANT * dt), platform.dy + GRAVITY_CONSTANT * dt
local nx, ny = platform.x + ndx * dt, platform.y + ndy * dt
if true then
if not self:isPointOccupied(platform.x, ny, platform) and not self:isPointOccupied(platform.x + platform.w, ny, platform) and not self:isPointOccupied(platform.x, ny + platform.h, platform) and not self:isPointOccupied(platform.x + platform.w, ny + platform.h, platform) then
platform.y, platform.dy = ny, ndy
else
ndx = ndx * (1 - AIR_RES_CONSTANT * dt)
platform.dy = 0
end
if not self:isPointOccupied(nx, platform.y, platform) and not self:isPointOccupied(nx + platform.w, platform.y, platform) and not self:isPointOccupied(nx, platform.y + platform.h, platform) and not self:isPointOccupied(nx + platform.w, platform.y + platform.h, platform) then
platform.x, platform.dx = nx, ndx
else
platform.dx = 0
end
end
end
function PlatformSystem:update (dt)
-- Update movable platforms
for _, platform in ipairs(self.platforms) do
if platform.movable then
platform.moved = self:updatePlatform(platform, dt) or self:updatePlatform(platform, dt * 0.5) or self:updatePlatform(platform, dt * 0.25)
end
end
-- Update controllers
for _, controller in ipairs(self.controllers) do
controller:update(dt, self)
end
end
function PlatformSystem:draw (dt, offset_x, offset_y)
local offset_x, offset_y = offset_x or 0, offset_y or 0
for _, platform in ipairs(self.platforms) do
love.graphics.setColor(platform.color)
love.graphics.rectangle('fill', platform.x - offset_y, platform.y - offset_x, platform.w, platform.h)
end
end
--------------------------------------------------------------------------------
return {
PlatformSystem = PlatformSystem,
Player = Player,
}