local DEFAULT_PLATFORM_COLOR = {255,255,255} local GRAVITY_CONSTANT = 300 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 ) then self.target.dy = self.target.dy + (not_jumping and -260 or (-280 * dt)) end if love.keyboard.isDown( self.controls.left ) then self.target.dx = self.target.dx - 15 end if 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, }