add camera smoothing
This commit is contained in:
commit
9c070e161f
@ -1,36 +1,38 @@
|
|||||||
Camera = {
|
Camera = {
|
||||||
pos = {x = 0, y = 0},
|
pos = Point:new(0, 0),
|
||||||
width = 0,
|
width = 0,
|
||||||
height = 0
|
height = 0,
|
||||||
|
speed = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
function Camera:followPlayer(player)
|
function Camera:followPlayer(player)
|
||||||
local pos = player.pos
|
-- make sure we have the Point metatable self:moveTowards(pos)
|
||||||
|
local pos = Point.copy(player.pos)
|
||||||
local room = player:getCollidingAt(pos.x,pos.y,LoadedObjects.Rooms)
|
local room = player:getCollidingAt(pos.x,pos.y,LoadedObjects.Rooms)
|
||||||
|
|
||||||
self:positionCenterAt(pos.x, pos.y)
|
self:moveTowards(self:confineTo(room, pos))
|
||||||
|
|
||||||
self:confineTo(room)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Camera:confineTo(box)
|
function Camera:confineTo(box, pos)
|
||||||
if box == nil then
|
if box == nil then
|
||||||
--frameDebug("not in a room")
|
--frameDebug("not in a room")
|
||||||
return
|
return pos
|
||||||
end
|
end
|
||||||
--frameDebug("in a room")
|
--frameDebug("in a room")
|
||||||
|
|
||||||
local w = self.width/game.scale
|
local w = self.width/game.scale
|
||||||
local h = self.height/game.scale
|
local h = self.height/game.scale
|
||||||
|
local npos = pos - self:centerOffset()
|
||||||
|
|
||||||
-- bottom edge
|
-- bottom edge
|
||||||
self.pos.y = math.min(self.pos.y+h, box.to.y)-h
|
npos.y = math.min(npos.y+h, box.to.y)-h
|
||||||
-- right edge
|
-- right edge
|
||||||
self.pos.x = math.min(self.pos.x+w, box.to.x)-w
|
npos.x = math.min(npos.x+w, box.to.x)-w
|
||||||
-- top edge
|
-- top edge
|
||||||
self.pos.y = math.max(self.pos.y, box.from.y)
|
npos.y = math.max(npos.y, box.from.y)
|
||||||
-- left edge
|
-- left edge
|
||||||
self.pos.x = math.max(self.pos.x, box.from.x)
|
npos.x = math.max(npos.x, box.from.x)
|
||||||
|
return npos + self:centerOffset()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Camera:confineToLevel()
|
function Camera:confineToLevel()
|
||||||
@ -38,6 +40,32 @@ function Camera:confineToLevel()
|
|||||||
self.pos.y = math.max(0,math.min(self.pos.y,LevelData.Height-self.height/game.scale))
|
self.pos.y = math.max(0,math.min(self.pos.y,LevelData.Height-self.height/game.scale))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Camera:moveTowards(pt)
|
||||||
|
--local pt = Point:new(x,y)
|
||||||
|
local diff = pt - self:center()
|
||||||
|
local dist = diff:abs()
|
||||||
|
local npos
|
||||||
|
if dist < self.speed then
|
||||||
|
npos = pt
|
||||||
|
else
|
||||||
|
frameDebug("camera at speed limit")
|
||||||
|
npos = self:center() + diff * (self.speed/dist)
|
||||||
|
frameDebug("dist = "..dist..", npos = "..tostring(npos))
|
||||||
|
end
|
||||||
|
self:positionCenterAt(npos.x, npos.y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Camera:size()
|
||||||
|
return Point:new(self.width, self.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Camera:centerOffset()
|
||||||
|
return self:size()/game.scale/2
|
||||||
|
end
|
||||||
|
|
||||||
|
function Camera:center()
|
||||||
|
return self.pos + self:centerOffset()
|
||||||
|
end
|
||||||
function Camera:positionCenterAt(x,y)
|
function Camera:positionCenterAt(x,y)
|
||||||
self.pos.x = x-self.width/game.scale/2
|
self.pos.x = x-self.width/game.scale/2
|
||||||
self.pos.y = y-self.height/game.scale/2
|
self.pos.y = y-self.height/game.scale/2
|
||||||
@ -48,3 +76,4 @@ function Camera:positionAt(x,y)
|
|||||||
self.pos.x = math.floor((x/self.width)*self.width)
|
self.pos.x = math.floor((x/self.width)*self.width)
|
||||||
self.pos.y = math.floor((y/self.height)*self.height)
|
self.pos.y = math.floor((y/self.height)*self.height)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
37
code/point.lua
Normal file
37
code/point.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Point = {}
|
||||||
|
Point.__index = Point
|
||||||
|
|
||||||
|
function Point:new(x, y)
|
||||||
|
local o = { x = x or 0, y = y or 0 }
|
||||||
|
setmetatable(o, self)
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:__add(other)
|
||||||
|
return Point:new(self.x+other.x, self.y+other.y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:__sub(other)
|
||||||
|
return Point:new(self.x-other.x, self.y-other.y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:__mul(n)
|
||||||
|
return Point:new(self.x*n, self.y*n)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:__div(n)
|
||||||
|
return Point:new(self.x/n, self.y/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- absolute value, or the distance from the origin
|
||||||
|
function Point:abs()
|
||||||
|
return math.sqrt(self.x ^ 2 + self.y ^ 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:__tostring()
|
||||||
|
return "("..self.x..","..self.y..")"
|
||||||
|
end
|
||||||
|
|
||||||
|
function Point:copy()
|
||||||
|
return Point:new(self.x, self.y)
|
||||||
|
end
|
@ -13,6 +13,7 @@ require "code/hex"
|
|||||||
require "code/in_out"
|
require "code/in_out"
|
||||||
|
|
||||||
-- classes
|
-- classes
|
||||||
|
require "code/point"
|
||||||
require "code/objects"
|
require "code/objects"
|
||||||
require "code/level"
|
require "code/level"
|
||||||
require "code/camera"
|
require "code/camera"
|
||||||
|
Loading…
Reference in New Issue
Block a user