aboutsummaryrefslogtreecommitdiff
path: root/src/camera.lua
blob: 81f1657c746b1f7d09f6bdc5b897fb46ca7b1348 (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
local DEFAULT_CAMERA_SMOOTHING = 30

local SHAKE_NOISE_SPEED = 15

Cam = {}
Cam.__index = Cam

function Cam.new(x, y)
  local self = setmetatable({}, Cam)

  self.x = x or 0
  self.y = y or 0
  self.realx = self.x
  self.realy = self.y
  self.zoom = 1

  self.smoothing = DEFAULT_CAMERA_SMOOTHING

  self.shake_strength = 0
  self.shake_timer_max = 0
  self.shake_timer = 0

  self.shake_damp = EASING_FUNCTIONS.Lerp
  self.shake_noise = lmath.noise

  return self
end

function Cam:update(dt)
  self.realx = dlerp(self.realx, self.x, self.smoothing * dt)
  self.realy = dlerp(self.realy, self.y, self.smoothing * dt)

  self.shake_timer = self.shake_timer - dt
  if self.shake_timer < 0 then
    self.shake_strength = 0
  end
end

local active_cam = Cam.new()

function get_active_camera()
  return active_cam
end

function Cam:shake(strength, time)
  if strength < self.shake_strength then
    return
  end
  self.noise_seed = lmath.random() * 1000
  self.shake_strength = strength
  self.shake_timer = time
  self.shake_timer_max = time
end

function set_active_camera(new_cam)
  active_cam = new_cam
end

function use_camera_transform()
  local w, h = SCR_WIDTH / 2, SCR_HEIGHT / 2
  lg.scale(active_cam.zoom)
  local ox, oy = -active_cam.realx + w / active_cam.zoom,
                 -active_cam.realy + h / active_cam.zoom

  local shakex, shakey = 0, 0
  if active_cam.shake_timer > 0 then
    shakex = active_cam.shake_noise(
      active_cam.shake_timer * SHAKE_NOISE_SPEED + active_cam.noise_seed)

    shakey = active_cam.shake_noise(
      -- 100 is a magic number to offset the x and y noise (so its not just a diagonal shake)
      active_cam.shake_timer * SHAKE_NOISE_SPEED + active_cam.noise_seed, 100)

    local anim = active_cam.shake_timer / active_cam.shake_timer_max
    local strength = active_cam.shake_strength * active_cam.shake_damp(0, 1, anim)
    shakex = shakex * strength
    shakey = shakey * strength
  end

  lg.translate(
    round(ox + shakex),
    round(oy + shakey))
end