diff options
author | Aki <nthirtyone@gmail.com> | 2017-09-21 21:05:37 +0200 |
---|---|---|
committer | Aki <nthirtyone@gmail.com> | 2017-09-21 21:05:37 +0200 |
commit | e9a450d65d4fb564691cdf651ef5771dd88303ae (patch) | |
tree | f49d29582dd6877f3b3c807c3f7d9d92d368f798 /not/Camera.lua | |
parent | eb8302723cd85adca0fbaf505cfb315f1db0299a (diff) | |
parent | b97985def64b8bd8f93a7b391b12333595432e52 (diff) | |
download | roflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.zip roflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.tar.gz roflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.tar.bz2 |
Merge branch 'maps'
Diffstat (limited to 'not/Camera.lua')
-rw-r--r-- | not/Camera.lua | 221 |
1 files changed, 107 insertions, 114 deletions
diff --git a/not/Camera.lua b/not/Camera.lua index aa4df5b..65395cb 100644 --- a/not/Camera.lua +++ b/not/Camera.lua @@ -1,37 +1,46 @@ ---- `Camera` --- Used in drawing. -Camera = { - x = 0, - y = 0, - dest_x = 0, - dest_y = 0, - shake = 0, - timer = 0, - delay = 0, - origin_x = 0, - origin_y = 0, - shake_x = 0, - shake_y = 0, - world = --[[not.World]]nil, -} - --- Constructor of `Camera` -function Camera:new (world) - local o = {} - setmetatable(o, self) - self.__index = self - o.world = world - o:setPosition(o:follow()) - o:setDestination(o:follow()) - return o -end - --- Drawing offsets -function Camera:getOffsets () - return -self.x,-self.y -end - --- Position +--- Used in drawing other stuff in places. +-- TODO: Camera is missing documentation on every important method. +Camera = require "not.Object":extends() + +Camera.SHAKE_LENGTH = 0.6 +Camera.SHAKE_INTERVAL = 0.03 + +-- TODO: Camera would really make use of vec2s (other classes would use them too). +function Camera:new (x, y, world) + self.world = world + self:setPosition(x, y) + self:resetSum() + self:initShake() +end + +function Camera:initShake () + self.shakeTime = 0 + self.shakeInterval = 0 + self.shakeShift = { + theta = love.math.random() * 2, + radius = 0 + } +end + +function Camera:push () + love.graphics.push() +end + +function Camera:transform (scale, ratio, vw, vh) + local px, py = self:getPosition() + local sx, sy = self:getShake() + local dx, dy = (px + sx) * ratio, (py + sy) * ratio + + vw, vh = vw / scale / 2, vh / scale / 2 + + love.graphics.scale(scale, scale) + love.graphics.translate(vw - dx, vh - dy) +end + +function Camera:pop () + love.graphics.pop() +end + function Camera:setPosition (x, y) local x = x or 0 local y = y or 0 @@ -42,102 +51,86 @@ function Camera:getPosition () return self.x, self.y end -function Camera:getPositionScaled () - return self.x*getScale(), self.y*getScale() -end - --- Destination -function Camera:setDestination (x, y) - local x = x or 0 - local y = y or 0 - self.dest_x, self.dest_y = x, y +function Camera:getBoundaries (scale, vw, vh) + local x, y = self:getPosition() + local width, height = vw / scale / 2, vh / scale / 2 + return x - width, y - height, x + width, y + height end -function Camera:getDestination () - return self.dest_x, self.dest_y +function Camera:startShake () + self.shakeTime = Camera.SHAKE_LENGTH end --- Translate points -function Camera:translatePosition (x, y) - local x = x or 0 - local y = y or 0 - return (x-self.x)*getScale(), (y-self.y)*getScale() +local +function limit (theta) + if theta > 2 then + return limitAngle(theta - 2) + end + if theta < 0 then + return limitAngle(theta + 2) + end + return theta end -function Camera:translatePoints(...) - local a = {...} - local r = {} - local x,y = self:getOffsets() - for k,v in pairs(a) do - if k%2 == 1 then - table.insert(r, (v + x) * getScale()) +-- TODO: Magic numbers present in Camera's shake. +function Camera:shake (dt) + if self.shakeTime > 0 then + self.shakeTime = self.shakeTime - dt + if self.shakeInterval < 0 then + self.shakeShift.theta = self.shakeShift.theta - 1.3 + love.math.random() * 0.6 + self.shakeShift.radius = 50 * self.shakeTime + self.shakeInterval = Camera.SHAKE_INTERVAL else - table.insert(r, (v + y) * getScale()) + self.shakeShift.radius = self.shakeShift.radius * 0.66 + self.shakeInterval = self.shakeInterval - dt + end + if self.shakeTime < 0 then + self.shakeShift.radius = 0 end end - return r -end - --- Shake it --- Really bad script, but for now it works -function Camera:shake () - if self.shake_x == 0 then - self.shake_x = math.random(-10, 10) * 2 - elseif self.shake_x > 0 then - self.shake_x = math.random(-10, -1) * 2 - elseif self.shake_x < 0 then - self.shake_x = math.random(10, 1) * 2 - end - if self.shake_y == 0 then - self.shake_y = math.random(-10, 10) * 2 - elseif self.shake_y > 0 then - self.shake_y = math.random(-10, -1) * 2 - elseif self.shake_y < 0 then - self.shake_y = math.random(10, 1) * 2 - end - local x = self.origin_x + self.shake_x - local y = self.origin_y + self.shake_y - self:setDestination(x, y) end -function Camera:startShake () - self.timer = 0.3 - self.origin_x, self.origin_y = self:getPosition() +function Camera:getShake () + local radius = self.shakeShift.radius + local theta = self.shakeShift.theta * math.pi + return radius * math.cos(theta), radius * math.sin(theta) end --- Move follow -function Camera:follow () +function Camera:resetSum () + self.sumX = 0 + self.sumY = 0 + self.sumI = 0 +end + +function Camera:sum (x, y) local map = self.world.map - local sum_x,sum_y,i = map.center_x, map.center_y, 1 - for k,naut in pairs(self.world.Nauts) do - local naut_x,naut_y = naut:getPosition() - if math.abs(naut_x - map.center_x) < map.width/2 and - math.abs(naut_y - map.center_y) < map.height/2 then - i = i + 1 - sum_x = naut_x + sum_x - sum_y = naut_y + sum_y - end + if math.abs(x - map.center.x) < map.width/2 and + math.abs(y - map.center.y) < map.height/2 then + self.sumX = self.sumX + x + self.sumY = self.sumY + y + self.sumI = self.sumI + 1 end - local x = sum_x / i - love.graphics.getWidth()/getScale()/2 - local y = sum_y / i - love.graphics.getHeight()/getScale()/2 + 4*getScale() -- hotfix - return x,y end --- Update -function Camera:update (dt) - if self.timer > 0 then - self.timer = self.timer - dt - if self.delay <= 0 then - self:shake() - self.delay = 0.02 - else - self.delay = self.delay - dt - end - else - self:setDestination(self:follow()) +function Camera:getSumPostion () + if self.sumI > 0 then + return self.sumX / self.sumI, self.sumY / self.sumI end - local dx, dy = self:getDestination() - dx = (dx - self.x) * 6 * dt - dy = (dy - self.y) * 6 * dt - self:setPosition(self.x + dx, self.y + dy) + return 0, 0 +end + +function Camera:step (dt) + local x, y = self:getSumPostion() + local dx, dy = (x - self.x), (y - self.y) + if math.abs(dx) > 0.4 or math.abs(dy) > 0.4 then + x = self.x + (x - self.x) * dt * 6 + y = self.y + (y - self.y) * dt * 6 + end + self:setPosition(x, y) +end + +function Camera:update (dt) + self:step(dt) + self:shake(dt) + self:resetSum() end |