Untitled
unknown
plain_text
2 years ago
14 kB
4
Indexable
// ---- // Game // ---- let messageListener = null; function StartGame() { if (messageListener) { window.removeEventListener(messageListener, "message"); } (function () { let gameOver = false; let interval = false; let difficulties = { veryHard: { forceApply: -0.075, instantForce: 0.065, speed: 0.9, }, hard: { forceApply: -0.075, instantForce: 0.065, speed: 0.8, }, medium: { forceApply: -0.08, instantForce: 0.065, speed: 0.7, }, easy: { forceApply: -0.09, instantForce: 0.065, speed: 0.6, }, veryEasy: { forceApply: -0.0975, instantForce: 0.065, speed: 0.5, }, } let difficulty = 'veryEasy' // -------------- // Animation loop // -------------- function animationLoop() { if (!gameOver) { indicator.updatePosition(); indicator.detectCollision(); progressBar.updateUi(); progressBar.detectGameEnd(); fish.updateFishPosition(); requestAnimationFrame(animationLoop); } } // --------- // Indicator // --------- class Indicator { constructor() { this.indicator = document.querySelector(".indicator"); this.height = this.indicator.clientHeight; this.y = 0; this.velocity = 0; this.acceleration = 0; this.topBounds = gameBody.clientHeight * -1 + 48; this.bottomBounds = 0; } applyForce(force) { this.acceleration += force; } updatePosition() { this.velocity += this.acceleration; this.y += this.velocity; // Reset acceleration indicator.acceleration = 0; // Change direction when hitting the bottom + add friction if (this.y > this.bottomBounds) { this.y = 0; this.velocity *= 0.1; this.velocity *= -1; } // Prevent from going beyond the top // Don't apply button forces when beyond the top // console.log(indicator.y, this.topBounds); if (indicator.y < this.topBounds) { indicator.y = this.topBounds; indicator.velocity = 0; } else { if (keyPressed) { indicator.applyForce(difficulties[difficulty].forceApply); } } // // Apply constant force indicator.applyForce(difficulties[difficulty].instantForce); // Update object position this.indicator.style.transform = `translateY(${this.y}px)`; } detectCollision() { if ( (fish.y < this.y && fish.y > this.y - this.height) || (fish.y - fish.height < this.y && fish.y - fish.height > this.y - this.height) ) { progressBar.fill(); document.body.classList.add("collision"); } else { progressBar.drain(); document.body.classList.remove("collision"); } } } // ---- // Fish // ---- class Fish { constructor() { this.fish = document.querySelector(".fish"); this.height = this.fish.clientHeight; this.y = -125; this.direction = null; this.randomPosition = null; this.randomCountdown = null; this.speed = difficulties[difficulty].speed; } resetPosition() { this.y = -125; } updateFishPosition() { if (!this.randomPosition || this.randomCountdown < 0) { this.randomPosition = Math.ceil(Math.random() * (gameBody.clientHeight - this.height)) * -1; this.randomCountdown = Math.abs(this.y - this.randomPosition); this.speed = difficulties[difficulty].speed; } if (this.randomPosition < this.y) { this.y -= this.speed; } else { this.y += this.speed; } this.fish.style.transform = `translateY(${this.y}px)`; this.randomCountdown -= this.speed; } } // ------------ // Progress bar // ------------ class ProgressBar { constructor() { this.wrapper = document.querySelector(".progress-bar"); this.progressBar = this.wrapper.querySelector( ".progress-gradient-wrapper" ); this.progress = 50; } reset() { this.progress = 50; } drain() { if (this.progress > 0) this.progress -= 0.4; if (this.progress < 1) this.progress = 0; } fill() { if (this.progress < 100) this.progress += 0.35; } detectGameEnd() { if (this.progress >= 100) { gameOver = true; $.post( `https://fm-ui/minigamecompleted`, JSON.stringify({ success: true, }) ); resetGame(); } } updateUi() { this.progressBar.style.height = `${this.progress}%`; } } // ----------- // Application // ----------- const gameBody = document.querySelector(".game-body"); let keyPressed = false; const indicator = new Indicator(); const progressBar = new ProgressBar(); const fish = new Fish(); // ------------ // Mouse events // ------------ let events = {}; events["mousedown"] = window.addEventListener("mousedown", indicatorActive); events["mouseup"] = window.addEventListener("mouseup", indicatorInactive); events["keydown"] = window.addEventListener("keydown", indicatorActive); events["keyup"] = window.addEventListener("keyup", indicatorInactive); events["touchstart"] = window.addEventListener( "touchstart", indicatorActive ); events["touchend"] = window.addEventListener("touchend", indicatorInactive); messageListener = window.addEventListener("message", function (event) { let data = event.data; switch (data.type) { case "keydown": indicatorActive(); break; case "keyup": indicatorInactive(); break; case "hide": resetGame(); break; case "SetDifficulty": SetDifficulty(data.val) break default: break; } }); function SetDifficulty(val) { difficulty = val } function indicatorActive() { if (!keyPressed) { keyPressed = true; document.body.classList.add("indicator-active"); } } function indicatorInactive() { if (keyPressed) { keyPressed = false; document.body.classList.remove("indicator-active"); } } // ---------- // Reset game // ---------- const successButton = document.querySelector(".success"); const game = document.querySelector(".game"); events["click"] = successButton.addEventListener("click", resetGame); function resetGame() { progressBar.reset(); fish.resetPosition(); successButton.removeAttribute("style"); game.removeAttribute("style"); document.querySelector("body").style.display = "none"; gameOver = false; for (key in events) { window.removeEventListener(key, events[key]); } clearInterval(interval); events = {}; //animationLoop(); } function StartTimer() { let seconds = 15; if (interval) { clearInterval(interval); interval = false } interval = setInterval(() => { seconds -= 1; if (seconds === 0) { $.post( `https://fm-ui/minigamecompleted`, JSON.stringify({ success: false, }) ); resetGame(); clearInterval(interval); interval = false } }, 1000); } StartTimer(); // ---------------- // Success timeline // ---------------- // ------------- // Initiate loop // ------------- animationLoop(); })(); // ------- // Seaweed // ------- (function () { let seaweed = []; const canvas = document.querySelector('[data-element="seaweed"]'); canvas.width = canvas.clientWidth * 2; canvas.height = canvas.clientHeight * 2; const context = canvas.getContext("2d"); function animationLoop() { clearCanvas(); seaweed.forEach((seaweed) => seaweed.draw()); requestAnimationFrame(animationLoop); } function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); } class Seaweed { constructor(segments, spread, xoff) { this.segments = segments; this.segmentSpread = spread; this.x = 0; this.xoff = xoff; this.y = 0; this.radius = 1; this.sin = Math.random() * 10; } draw() { context.beginPath(); context.strokeStyle = "#143e5a"; context.fillStyle = "#143e5a"; context.lineWidth = 2; for (let i = this.segments; i >= 0; i--) { if (i === this.segments) { context.moveTo( (Math.sin(this.sin + i) * i) / 2.5 + this.xoff, canvas.height + -i * this.segmentSpread ); } else { context.lineTo( (Math.sin(this.sin + i) * i) / 2.5 + this.xoff, canvas.height + -i * this.segmentSpread ); } // context.arc(Math.sin(this.sin + i) * 10 + 30, this.y + (this.segmentSpread * i), this.radius, 0, 2*Math.PI); } context.stroke(); this.sin += 0.05; } } seaweed.push(new Seaweed(6, 8, 25)); seaweed.push(new Seaweed(8, 10, 35)); seaweed.push(new Seaweed(4, 8, 45)); animationLoop(); })(); // ----------------- // Reel line tension // ----------------- (function () { let line = null; const canvas = document.querySelector('[data-element="reel-line-tension"]'); canvas.width = canvas.clientWidth * 2; canvas.height = canvas.clientHeight * 2; const context = canvas.getContext("2d"); function animationLoop() { clearCanvas(); line.draw(); line.animate(); requestAnimationFrame(animationLoop); } function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); } class Line { constructor() { this.tension = 0; this.tensionDirection = "right"; } draw() { context.beginPath(); context.strokeStyle = "#18343d"; context.lineWidth = 1.3; context.moveTo(canvas.width, 0); context.bezierCurveTo( canvas.width, canvas.height / 2 + this.tension, canvas.width / 2, canvas.height + this.tension, 0, canvas.height ); context.stroke(); } animate() { if (document.body.classList.contains("collision")) { if (this.tension > -30) this.tension -= 8; } else { if (this.tension < 0) this.tension += 4; } } } line = new Line(); animationLoop(); })(); // ------- // Bubbles // ------- (function () { let bubbles = {}; let bubblesCreated = 0; const canvas = document.querySelector('[data-element="bubbles"]'); canvas.width = canvas.clientWidth * 2; canvas.height = canvas.clientHeight * 2; const context = canvas.getContext("2d"); function animationLoop() { clearCanvas(); Object.keys(bubbles).forEach((bubble) => bubbles[bubble].draw()); requestAnimationFrame(animationLoop); } function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); } class Bubble { constructor() { this.index = Object.keys(bubbles).length; this.radius = Math.random() * (6 - 2) + 2; this.y = canvas.height + this.radius; this.x = canvas.width * Math.random() - this.radius; this.sin = this.style > 0.5 ? 0 : 5; this.style = Math.random(); this.childAdded = false; this.speed = 1; this.sway = Math.random() * (0.03 - 0.01) + 0.01; this.swayDistance = Math.random() * (canvas.width - canvas.width / 2) + canvas.width / 2; } draw() { context.beginPath(); context.strokeStyle = "#abe2f9"; context.lineWidth = 2; context.arc( this.x + this.radius, this.y + this.radius, this.radius, 0, 2 * Math.PI ); context.stroke(); this.x = Math.sin(this.sin) * this.swayDistance + this.swayDistance - this.radius; this.sin += this.sway; this.y -= this.speed; if (this.y + this.radius < 0) { delete bubbles[this.index]; } if (this.y < canvas.height * 0.6) { if (!this.childAdded) { bubbles[bubblesCreated] = new Bubble(); bubblesCreated++; this.childAdded = true; } } } } bubbles[bubblesCreated] = new Bubble(); bubblesCreated++; })(); } window.addEventListener("message", function (event) { let data = event.data; switch (data.type) { case "OPEN": document.querySelector("body").style.display = "flex"; StartGame(); break; default: break; } });
Editor is loading...