From 5a4e7cc85f9971bd48ee3097384f3b8054486af1 Mon Sep 17 00:00:00 2001 From: Sharkiller Date: Tue, 13 Feb 2024 21:05:27 -0300 Subject: [PATCH] Add Laundromat minigame --- nopixel_minigame/4.0/index.html | 1 + nopixel_minigame/4.0/laundromat/favicon.ico | Bin 0 -> 15406 bytes nopixel_minigame/4.0/laundromat/index.html | 69 +++++ nopixel_minigame/4.0/laundromat/minigame.css | 158 ++++++++++ nopixel_minigame/4.0/laundromat/minigame.js | 292 +++++++++++++++++++ nopixel_minigame/4.0/roof_running/index.html | 1 + 6 files changed, 521 insertions(+) create mode 100644 nopixel_minigame/4.0/laundromat/favicon.ico create mode 100644 nopixel_minigame/4.0/laundromat/index.html create mode 100644 nopixel_minigame/4.0/laundromat/minigame.css create mode 100644 nopixel_minigame/4.0/laundromat/minigame.js diff --git a/nopixel_minigame/4.0/index.html b/nopixel_minigame/4.0/index.html index 53a4856..1c8fa4b 100644 --- a/nopixel_minigame/4.0/index.html +++ b/nopixel_minigame/4.0/index.html @@ -40,6 +40,7 @@
+ Laundromat Minigame
Roof Running Minigame

NoPixel 3.0 Minigames

