summaryrefslogtreecommitdiff
path: root/camera.lua
blob: 22be0fc0a7b4f826591bcac06ca8a928475bdff6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
SCREEN = vec2(128, 128)

_chunk_size = vec2(100, 100)
_chunk_size:apply(function (v) assert(v % 2 == 0) end)
_padding = (SCREEN - _chunk_size) / 2
_interpolate_step = 20
assert(_chunk_size.x < SCREEN.x and _chunk_size.y < SCREEN.y)

Camera = {}
Camera.__index = Camera
function Camera:update()
    if self.transition_to ~= self.position then
        delta = (self.transition_to - self.position)
        snap_x = delta.x == 0 or abs(delta.x) < _interpolate_step
        snap_y = delta.y == 0 or abs(delta.y) < _interpolate_step
        if snap_x then 
            self.position.x = self.transition_to.x 
        else
            self.position.x += normalize_scalar(delta.x) * _interpolate_step
        end
        if snap_y then 
            self.position.y = self.transition_to.y 
        else
            self.position.y += normalize_scalar(delta.y) * _interpolate_step
        end
        return
    end

    assert(self.tracking.position)
    tracking_chunk = chunk_from(self.tracking.position)
    self.transition_to = (tracking_chunk * _chunk_size) - _padding
end

function chunk_from(position)
    return vec2(position / _chunk_size):apply(flr)
end

function from_chunk(chunk)
    return chunk * _chunk_size
end

function Camera:render(entity)
    screen_position = (entity.sprite_position or entity.position) - self.position
    entity:render(screen_position)
end

function Camera:new(tracking)
    cam = setmetatable({
        transition_to = from_chunk(chunk_from(tracking.position)),
        tracking = tracking
    }, Camera)
    cam.position = cam.transition_to

    AddUpdateHook(function (dt) cam:update() end)
    return cam
end