js1k.js 3.23 KB
Newer Older
Evan Hahn's avatar
Evan Hahn committed
1 2 3 4
/*
 * a = canvas
 * b = body
 * c = context
Evan Hahn's avatar
Evan Hahn committed
5
 * d = document (?)
Evan Hahn's avatar
Evan Hahn committed
6
 * e = array of entities (functions that are called)
Evan Hahn's avatar
Evan Hahn committed
7 8
 * f = pressing Left?
 * g = pressing Right?
Evan Hahn's avatar
Evan Hahn committed
9
 * h = pressing Stop?
10 11 12
 * i = used instead of `icon` in a function
 * j = player speed
 * k = player direction
Evan Hahn's avatar
Evan Hahn committed
13
 * l = last tick time
Evan Hahn's avatar
Evan Hahn committed
14 15
 * m = player X
 * n = player Y
Evan Hahn's avatar
Evan Hahn committed
16 17 18
 * q = tick function
 * r = scalar relative to screen size
 * s = ∆t
Evan Hahn's avatar
Evan Hahn committed
19
 * u = item constructor
Evan Hahn's avatar
Evan Hahn committed
20
 * y = stats
21
 * z = scoreboard
Evan Hahn's avatar
Evan Hahn committed
22 23
 */

24
/* eslint-disable no-undef, no-return-assign, no-implied-eval */
Evan Hahn's avatar
Evan Hahn committed
25 26 27

// Initial setup

28 29
c.textAlign = 'center'
c.textBaseline = 'middle'
30
c.font = b.style.font = '3vh sans-serif'
Evan Hahn's avatar
Evan Hahn committed
31
y = [
32
  ['#fd0', '$', 0, 1, 0],
33
  ['#8fd', '>', (r = Math.min(a.width, a.height) / 30) / 4, r / 5, 0],
34
  ['#f64', '+', 1, r / 100, 0],
35
  ['#8f0', '↺', 3, 0.5, 0],
36
  ['#ccc', '⧖', 60, 5, 60]
Evan Hahn's avatar
Evan Hahn committed
37
]
Evan Hahn's avatar
Evan Hahn committed
38

39 40
// The stats element

41
b.appendChild(z = document.createElement('b'))
42
z.style.position = 'absolute'
43
z.style.margin = '1vh'
44 45
z.style.fontSize = '4vh'

Evan Hahn's avatar
Evan Hahn committed
46 47
// The player

48 49
m = a.width / 2
n = a.height / 2
Evan Hahn's avatar
Evan Hahn committed
50
j = k = f = g = h = z.style.top = 0
51 52
onkeydown = event => {
  if (event.keyCode === 32) { h = 1 }
Evan Hahn's avatar
Evan Hahn committed
53 54
  if (event.keyCode === 37) { f = 1 }
  if (event.keyCode === 39) { g = 1 }
55 56 57 58 59
}
onkeyup = event => {
  if (event.keyCode === 32) {
    h = 0
    j += r / 2
Evan Hahn's avatar
Evan Hahn committed
60
  }
Evan Hahn's avatar
Evan Hahn committed
61 62
  if (event.keyCode === 37) { f = 0 }
  if (event.keyCode === 39) { g = 0 }
63
}
Evan Hahn's avatar
Evan Hahn committed
64

65 66 67 68 69 70 71 72 73 74 75 76 77
// Item

u = (type, itemX, itemY, me) => (
  me = _ => {
    [c.fillStyle, i] = y[type]

    c.beginPath()
    c.arc(itemX, itemY, r, 0, 7)
    c.fill()

    c.fillStyle = '#000'
    c.fillText(i, itemX, itemY)

78 79 80 81
    // This checks for distance to the player (taking its size into account)
    if ((((itemX - m) ** 2) +
      ((itemY - n) ** 2)) <
      ((r * y[2][2]) ** 2)) {
82 83 84 85 86 87 88
      y[type][2] += y[type][3]
      y[type][4] += type === 4 ? y[type][3] : 1
      e.splice(e.indexOf(me), 1)
    }
  }
)

Evan Hahn's avatar
Evan Hahn committed
89
// Define the list of entities, starting with a player and a powerup
90

91 92 93 94
e = [
  _ => {
    // y[3][2] === turn speed
    k += ((g * y[3][2]) - (f * y[3][2])) * s
Evan Hahn's avatar
Evan Hahn committed
95

96 97 98 99 100 101 102 103 104 105 106
    if (h) {
      j = Math.max(0, j - 100 * s)
    } else {
      // y[1][2] === top speed
      j = Math.min(y[1][2], j + 3 * s)
    }

    m = (m + (Math.cos(k) * j * r * s)) % a.width
    n = (n + (Math.sin(k) * j * r * s)) % a.height
    if (m < 0) { m += a.width }
    if (n < 0) { n += a.height }
107

108 109 110 111 112 113 114 115 116 117 118 119 120
    c.fillStyle = '#f19'
    c.translate(m, n)
    c.rotate(k)
    c.beginPath()
    // y[2][2] === size
    c.moveTo(-r * y[2][2], -r * y[2][2])
    c.lineTo(r * y[2][2], 0)
    c.lineTo(-r * y[2][2], r * y[2][2])
    c.fill()
    c.setTransform(1, 0, 0, 1, 0, 0)
  },
  u(0, Math.random() * a.width, Math.random() * a.height)
]
Evan Hahn's avatar
Evan Hahn committed
121

Evan Hahn's avatar
Evan Hahn committed
122 123 124 125 126 127 128
// Tick function

l = 0
requestAnimationFrame(q = (currentTime) => {
  s = (l ? currentTime - l : 0) / 1000
  l = currentTime

129 130 131 132 133 134 135
  if (Math.random() < 0.007) {
    e.push(u(
      new Date() % 5,
      Math.random() * a.width,
      Math.random() * a.height
    ))
  }
Evan Hahn's avatar
Evan Hahn committed
136

137 138
  c.fillStyle = '#000'
  c.fillRect(0, 0, a.width, a.height)
Evan Hahn's avatar
Evan Hahn committed
139

Evan Hahn's avatar
Evan Hahn committed
140
  e.map(entity => entity())
Evan Hahn's avatar
Evan Hahn committed
141

142 143
  if (y[4][2] < 0) {
    z.innerHTML = `Game over! Score: ${y[0][2]}¢`
144
  } else {
Evan Hahn's avatar
Evan Hahn committed
145
    z.innerHTML = y.map(stat => (
146
      `<font color=${stat[0]}>${stat[1]} ${stat[4]}`
Evan Hahn's avatar
Evan Hahn committed
147 148
    )).join(' ')

149 150
    requestAnimationFrame(q)
  }
Evan Hahn's avatar
Evan Hahn committed
151
})
Evan Hahn's avatar
Evan Hahn committed
152 153 154

// Less and less time

155
setInterval('y[4][2]--;y[4][4]--', 1000)