Whisper me on Twitch @Sh4rkill3r or Discord sharkiller
diff --git a/nopixel_minigame/4.0/laundromat/favicon.ico b/nopixel_minigame/4.0/laundromat/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..46c085c078feae53d269dfeb0c5a827edecff437 GIT binary patch literal 15406 zcmeI3f3Q_m6~~uphDM4SnPv4VD@-${jHIF=!%}pzoNNpZ@45Fp_dA?(?m73qC;q{m z+3)PL_g-s#*V^l>{qvcfWGCB@A;z=8Zau|pgqbxol;4M)Wj2Sh;lnHS?>Ad9)NB}S zAc3M>&Li=c@3N2P3idnF?tIZ^EG^i(5(z4mjYaz$H0{uMq12r(*<-nqU6jNpU$DPQ z9_dhsKH%4uNME$P>X+=dvzkhFH~ea;r-dG;pCefa?o-e-l{E)Ts2dg-~1)Ev<237&`D_CN6KbuFEC z8RdVVyvMC0-$`n5>3N^+wsGs4i*}n^N4^ujt!^9o>^E*3w~l`Px?2}TPn$Vz80H)4OD!v2Co-vhr#)sFsoC*@N~zs_~pM^vWYYW&P;@Ao^tBtO5uwP^1t zw|eETd>H%Rg{=AX%awDt*dT{~2jzD!@r*A%`Pb#w}}fqJ2jcAwpzuR z2GVGf;#1aN&a?B-YYKX92k%Pa#kh9Qh-d@*TUxRYA!{ynE;%+Xf13r{O8Fh&7~J0| zkaY#Tb3Bh8BR3pFOSV_G0mobG#o@>4qOGkeGmN49UIg>QxdV1~tvHaok@OGJmKrg5 z^8Z@pgI{tVly5b6+E;mhE;Ejj-BYi8mmUmbNa=h*{SYC)wPYWJ$JKn_r@6etdD?6t z&iyJ}u6M@GOR&Y`Rqf%(mp{SJ#lDm8_j|3Lof9QP@=1~M)xNpQhF6teupi+A6R<

hwWqHPr1hWSoxZN1+@MBq+jNM zXFKVa!V>ip&Lp|`$aT~&OKKBWhupo??I6vFlC3iAKO&A^<-wSc>$DN*vyigzT&Nto zqvBV|pHI95%`f8Q`(u0*ZKaIw>tvS}|9>z19wZ$m#miP*S^mx>`Ayw6GKr5X+s(Hh zv^PWd&m`K4{9W|JbeGo6qyHz9c(`rDdA`Y~lW2YUCEJrEzqz{(`Nb6SnNuQvS{Qrq z&V2q;Nje1WqMm%`&m__M`d5+P(p|fJ?4Pv8DEps$uw*}v!ml!P7?q?$9G%MH`?(%#I;d5daX*5kKOk&CaCdT=j zv@S~G7p_}ej&W0k$E|C8+0KCPox+zSAAB1d57|(jKPJf!w}EN0=v{tsd4D}sj^ib4 zI8S>CP3868{zSRuJ&l?9PJ2hdTWeEjZYOCzvL75jYxeAIL4DM7v1g}OkrVd49mu>( z>&Ym7D${sM-`)VZb(# zk0LX#`KU`%OTMYYE@4ghD6+cf=atyxdX4*0@+&r*t8cXySxGeb+xggG8vP@`-VBcK z1o|U)FXdAf9ZvR{B>rjZ{LUTAKWk2zE?-phs&_b z5ZXQo|194{kLK-*JMHZ}$3d%ei8S;j`uhpSr%yb?Ih^zk;|cKN8)L(DQSbg3U1Xd~ zCqKY=1izT=k7=w`GSYh3OM8}o0_!)IcJw`45>N4?&6QDj!)5-NCA_j?pncuriu54; zOKaWW+<`gQnoRiVN7~ndKj@2oc~)ZLRRMnD&*#Ioj(XRb9JEU^*uRa~5_i|4UR~DE zA8Umr?Rq>b{>oXq&QP^qP%qvvz4nE)Po?rJqU;?m6Mot*O^aodvmQ_!f$mAZxt+w7 zn&#&rxtZ~|9<+1dk=m9E*Y&+eK>Qt)@3v24H_cBpj?|-v&d9XS;5D-+6t;ELd%gGr zo{Wd5HhI>ddp&$lTH}R%BhC9(`cdcHp7yi?-bqj4$9B22@}kC^Fn{`FFtPnUcxGLL z^y0@SFAwvLdavxwHmAiO#UrXr^5NO%E>{W}@}JFWhyI_5;u|g-DE#VwFzil&+4U=Z zznU9o!jGJmv~t4w$Gz8!ANtX8yxnqqRp*zl8T??`Dq9|J{P@9`TKuOL{KzV=`O#at zCndM7r*W^xcuVsi(j(S@zpz+69@CYNZf&baeTt%HRCVXcFAHMGBV6F z?p<>i?V0i&e2bW|DZm=_jN=h5hxRJ^RcED%_6XI>cQWI5Wor)v9^a-vo@Xv~5S{w0 z6Wz8+dF(&79{jpzl*GSU9rs$#W)6EJy6CP_?;dtFx}YAt$D)5N_V?$m>~mil@T&RA z{zi*uXSV5XT*)3mk3w2rm3^%6UQnVh;k)vkbtJW$jSVl-To#$f?6aiB;kJ9K%Ra0- z=(%ltStHz8~?8o zKG#`CTx5UmE67lP_-7f&SdR}((4C9+_Gll7(@%Hr;S=Dm=~;B|9q@T?oZ?ywc?G5Ln#TfjH%(>cq~-3HyqlP|wW zeqPHVyRaG`?eW!U|NX@C2at2If36&{Z(B`vxE`Nv!1gofL;oy;{?z|F>02Ke_pP^f z*tr?->wHB2hwy;znug`~*E{?#KnLx4EJL1j(3tat?rG`##Fdi zMjQBFaF&tpVa`%MgOFc!khB*(DTrB#_{--wZJM_|?b*<9EE#w$$`bg0uT%WFOVOU9 zFZPfW54SPDn?(9Jc{lDH!PdJ-Ir?#oN9=yJa8{GkzQqRlbKp+@j + + + + NoPixel Laundromat Minigame + + + + + + + + + + + + +

NoPixel Laundromat Minigame

+

+ Play the NoPixel Laundromat Minigame and match the correct colors. +

+ How to play: Rotate the dots with ← and → or A and D to match the outer circle color.
+

+
+ STREAK: 0 MAX STREAK: 0 +
TIME: 0.000 BEST TIME: 0.000 +
+
+
+ + +
10s
+
+
+
+
Lockpick... Unlock each lock...
+ +
+
+
+ Whisper me on Twitch @Sh4rkill3r or Discord sharkiller
+ + See also:
+ >Laundromat Minigame<
+ Roof Running Minigame

+ NoPixel 3.0 Minigames

+ +
+ + \ No newline at end of file diff --git a/nopixel_minigame/4.0/laundromat/minigame.css b/nopixel_minigame/4.0/laundromat/minigame.css new file mode 100644 index 0000000..189a51b --- /dev/null +++ b/nopixel_minigame/4.0/laundromat/minigame.css @@ -0,0 +1,158 @@ +/*! + * Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face { + font-family: "Font Awesome 5 Free"; + font-style: normal; + font-weight: 900; + font-display: block; + src: url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.eot); + src: url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"), + url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.woff2) format("woff2"), + url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.woff) format("woff"), + url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.ttf) format("truetype"), + url(https://use.fontawesome.com/releases/v5.15.2/webfonts/fa-solid-900.svg#fontawesome) format("svg") +} + +.fa, .fas { + font-family: "Font Awesome 5 Free", sans-serif; + font-weight: 900 +} + +/*! + * Game + */ + +body{ + background-color: #15181d; + font-family: sans-serif; +} + +.title{ + text-align: center; + color: white; +} +.description{ + text-align: center; + color: gray; +} +.description sub{ + font-style: italic; +} + +.streaks { + display: block; + margin: 40px auto; + text-align: center; + font-size: 30px; + font-weight: bold; + text-transform: uppercase; + color: white; + width: -moz-fit-content; + width: fit-content; + background-color: #028000; + padding: 12px; + border-radius: 18px; +} +.best_time, +.time { + display: inline-block; + width: 100px; +} +.streaks .fa { + padding: 0 10px; +} +.options{ + font-weight: bold; + text-align: center; + margin: 0 auto 10px; +} +.option{ + display: inline-block; + color: white; + font-weight: bold; + text-align: center; + width: -moz-fit-content; + width: fit-content; + height: 20px; + background-color: #20282e; + padding: 10px 20px; + margin: 0 auto 10px; + border-radius: 6px; +} +.option.speed input{ + vertical-align: text-top; +} +.speed_value{ + display: inline-block; + width: 18px; + text-align: right; +} +.dots_value{ + display: inline-block; + width: 40px; + text-align: center; +} +.minigame{ + margin: 0 auto 20px; + width: 540px; + min-width: 540px; + max-width: 540px; + height: 540px; + min-height: 540px; + max-height: 540px; + background-color: #232832; +} +.splash{ + display: inline-block; + width: 100%; + margin: 220px auto; + text-align: center; + color: white; + font-size: 16px; + user-select: none; +} +.splash .hacker{ + font-size: 65px; + margin-bottom: 30px; +} +.game-canvas{ + margin: 0; + background-color: #0c2332; +} +.hidden { + display: none; +} +.restart{ + text-align: center; +} +.btn_again { + padding: 6px 15px; + font-weight: bold; +} +.credits{ + text-align: center; + color: gray; + margin-top: 40px; +} +.credits a{ + color: #ccc; +} +.credits b{ + color: white; +} +.credits .fas{ + color: red; +} +.credits .donate{ + margin: 20px 0; +} +.credits .coin{ + font-weight: bold; + color: white; +} +.credits .wallet{ + font-family: monospace; + font-size: 20px; +} diff --git a/nopixel_minigame/4.0/laundromat/minigame.js b/nopixel_minigame/4.0/laundromat/minigame.js new file mode 100644 index 0000000..9f098a2 --- /dev/null +++ b/nopixel_minigame/4.0/laundromat/minigame.js @@ -0,0 +1,292 @@ +let timer_start, timer_finish, timer_hide, timer_time, wrong, speed, timerStart; +let game_started = false; +let streak = 0; +let max_streak = 0; +let best_time = 99.999; + +const random = (min, max) => { + return Math.floor(Math.random() * (max - min)) + min; +} + +let stage = false + +let colors = []; +let lastRotation = 0; +let currentCircle = 1; +let currentCirclePos = []; + +const getCookieValue = (name) => ( + document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.pop() || '' +) +let getMaxStreakFromCookie = () => { + let str = getCookieValue('max-streak_laundromat'); + if(str !== '') + return parseInt(str, 10); + else + return 0; +} +let getBestTimeFromCookie = () => { + let str = getCookieValue('best-time_laundromat'); + if(str !== '') + return parseFloat(str); + else + return 99.999; +} +max_streak = getMaxStreakFromCookie(); +best_time = getBestTimeFromCookie(); + +const sleep = (ms, fn) => {return setTimeout(fn, ms)}; + +function addListeners(){ + // Options + document.querySelector('#speed').addEventListener('input', function(ev){ + document.querySelector('.speed_value').innerHTML = ev.target.value + 's'; + streak = 0; + reset(); + }); + // Resets + document.querySelector('.btn_again').addEventListener('click', function(){ + streak = 0; + reset(); + }); + +} + +function fillColor(color){ + let dots = stage.find('#dots-'+(45 * currentCircle))[0]; + dots.getChildren().forEach(dot => { + dot.fill(color); + }); + let sections = stage.find('#section-'+(45 * currentCircle))[0]; + sections.getChildren().forEach(section => { + section.fill(color); + }); +} + +function check(timeout){ + if (timeout) { + streak = 0; + stopTimer(); + }else if(currentCirclePos[45 * currentCircle] === 0){ + if(currentCircle === 5){ + streak++; + if(streak > max_streak){ + max_streak = streak; + document.cookie = "max-streak_laundromat="+max_streak; + } + let time = document.querySelector('.streaks .time').innerHTML; + if(parseFloat(time) < best_time){ + best_time = parseFloat(time); + document.cookie = "best-time_laundromat="+best_time; + } + if (!timeout) { + stopTimer(); + reset(); + } + }else{ + fillColor('#08AF93DB'); + currentCircle++; + dots = stage.find('#dots-'+(45 * currentCircle))[0]; + lastRotation = dots.rotation(); + } + }else{ + fillColor('rgba(234,6,6,0.8)'); + streak = 0; + stopTimer(); + } +} + +function reset(){ + + resetTimer(); + clearTimeout(timer_start); + clearTimeout(timer_hide); + clearTimeout(timer_finish); + + max_streak = getMaxStreakFromCookie(); + best_time = getBestTimeFromCookie(); + + document.querySelector('.splash').classList.remove('hidden'); + document.querySelector('.game-canvas').classList.add('hidden'); + + start(); +} + +document.addEventListener("keydown", function(ev) { + let key_pressed = ev.key; + let valid_keys = ['a','d','ArrowRight','ArrowLeft','Enter',' ']; + + if(key_pressed === 'r'){ + streak = 0; + stopTimer(); + reset(); + return; + } + if(game_started && valid_keys.includes(key_pressed) ){ + ev.preventDefault(); + let rotation = false; + switch(key_pressed){ + case 'a': + case 'ArrowLeft': + rotation = -1; + break; + case 'd': + case 'ArrowRight': + rotation = 1; + break; + case 'Enter': + case ' ': + check(); + return; + } + let dots = stage.find('#dots-'+(45 * currentCircle))[0]; + let currentRotation = dots.rotation() - lastRotation; + + if(rotation !== false && currentRotation > -30 && currentRotation < 30){ + currentCirclePos[45 * currentCircle] += rotation; + if(currentCirclePos[45 * currentCircle] < 0) currentCirclePos[45 * currentCircle] = 11; + if(currentCirclePos[45 * currentCircle] > 11) currentCirclePos[45 * currentCircle] = 0; + lastRotation += 30 * rotation; + new Konva.Tween({node: dots, duration: 0.2, rotation: lastRotation}).play(); + } + } +}); + +function addDots(radius){ + + let dotsGroup = new Konva.Group({id: 'dots-'+radius, x: 270, y: 270}); + + let cols = ['#dd2169', '#258fe6', '#ffc30a']; + colors[radius] = []; + + for(let i = 0; i < 12; i++) { + let randomColor = cols[Math.floor(Math.random() * cols.length)]; + colors[radius][i] = randomColor; + + if(Math.random() > 0.2) { + dotsGroup.add(new Konva.Circle({ + x: Math.floor(radius * Math.cos(2 * Math.PI * i / 12)), + y: Math.floor(radius * Math.sin(2 * Math.PI * i / 12)), + radius: 8, + fill: randomColor, + })); + } + } + + return dotsGroup; +} + +function addSections(radius){ + let sectionsGroup = new Konva.Group({id: 'section-'+radius, x: 270, y: 270}); + + for(let i = 0; i < 12; i++) { + let randomColor = colors[radius][i]; + + if(Math.random() > 0.4) { + sectionsGroup.add(new Konva.Arc({ + fill: randomColor, + innerRadius: radius + 15, + outerRadius: radius + 20, + angle: 30, + rotation: ((30 * (i+1)) - 45) + })); + } + } + + return sectionsGroup; +} + +function shuffleDots(){ + for(let i=1; i<=5; i++){ + let randomPos = random(1,11); + currentCirclePos[45*i] = randomPos; + let dots = stage.find('#dots-'+(45 * i))[0]; + dots.rotation( 30 * randomPos ); + if(i === 1) lastRotation = 30 * randomPos; + } +} + + +function start(){ + if(stage !== false){ + stage.destroy(); + } + stage = new Konva.Stage({ + container: 'game-canvas', + width: 540, + height: 540, + }); + colors = []; + lastRotation = 0; + currentCircle = 1; + currentCirclePos = []; + + let staticLayer = new Konva.Layer(); + for(let i=1; i<=5; i++){ + staticLayer.add( new Konva.Circle({x: 270, y: 270, radius: 45*i, stroke: 'white', strokeWidth: 2}) ); + } + for(let i=0; i<=5; i++){ + staticLayer.add( new Konva.Line({x:270,y:270,points: [-240, 0, 240, 0], stroke: '#ffffffa0', strokeWidth: 1, rotation: 30*i}) ); + } + staticLayer.add( new Konva.Line({points: [0, 540, 540, 540], stroke: '#26303e', strokeWidth: 15}) ); + staticLayer.add( new Konva.Line({id: 'progress',points: [0, 540, 540, 540], stroke: '#ff4e00', strokeWidth: 15}) ); + stage.add(staticLayer); + + let gameLayer = new Konva.Layer({id:'game'}); + for(let i=1; i<=5; i++){ + gameLayer.add(addDots(45*i)); + gameLayer.add(addSections(45*i)); + } + stage.add(gameLayer); + + shuffleDots(); + + document.querySelector('.streak').innerHTML = streak; + document.querySelector('.max_streak').innerHTML = max_streak; + document.querySelector('.best_time').innerHTML = best_time; + + timer_start = sleep(500, function(){ + document.querySelector('.splash').classList.add('hidden'); + document.querySelector('.game-canvas').classList.remove('hidden'); + + game_started = true; + + startTimer(); + speed = document.querySelector('#speed').value; + + let progress = stage.find('#progress')[0]; + new Konva.Tween({node: progress, duration: speed, points: [0, 540, 0, 540]}).play(); + + timer_finish = sleep((speed * 1000), function(){ + check(true); + }); + }); +} + +function startTimer(){ + timerStart = new Date(); + timer_time = setInterval(timer,1); +} +function timer(){ + let timerNow = new Date(); + let timerDiff = new Date(); + timerDiff.setTime(timerNow - timerStart); + let ms = timerDiff.getMilliseconds(); + let sec = timerDiff.getSeconds(); + if (ms < 10) {ms = "00"+ms;}else if (ms < 100) {ms = "0"+ms;} + document.querySelector('.streaks .time').innerHTML = sec+"."+ms; +} +function stopTimer(){ + clearInterval(timer_time); + game_started = false; +} +function resetTimer(){ + clearInterval(timer_time); + document.querySelector('.streaks .time').innerHTML = '0.000'; +} + +addListeners(); + +start(); + + diff --git a/nopixel_minigame/4.0/roof_running/index.html b/nopixel_minigame/4.0/roof_running/index.html index f53f4ff..354739a 100644 --- a/nopixel_minigame/4.0/roof_running/index.html +++ b/nopixel_minigame/4.0/roof_running/index.html @@ -53,6 +53,7 @@


See also:
+ Laundromat Minigame
>Roof Running Minigame<

NoPixel 3.0 Minigames

NoPixel Minigames by Sharkiller is licensed under CC BY-NC-ND 4.0CCBYNCND