Last active
September 9, 2020 12:32
-
-
Save thykka/d6813988ba7a22c2d9cfc6fdef4a5dad to your computer and use it in GitHub Desktop.
SCRIPT-8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "0": { | |
| "0": { | |
| "2": 0 | |
| }, | |
| "1": { | |
| "3": 2 | |
| }, | |
| "tempo": "5" | |
| }, | |
| "1": { | |
| "0": { | |
| "2": "1" | |
| }, | |
| "tempo": "7" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // title: PePuSnek | |
| const { sin, cos, PI } = Math | |
| const ParticleSprites = range(17, 21) | |
| const MaxParticleAge = 32 | |
| init = S => { | |
| S.infoShown = !!S.infoShown | |
| S.gameArea = { | |
| x: 0, | |
| y: 8, | |
| w: 128, | |
| h: 120 | |
| } | |
| S.snek = { | |
| x: S.gameArea.x, | |
| y: S.gameArea.y + S.gameArea.h / 2, | |
| angle: 0, | |
| velocity: 1, | |
| length: 16, | |
| radius: 5.5, | |
| drunk: 0, | |
| burnRate: 2048, | |
| turnSpeed: PI / 25, | |
| tail: [] | |
| } | |
| S.pepu = { | |
| x: 110, | |
| y: 68, | |
| vx: 0, | |
| vy: 0 | |
| } | |
| S.lastAd = -1000 | |
| S.frame = 0 | |
| S.particles = [ | |
| // [x, y, color, vx, vy, birth] | |
| ] | |
| } | |
| update = (S, input, elapsed) => { | |
| S.frame++ | |
| updateSnek(S, input) | |
| } | |
| function updateSnek(S, input) { | |
| updatePepuPos(S) | |
| collideSnek(S) | |
| if (!S.snek.dead) { | |
| controlSnek(S, input) | |
| updateTail(S) | |
| moveSnek(S) | |
| } else { | |
| if (input.start) { | |
| init(S) | |
| } | |
| } | |
| updateParticles(S) | |
| } | |
| function randomizePepuPos(S) { | |
| S.pepu.x = random(S.gameArea.x + 4, S.gameArea.x + S.gameArea.w - 4) | |
| S.pepu.y = random(S.gameArea.y + 4, S.gameArea.y + S.gameArea.h - 4) | |
| S.pepu.vx = (Math.random() * 2 - 1) * Math.pow(S.snek.drunk, 3) | |
| S.pepu.vy = (Math.random() * 2 - 1) * Math.pow(S.snek.drunk, 3) | |
| S.pepu.flipH = Math.random() < 0.5 | |
| } | |
| function createParticles(S, x, y, length = 8) { | |
| S.particles.push( | |
| ...Array.from({ length }, (_, i) => { | |
| return [ | |
| x, | |
| y, | |
| 0, | |
| Math.random() * 3 - 1.5, | |
| Math.random() * -3, | |
| S.frame - Math.random() * 5 | |
| ] | |
| }) | |
| ) | |
| } | |
| function updatePepuPos(S) { | |
| S.pepu.x += S.pepu.vx | |
| S.pepu.y += S.pepu.vy | |
| wrap(S.pepu, S.gameArea) | |
| } | |
| function updateParticles(S) { | |
| S.particles.forEach((p, i) => { | |
| p[4] += 0.2 | |
| p[0] += p[3] | |
| p[1] += p[4] | |
| }) | |
| S.particles = S.particles.filter(p => S.frame - p[5] < MaxParticleAge) | |
| } | |
| function collideSnek(S) { | |
| if (S.snek.dead) return | |
| const distToPepu = distance([S.pepu.x, S.pepu.y], [S.snek.x, S.snek.y]) | |
| if (distToPepu < S.snek.radius) { | |
| playChain(0) | |
| createParticles(S, S.pepu.x, S.pepu.y, 8) | |
| S.lastAd = S.frame | |
| S.snek.length *= 1.05 | |
| S.snek.length += 4 | |
| randomizePepuPos(S) | |
| S.snek.drunk += 1 / 8 | |
| } | |
| const collideTail = S.snek.tail | |
| .slice(0, -S.snek.radius * 2) // ignore tail segments near head | |
| .find( | |
| ([tx, ty]) => distance([tx, ty], [S.snek.x, S.snek.y]) < S.snek.radius | |
| ) | |
| if (collideTail) { | |
| createParticles(S, ...collideTail, 32) | |
| playChain(1) | |
| S.snek.dead = true | |
| } | |
| } | |
| function distance([ax, ay], [bx, by]) { | |
| const dx = ax - bx | |
| const dy = ay - by | |
| return Math.sqrt(dx * dx + dy * dy) | |
| } | |
| function controlSnek(S, input) { | |
| if (input.right || input.b) { | |
| S.infoShown = true | |
| S.snek.angle = (S.snek.angle + S.snek.turnSpeed) % (PI * 2) | |
| } | |
| if (input.left) { | |
| S.infoShown = true | |
| S.snek.angle = (S.snek.angle - S.snek.turnSpeed) % (PI * 2) | |
| } | |
| const drunkOsc1 = Math.cos((S.frame / 60) * PI * 2) * S.snek.drunk | |
| const drunkOsc2 = Math.sin((S.frame / 100) * PI * 2) * S.snek.drunk | |
| const drunkOsc3 = Math.cos((S.frame / 150) * PI * 2 + PI / 2) * S.snek.drunk | |
| S.snek.angle += | |
| S.snek.drunk * | |
| clamp(drunkOsc1 * drunkOsc2 * drunkOsc3, 0 - PI / 90, PI / 90) | |
| S.snek.drunk = clamp(S.snek.drunk - 1 / S.snek.burnRate, 0, 1) | |
| } | |
| function moveSnek(S) { | |
| const { angle, velocity } = S.snek | |
| S.snek.x += | |
| sin(angle + PI / 2) * | |
| (velocity + velocity * Math.sin(S.frame / 30) * 0.3 * S.snek.drunk) | |
| S.snek.y += | |
| -cos(angle + PI / 2) * | |
| (velocity + velocity * Math.cos(-S.frame / 30) * 0.3 * S.snek.drunk) | |
| wrap(S.snek, S.gameArea) | |
| } | |
| function updateTail(S) { | |
| if (S.frame % 1 === 0) { | |
| S.snek.tail.push([S.snek.x, S.snek.y]) | |
| if (S.snek.tail.length > S.snek.length) { | |
| S.snek.tail.shift(0) | |
| } | |
| } | |
| } | |
| function wrap(subject, area) { | |
| if (subject.x < area.x) subject.x += area.w | |
| if (subject.x > area.x + area.w) subject.x -= area.w | |
| if (subject.y < area.y) subject.y += area.h | |
| if (subject.y > area.y + area.h) subject.y -= area.h | |
| } | |
| draw = S => { | |
| const bgColor = S.frame - S.lastAd < 1 ? 4 : 6 | |
| if (S.snek.drunk < 0.9) { | |
| clear(bgColor) | |
| } else { | |
| Math.random() < 1 / 20 && clear(bgColor) | |
| } | |
| drawAd(S) | |
| drawSnek(S) | |
| drawPepu(S) | |
| drawParticles(S) | |
| drawMask(S, 7) | |
| drawUI(S) | |
| } | |
| function drawPepu(S) { | |
| circStroke( | |
| S.pepu.x - (S.pepu.flipH ? 0 : 1), | |
| S.pepu.y, | |
| ((S.frame / 4) % S.snek.radius) * 2, | |
| ((S.frame / 4) % 4) + 2 | |
| ) | |
| sprite(S.pepu.x - 4, S.pepu.y - 4, 16, !(S.frame % 3) ? 0 : 1, S.pepu.flipH) | |
| } | |
| function drawSnek(S) { | |
| let color = 0 | |
| if (S.snek.dead) { | |
| color = 0 - (Math.floor(S.frame / 3) % 6) | |
| } | |
| const tr = 2.25 | |
| const ta = S.snek.angle + PI / 2; | |
| const tx = S.snek.x + Math.sin(ta) * (tr + 4) | |
| const ty = S.snek.y - Math.cos(ta) * (tr + 4) | |
| const t1a = S.snek.angle + PI / 4 | |
| const t1x = tx + Math.sin(t1a) * tr | |
| const t1y = ty - Math.cos(t1a) * tr | |
| const t2a = S.snek.angle + PI / 4 * 3 | |
| const t2x = tx + Math.sin(t2a) * tr | |
| const t2y = ty - Math.cos(t2a) * tr | |
| line(S.snek.x, S.snek.y, tx, ty, 4) | |
| line(tx, ty, t1x, t1y, 4) | |
| line(tx, ty, t2x, t2y, 4) | |
| S.snek.tail.forEach((t, i, tail) => drawTail(t, color, i, tail.length)) | |
| sprite(S.snek.x - 4, S.snek.y - 4, 0, color) | |
| } | |
| const SnekSprites = range(0, 6) | |
| const TailTaper = SnekSprites.length | |
| function drawTail([x, y], color, index, length) { | |
| const spriteIndex = Math.round( | |
| SnekSprites[TailTaper - 1] - | |
| clamp(index / 3, SnekSprites[0], SnekSprites[TailTaper - 1]) | |
| ) | |
| sprite(x - 4, y - 4, spriteIndex, color - (index % 10 <= 1 ? 0 : 3)) | |
| } | |
| function drawMask(S, color = 5) { | |
| S.gameArea.y > 0 && rectFill(0, 0, 128, S.gameArea.y, color) | |
| S.gameArea.x > 0 && rectFill(0, 0, S.gameArea.x, 128, color) | |
| S.gameArea.x + S.gameArea.w < 128 && | |
| rectFill( | |
| S.gameArea.x + S.gameArea.w, | |
| 0, | |
| 128 - (S.gameArea.x + S.gameArea.w), | |
| 128, | |
| color | |
| ) | |
| S.gameArea.y + S.gameArea.h < 128 && | |
| rectFill( | |
| 0, | |
| S.gameArea.y + S.gameArea.h, | |
| 128, | |
| 128 - (S.gameArea.y + S.gameArea.h), | |
| color | |
| ) | |
| } | |
| function drawUI(S) { | |
| const bac = `Drunk: ${(((S.snek.drunk * S.snek.drunk * 60) | 0) / 10).toFixed( | |
| 1 | |
| )}` | |
| print(86, 0, bac, S.snek.dead ? 6 : 0) | |
| sprite(123, 0, 48, S.snek.dead ? -6 : 0) | |
| if (!S.infoShown) { | |
| print(16, 122, 'Move with [Left + Right / B]') | |
| } | |
| if (S.snek.dead) { | |
| const assessment = | |
| S.snek.length > 400 | |
| ? '!! pepu god !!' | |
| : S.snek.length > 256 | |
| ? 'unbelievable!' | |
| : S.snek.length > 192 | |
| ? 'respectable!' | |
| : S.snek.length > 128 | |
| ? 'hey, not bad!' | |
| : S.snek.length > 96 | |
| ? 'one more try!' | |
| : S.snek.length > 64 | |
| ? 'you can do better!' | |
| : S.snek.length > 48 | |
| ? 'whoops!' | |
| : 'how???' | |
| print(45, 48, 'Game over!') | |
| print(27, 92, `Final length: ${S.snek.length | 0}cm`) | |
| print(64 - assessment.length * 1.816, 99, assessment) | |
| print(9, 122, 'Press start/enter to restart', 7) | |
| } | |
| } | |
| function drawParticles(S) { | |
| S.particles.forEach(p => { | |
| const age = (S.frame - p[5]) / MaxParticleAge | |
| const spriteIndex = (age * ParticleSprites.length) | 0 | |
| sprite(p[0] - 3, p[1] - 3, ParticleSprites[spriteIndex], (0 - age * 7) | 0) | |
| }) | |
| } | |
| const letters = { b: 32, u: 33, y: 34, p: 35, e: 36 } | |
| function drawAd(S) { | |
| if (S.frame - S.lastAd < 40) { | |
| ;[...'buy pepu'].forEach((char, i, message) => { | |
| sprite( | |
| 37 + i * 7, | |
| 64, | |
| letters[char], | |
| (-4 + | |
| (7 * | |
| Math.cos(-(S.frame - S.lastAd) / 10 + (i / message.length) * PI) * | |
| 0.5 + | |
| 0.5)) | | |
| 0 | |
| ) | |
| }) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "iframeVersion": "0.1.280", | |
| "lines": [ | |
| 315, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0 | |
| ] | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "0": { | |
| "notes": [ | |
| "0c17", | |
| "1e17", | |
| "2g17", | |
| "3a17", | |
| "4a#17", | |
| "5b17" | |
| ], | |
| "tempo": "6", | |
| "synth": "2" | |
| }, | |
| "1": { | |
| "notes": [ | |
| "0b37", | |
| "1f32", | |
| "2c32", | |
| "3b27", | |
| "4f22", | |
| "5c23", | |
| "6b17", | |
| "7f15", | |
| "8c13", | |
| "9b07", | |
| "10f01", | |
| "11c00" | |
| ], | |
| "tempo": "5", | |
| "synth": "2" | |
| }, | |
| "2": { | |
| "notes": [ | |
| "0b31", | |
| "6b31", | |
| "10b30", | |
| "13b30", | |
| "15b30" | |
| ], | |
| "tempo": "4", | |
| "synth": "1" | |
| }, | |
| "3": { | |
| "notes": [ | |
| "8b32" | |
| ], | |
| "tempo": "4", | |
| "synth": "1" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "0": [ | |
| " ", | |
| " 1001 ", | |
| " 211112 ", | |
| " 222222 ", | |
| " 333333 ", | |
| " 344443 ", | |
| " 4554 ", | |
| " " | |
| ], | |
| "1": [ | |
| " ", | |
| " 00 ", | |
| " 1111 ", | |
| " 222222 ", | |
| " 333333 ", | |
| " 4444 ", | |
| " 55 ", | |
| " " | |
| ], | |
| "2": [ | |
| " ", | |
| " ", | |
| " 1001 ", | |
| " 2222 ", | |
| " 3333 ", | |
| " 4554 ", | |
| " ", | |
| " " | |
| ], | |
| "3": [ | |
| " ", | |
| " ", | |
| " 00 ", | |
| " 2222 ", | |
| " 3443 ", | |
| " 55 ", | |
| " ", | |
| " " | |
| ], | |
| "4": [ | |
| " ", | |
| " ", | |
| " ", | |
| " 02 ", | |
| " 35 ", | |
| " ", | |
| " ", | |
| " " | |
| ], | |
| "5": [ | |
| " ", | |
| " ", | |
| " ", | |
| " 12 ", | |
| " 35 ", | |
| " ", | |
| " ", | |
| " " | |
| ], | |
| "6": [ | |
| " ", | |
| " ", | |
| " ", | |
| " 2 ", | |
| " ", | |
| " ", | |
| " ", | |
| " " | |
| ], | |
| "16": [ | |
| " 12", | |
| " 123", | |
| " 1023 ", | |
| " 1001 ", | |
| " 10014 ", | |
| "12214 ", | |
| "2224 ", | |
| " 24 " | |
| ], | |
| "17": [ | |
| " ", | |
| " 0 ", | |
| " ", | |
| " 0 ", | |
| "0 ", | |
| " ", | |
| " ", | |
| " 0" | |
| ], | |
| "18": [ | |
| " 0 ", | |
| " 0 0", | |
| " 0 0 ", | |
| " 0 0 ", | |
| " 0 ", | |
| " ", | |
| " ", | |
| " " | |
| ], | |
| "19": [ | |
| " 0 ", | |
| " 0 ", | |
| " 0 0 ", | |
| " 0 0 ", | |
| " 0 0 ", | |
| " 0 ", | |
| " ", | |
| " " | |
| ], | |
| "20": [ | |
| " 000 ", | |
| " 0 0 ", | |
| "0 0 ", | |
| "0 0 ", | |
| "0 0 ", | |
| " 0 0 ", | |
| " 000 ", | |
| " " | |
| ], | |
| "21": [ | |
| "0 0 ", | |
| " ", | |
| " ", | |
| " ", | |
| " ", | |
| " ", | |
| "0 0 ", | |
| " " | |
| ], | |
| "32": [ | |
| "00000 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00000 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00000 ", | |
| " " | |
| ], | |
| "33": [ | |
| "00 00 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00 00 ", | |
| " 0000 ", | |
| " " | |
| ], | |
| "34": [ | |
| "00 00 ", | |
| "00 00 ", | |
| "00 00 ", | |
| " 0000 ", | |
| " 00 ", | |
| " 00 ", | |
| " 00 ", | |
| " " | |
| ], | |
| "35": [ | |
| "00000 ", | |
| "00 00 ", | |
| "00 00 ", | |
| "00000 ", | |
| "00 ", | |
| "00 ", | |
| "00 ", | |
| " " | |
| ], | |
| "36": [ | |
| "000000 ", | |
| "00 ", | |
| "00 ", | |
| "00000 ", | |
| "00 ", | |
| "00 ", | |
| "000000 ", | |
| " " | |
| ], | |
| "48": [ | |
| "0 0 ", | |
| " 0 ", | |
| " 0 ", | |
| "0 ", | |
| "0 0 0 ", | |
| " ", | |
| " ", | |
| " " | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment