<!doctype html> <html lang="en"> <head> <title>OinkPop</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div class="intro"> <h1>tap to gobble</h1> </div> <div class="play"> <div class="score"> 0 yums<br>0 seconds </div> <div class="controls"> <button class="up"></button> <button class="right"></button> <button class="down"></button> <button class="left"></button> </div> <div class="oink"></div> </div> <div class="outro"> <h1>you gobbled 0 yums in 0 seconds</h1> </div> </body> </html>
<!doctype html> <html lang="en"> <head> <title>OinkPop</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div class="intro"> <h1>tap to gobble</h1> </div> <div class="play"> <div class="score"> 0 yums<br>0 seconds </div> <div class="controls"> <button class="up"></button> <button class="right"></button> <button class="down"></button> <button class="left"></button> </div> <div class="oink"></div> </div> <div class="outro"> <h1>you gobbled 0 yums in 0 seconds</h1> </div> </body> </html>
<style> @font-face { font-family: PixelRPG; src: url('data:font/sfnt;base64,AAEAAAAOAIAAAwB...'); } html, body { width: 100%; height: 100%; overflow: hidden; } body { font-family: PixelRPG; background-color: #9ae6b4; cursor: default; } /*...*/ </style>
<style> @font-face { font-family: PixelRPG; src: url('data:font/sfnt;base64,AAEAAAAOAIAAAwB...'); } html, body { width: 100%; height: 100%; overflow: hidden; } body { font-family: PixelRPG; background-color: #9ae6b4; cursor: default; } /*...*/ </style>
#!/bin/sh if [ -z "$1" ]; then echo "usage: data-url file" >&2 exit 1 fi mimetype=$(file -bN --mime-type "$1") content=$(base64 < "$1") echo "data:$mimetype;base64,$content" # -> saved in /usr/local/bin/data-uri
#!/bin/sh if [ -z "$1" ]; then echo "usage: data-url file" >&2 exit 1 fi mimetype=$(file -bN --mime-type "$1") content=$(base64 < "$1") echo "data:$mimetype;base64,$content" # -> saved in /usr/local/bin/data-uri
#!/bin/sh if [ -z "$1" ]; then echo "usage: data-url file" >&2 exit 1 fi mimetype=$(file -bN --mime-type "$1") content=$(base64 < "$1") echo "data:$mimetype;base64,$content" # -> saved in /usr/local/bin/data-uri
var music = "data:audio/mpeg;base64,SUQzBAAAAAAA..." var biteSounds = [ "data:audio/mpeg;base64,SUQzBAAAAAAA...", "data:audio/mpeg;base64,SUQzBAAAAAAA...", "data:audio/mpeg;base64,SUQzBAAAAAAA...", "data:audio/mpeg;base64,SUQzBAAAAAAA...", ] var popSound = "data:audio/mpeg;base64,SUQzBAAAAAAAI..." var arrowFrames = [ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", ] // ...
var shouldGoUp = false var shouldGoRight = false var shouldGoLeft = false var shouldGoDown = false var facingScale = 1 document.addEventListener("keydown", function(event) { if (event.key === "ArrowUp") { shouldGoUp = true } if (event.key === "ArrowRight") { shouldGoRight = true if (!isEating) { facingScale = -1 } } if (event.key === "ArrowLeft") { shouldGoLeft = true if (!isEating) { facingScale = 1 } } // ... })
var shouldGoUp = false var shouldGoRight = false var shouldGoLeft = false var shouldGoDown = false var facingScale = 1 document.addEventListener("keydown", function(event) { if (event.key === "ArrowUp") { shouldGoUp = true } if (event.key === "ArrowRight") { shouldGoRight = true if (!isEating) { facingScale = -1 } } if (event.key === "ArrowLeft") { shouldGoLeft = true if (!isEating) { facingScale = 1 } } // ... })
var shouldGoUp = false var shouldGoRight = false var shouldGoLeft = false var shouldGoDown = false var facingScale = 1 document.addEventListener("keydown", function(event) { if (event.key === "ArrowUp") { shouldGoUp = true } if (event.key === "ArrowRight") { shouldGoRight = true if (!isEating) { facingScale = -1 } } if (event.key === "ArrowLeft") { shouldGoLeft = true if (!isEating) { facingScale = 1 } } // ... })
document.addEventListener("mousedown", function(event) { if (event.target.matches(".controls .up")) { shouldGoUp = true } if (event.target.matches(".controls .right")) { shouldGoRight = true if (!isEating) { facingScale = -1 } } if (event.target.matches(".controls .down")) { shouldGoDown = true } if (event.target.matches(".controls .left")) { shouldGoLeft = true if (!isEating) { facingScale = 1 } } if (event.target.matches(".intro")) { startPlaying() } })
document.addEventListener("mousedown", function(event) { if (event.target.matches(".controls .up")) { shouldGoUp = true } if (event.target.matches(".controls .right")) { shouldGoRight = true if (!isEating) { facingScale = -1 } } if (event.target.matches(".controls .down")) { shouldGoDown = true } if (event.target.matches(".controls .left")) { shouldGoLeft = true if (!isEating) { facingScale = 1 } } if (event.target.matches(".intro")) { startPlaying() } })
var isPlaying = false var intro = document.querySelector(".intro") var play = document.querySelector(".play") var startPlaying = function() { if (isPlaying) { return } isPlaying = true intro.style.display = "none" play.style.display = "flex" reset() animate() playMusic() setTimeout(spawnYum, yumBreather) secondsTimer = setInterval(function() { secondsPlayed += 1 }, 1000) }
var isPlaying = false var intro = document.querySelector(".intro") var play = document.querySelector(".play") var startPlaying = function() { if (isPlaying) { return } isPlaying = true intro.style.display = "none" play.style.display = "flex" reset() animate() playMusic() setTimeout(spawnYum, yumBreather) secondsTimer = setInterval(function() { secondsPlayed += 1 }, 1000) }
var isPlaying = false var intro = document.querySelector(".intro") var play = document.querySelector(".play") var startPlaying = function() { if (isPlaying) { return } isPlaying = true intro.style.display = "none" play.style.display = "flex" reset() animate() playMusic() setTimeout(spawnYum, yumBreather) secondsTimer = setInterval(function() { secondsPlayed += 1 }, 1000) }
var yum = undefined var yumTimeout = undefined var yumExpiry = 5000 var yumBreather = 1500 var spawnYum = function() { yum = document.createElement('div') yum.className = 'yum' yum.style.backgroundImage = `url('${yumFrame}')` yum.style.top = `${Math.round(play.offsetHeight * Math.random())}px` yum.style.left = `${Math.round(play.offsetWidth * Math.random())}px` play.appendChild(yum) yumTimeout = setTimeout(function() { play.removeChild(yum) yum = undefined setTimeout(function() { spawnYum() }, yumBreather) }, yumExpiry) }
var yum = undefined var yumTimeout = undefined var yumExpiry = 5000 var yumBreather = 1500 var spawnYum = function() { yum = document.createElement('div') yum.className = 'yum' yum.style.backgroundImage = `url('${yumFrame}')` yum.style.top = `${Math.round(play.offsetHeight * Math.random())}px` yum.style.left = `${Math.round(play.offsetWidth * Math.random())}px` play.appendChild(yum) yumTimeout = setTimeout(function() { play.removeChild(yum) yum = undefined setTimeout(function() { spawnYum() }, yumBreather) }, yumExpiry) }
var animationFrame = undefined var animate = function(timestamp) { animateOinkRunning(timestamp) animateOinkMoving(timestamp) animateOinkWrapping(timestamp) animateOinkFacing(timestamp) animateControls(timestamp) var shouldStopGame = animateCollisions(timestamp) animateScore(timestamp) if (!shouldStopGame) { animationFrame = requestAnimationFrame(animate) } }
var animationFrame = undefined var animate = function(timestamp) { animateOinkRunning(timestamp) animateOinkMoving(timestamp) animateOinkWrapping(timestamp) animateOinkFacing(timestamp) animateControls(timestamp) var shouldStopGame = animateCollisions(timestamp) animateScore(timestamp) if (!shouldStopGame) { animationFrame = requestAnimationFrame(animate) } }
var previousTimestamp = undefined var previousFrame = 0 var animateOinkRunning = function(timestamp) { if (isEating) { return } if (shouldGoUp || shouldGoRight || shouldGoDown || shouldGoLeft) { if (previousTimestamp === undefined) { previousTimestamp = timestamp } var elapsed = timestamp - previousTimestamp if (elapsed >= 120) { previousTimestamp = undefined var nextFrame = previousFrame + 1 if (nextFrame > 2) { nextFrame = 0 } oink.style.backgroundImage = `url('${oinkFrames[nextFrame]}')` previousFrame = nextFrame } } else { previousFrame = 0 oink.style.backgroundImage = `url('${oinkFrames[0]}')` } }
var previousTimestamp = undefined var previousFrame = 0 var animateOinkRunning = function(timestamp) { if (isEating) { return } if (shouldGoUp || shouldGoRight || shouldGoDown || shouldGoLeft) { if (previousTimestamp === undefined) { previousTimestamp = timestamp } var elapsed = timestamp - previousTimestamp if (elapsed >= 120) { previousTimestamp = undefined var nextFrame = previousFrame + 1 if (nextFrame > 2) { nextFrame = 0 } oink.style.backgroundImage = `url('${oinkFrames[nextFrame]}')` previousFrame = nextFrame } } else { previousFrame = 0 oink.style.backgroundImage = `url('${oinkFrames[0]}')` } }
var speed = 5 var oinkScale = 1 var oink = document.querySelector(".oink") var animateOinkMoving = function(timestamp) { if (isEating) { return } if (shouldGoUp) { oink.style.top = `${oink.offsetTop - speed}px` } if (shouldGoRight) { oink.style.left = `${oink.offsetLeft + speed}px` } if (shouldGoDown) { oink.style.top = `${oink.offsetTop + speed}px` } if (shouldGoLeft) { oink.style.left = `${oink.offsetLeft - speed}px` } } var animateOinkFacing = function(timestamp) { oink.style.transform = `scaleY(${oinkScale}) scaleX(${facingScale * oinkScale})`; }
var speed = 5 var oinkScale = 1 var oink = document.querySelector(".oink") var animateOinkMoving = function(timestamp) { if (isEating) { return } if (shouldGoUp) { oink.style.top = `${oink.offsetTop - speed}px` } if (shouldGoRight) { oink.style.left = `${oink.offsetLeft + speed}px` } if (shouldGoDown) { oink.style.top = `${oink.offsetTop + speed}px` } if (shouldGoLeft) { oink.style.left = `${oink.offsetLeft - speed}px` } } var animateOinkFacing = function(timestamp) { oink.style.transform = `scaleY(${oinkScale}) scaleX(${facingScale * oinkScale})`; }
var controls = document.querySelector(".controls") var animateControls = function(timestamp) { controls.style.backgroundImage = `url('${arrowFrames[0]}')` if (shouldGoUp) { controls.style.backgroundImage = `url('${arrowFrames[1]}')` } if (shouldGoRight) { controls.style.backgroundImage = `url('${arrowFrames[2]}')` } if (shouldGoDown) { controls.style.backgroundImage = `url('${arrowFrames[3]}')` } if (shouldGoLeft) { controls.style.backgroundImage = `url('${arrowFrames[4]}')` } } var yumsEaten = 0 var secondsPlayed = 0 var animateScore = function(timestamp) { score1.innerHTML = `${yumsEaten} yums<br>${secondsPlayed} seconds` score2.innerHTML = `you gobbled ${yumsEaten} yums in ${secondsPlayed} seconds` }
var controls = document.querySelector(".controls") var animateControls = function(timestamp) { controls.style.backgroundImage = `url('${arrowFrames[0]}')` if (shouldGoUp) { controls.style.backgroundImage = `url('${arrowFrames[1]}')` } if (shouldGoRight) { controls.style.backgroundImage = `url('${arrowFrames[2]}')` } if (shouldGoDown) { controls.style.backgroundImage = `url('${arrowFrames[3]}')` } if (shouldGoLeft) { controls.style.backgroundImage = `url('${arrowFrames[4]}')` } } var yumsEaten = 0 var secondsPlayed = 0 var animateScore = function(timestamp) { score1.innerHTML = `${yumsEaten} yums<br>${secondsPlayed} seconds` score2.innerHTML = `you gobbled ${yumsEaten} yums in ${secondsPlayed} seconds` }
var oinkWidth = oink.offsetWidth var oinkHeight = oink.offsetHeight var animateOinkWrapping = function(timestamp) { if (oink.offsetTop < 0) { oink.style.top = `${play.offsetHeight - oinkHeight}px` } if (oink.offsetLeft + oinkWidth > play.offsetWidth) { oink.style.left = 0 } if (oink.offsetTop + oinkHeight > play.offsetHeight) { oink.style.top = 0 } if (oink.offsetLeft < 0) { oink.style.left = `${play.offsetWidth - oinkWidth}px` } }
var yumsEatenLimit = 10 var animateCollisions = function(timestamp) { if (!yum) { return } var oinkBox = oink.getBoundingClientRect() var yumBox = yum.getBoundingClientRect() if ( oinkBox.left < yumBox.right && oinkBox.right > yumBox.left && oinkBox.top < yumBox.bottom && oinkBox.bottom > yumBox.top ) { // ...oink collides with yum! (next slide) } }
yumsEaten += 1 playBiteSound() oinkScale *= 1.1 isEating = true oink.style.backgroundImage = `url('${oinkFrames[3]}')` if (yumsEaten === yumsEatenLimit) { // ...stop the game! (next slide) } removeYum() setTimeout(function() { isEating = false }, yumPause) return false
cancelAnimationFrame(animationFrame) removeYum(true) setTimeout(function() { oink.style.display = "none" stopMusic() playPopSound() setTimeout(function() { play.style.display = "none" outro.style.display = "flex" isPlaying = false setTimeout(function() { outro.style.display = "none" intro.style.display = "flex" }, 5000) }, 2500) }, 1500) clearTimeout(secondsTimer) return true
var musicPlayer = undefined var biteSoundPlayer = undefined var playMusic = function() { if (!musicPlayer) { musicPlayer = new Audio() musicPlayer.addEventListener("ended", function() { this.currentTime = 0 this.play() }) } musicPlayer.src = music musicPlayer.play() } var stopMusic = function() { musicPlayer.pause() } var playBiteSound = function() { biteSounds = shuffle(biteSounds) if (!biteSoundPlayer) { biteSoundPlayer = new Audio() } biteSoundPlayer.src = biteSounds[0] biteSoundPlayer.play() }
var musicPlayer = undefined var biteSoundPlayer = undefined var playMusic = function() { if (!musicPlayer) { musicPlayer = new Audio() musicPlayer.addEventListener("ended", function() { this.currentTime = 0 this.play() }) } musicPlayer.src = music musicPlayer.play() } var stopMusic = function() { musicPlayer.pause() } var playBiteSound = function() { biteSounds = shuffle(biteSounds) if (!biteSoundPlayer) { biteSoundPlayer = new Audio() } biteSoundPlayer.src = biteSounds[0] biteSoundPlayer.play() }
var musicPlayer = undefined var biteSoundPlayer = undefined var playMusic = function() { if (!musicPlayer) { musicPlayer = new Audio() musicPlayer.addEventListener("ended", function() { this.currentTime = 0 this.play() }) } musicPlayer.src = music musicPlayer.play() } var stopMusic = function() { musicPlayer.pause() } var playBiteSound = function() { biteSounds = shuffle(biteSounds) if (!biteSoundPlayer) { biteSoundPlayer = new Audio() } biteSoundPlayer.src = biteSounds[0] biteSoundPlayer.play() }
Particles
Collision detection
Animation
Cross-platform
Loads more...
Heartbeast
GDQuest
Game Development Center
Game Endeavor
Use Pixaki for pixel art on mobile
kenney.nl
onemansymphony.com
opengameart.org
unsplash.com
undraw.co
notion.so
excalidraw.com
OinkPop (made in Godot)
published to iOS
OinkPop (made in Scratch)
published to iOS using Capacitor
sheeptester.github.io/htmlifier
Snake Catcher (made in Godot)
published to iOS and Android
Slither Deep (made in Godot)
published to iOS, Android, Windows, Linux, macOS
Sprout (making in Godot)
OinkPop (making in JS)
publishing to iOS using Capacitor