147 lines
4.5 KiB
Lua
147 lines
4.5 KiB
Lua
-- camera.lua :: a basic camera adapted to the asset/world system.
|
|
|
|
--[[
|
|
Copyright © 2019 Kazhnuz
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
]]
|
|
|
|
local CameraSystem = Object:extend()
|
|
|
|
local Vector3D = require "framework.libs.brinevector3D"
|
|
local physicsUtils = require "framework.scenes.world.actors.physics.utils"
|
|
|
|
-- INIT FUNCTIONS
|
|
-- Initialize the camera system
|
|
|
|
function CameraSystem:new(world, def)
|
|
self.world = world
|
|
self.mustFollowPlayer = true
|
|
|
|
def = def or {}
|
|
self.lock = {}
|
|
self:_initView(def.onScreen or {}, def.dimensions or {})
|
|
self:_regenerateCanvas()
|
|
end
|
|
|
|
function CameraSystem:_initView(onScreen, dimensions, target)
|
|
self.onScreen = Vector3D(onScreen.x, onScreen.y, 0)
|
|
local screenw, screenh = core.screen:getDimensions()
|
|
self.dimensions = { w = dimensions.w or screenw, h = dimensions.h or screenh, d = 1 }
|
|
self.position = Vector3D(0, 0, 0)
|
|
self.scale = 1
|
|
end
|
|
|
|
-- SETTER
|
|
-- Set some informations
|
|
|
|
function CameraSystem:lockCoordinates(x, y)
|
|
self.lock.x = x
|
|
self.lock.y = y
|
|
end
|
|
|
|
-- GETTER / COMPUTATION functions
|
|
-- Get some informations computations
|
|
|
|
function CameraSystem:getViewCoordinate()
|
|
local viewDimension = physicsUtils.dimensionsToVector(self.dimensions) / self.scale
|
|
local viewPosition = self.position - (viewDimension / 2)
|
|
return viewPosition, physicsUtils.vectorToDimensions(viewDimension)
|
|
end
|
|
|
|
-- UPDATE and MOVE functions
|
|
-- Move and update the camera system
|
|
|
|
function CameraSystem:update(dt)
|
|
if (self.mustFollowPlayer == true) then
|
|
self:_followPlayer()
|
|
end
|
|
end
|
|
|
|
function CameraSystem:moveView(position)
|
|
self.position = position
|
|
self:_limitView()
|
|
end
|
|
|
|
function CameraSystem:_limitView()
|
|
local worldPosition, worldDimensions = self.world:getBox()
|
|
|
|
local min = worldPosition + (physicsUtils.dimensionsToVector(self.dimensions) / 2)
|
|
local max = worldPosition + physicsUtils.dimensionsToVector(worldDimensions) -
|
|
(physicsUtils.dimensionsToVector(self.dimensions) / 2)
|
|
|
|
self.position.x = utils.math.between(self.position.x, min.x, max.x)
|
|
self.position.y = utils.math.between(self.position.y, min.y, max.y)
|
|
|
|
if (self.lock ~= nil and self.lock.x ~= nil) then
|
|
self.position.x = self.lock.x
|
|
end
|
|
|
|
if (self.lock ~= nil and self.lock.y ~= nil) then
|
|
self.position.y = self.lock.y
|
|
end
|
|
end
|
|
|
|
function CameraSystem:_followPlayer()
|
|
local target = self.world.player
|
|
if (target == nil) then
|
|
return
|
|
end
|
|
|
|
local position = target:getViewCenter()
|
|
position.x = math.floor(position.x)
|
|
position.y = math.floor(position.y)
|
|
self:moveView(position)
|
|
end
|
|
|
|
-- DRAWING FUNCTIONS
|
|
|
|
function CameraSystem:_regenerateCanvas()
|
|
self.canvas = love.graphics.newCanvas(self.dimensions.w, self.dimensions.h)
|
|
end
|
|
|
|
function CameraSystem:attachView()
|
|
self.previousCanvas = love.graphics.getCanvas()
|
|
love.graphics.setCanvas(self.canvas)
|
|
love.graphics.clear()
|
|
|
|
local t = self:getViewCoordinate()
|
|
|
|
love.graphics.push()
|
|
love.graphics.origin()
|
|
love.graphics.translate(math.floor(t.x) * -1, math.floor(t.y) * - 1)
|
|
end
|
|
|
|
function CameraSystem:detachView()
|
|
love.graphics.pop()
|
|
love.graphics.setCanvas(self.previousCanvas)
|
|
|
|
love.graphics.push()
|
|
love.graphics.origin()
|
|
love.graphics.translate(math.floor(self.onScreen.x), math.floor(self.onScreen.y))
|
|
love.graphics.scale(core.screen:getScale() * self.scale, core.screen:getScale() * self.scale)
|
|
|
|
love.graphics.draw(self.canvas)
|
|
|
|
local unscale = 1 / self.scale
|
|
love.graphics.scale(unscale, unscale)
|
|
|
|
love.graphics.pop()
|
|
end
|
|
|
|
return CameraSystem
|