-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.min.js
More file actions
1 lines (1 loc) · 11.4 KB
/
script.min.js
File metadata and controls
1 lines (1 loc) · 11.4 KB
1
!function(){function e(){Fe=performance.now(),Ue=4,Oe=9999,We=!0,qe=r(),Ae=!1,c(!0,we),t()}function t(){Ue--,Ue>0?setTimeout(t,1e3):(Ue=0,Oe=Re,_(qe),We=!1)}function n(){let e=performance.now(),t=e-Fe;if(rt.count++,t>=le){let n=t-le,r=Math.max(1,Math.round(n/le));for(let t=0;t<r;t++)o(e);if(0!=qe.length&&_(qe),Fe=performance.now(),Q(Fe),!(Math.round(performance.now()/1e3)-at<5))return alert("Connection lost."),void location.reload();for(let e in je)Math.round(performance.now()/1e3)-je[e]>10&&Ee.ref("snake/players/"+e).remove()}B(),v(),R(),N(),T(),E();let r=Math.max(0,1e3/re-(performance.now()-e));setTimeout(n,r)}function o(e){0==Je.length&&u(z(),G(),A()),0!=Ue||(Ae||qe.length<=0||s()?Ae||m():a()),Oe>0&&Oe--;for(let e=$e.length-1;e>=0;e--){let t=$e[e];t.ticksRemaining--,t.ticksRemaining<=0&&$e.splice(e,1)}Pe%5==0&&(document.getElementById("fpsCounter").innerText=Math.round(rt.count/((e-rt.timeLastFPSUpdate)/1e3))+" FPS",rt.count=0,rt.timeLastFPSUpdate=e),Pe++}function r(){let e=z(4),t=G(),n=[];for(let o=0;o<5;o++){let r=o*Me;n[o]={x:e-r,y:t}}return n}function a(){const e={x:qe[0].x+Xe,y:qe[0].y+_e};qe.unshift(e);const t=f();if(t){let e=V(U(y()))-1;if(e<0)for(let t=0;t>e&&1!=H(qe);t--)qe.pop();else et+=e}else et<=0?qe.pop():et--;Ge=He,He=ge,c(!1)}function l(e,t,n,o){let r;e?r=ke:t?r=xe:n?r=be:o&&(r=we),c(!1,r)}function c(e,t=ge){switch(0!=Ue&&(e=!0),e||t==ge?e?(Ge=ge,He=ge):t=Ge:(Ge==ge?Ge=t:He=t,t=Ge),t){case ke:Xe=0,_e=-Me;break;case xe:Xe=-Me,_e=0;break;case be:Xe=0,_e=Me;break;case we:Xe=Me,_e=0}ze=t==ge?ze:t}function s(){for(let e=4;e<qe.length;e++)if(qe[e].x===qe[0].x&&qe[e].y===qe[0].y)return!0;if(Oe<=0&&X())return!0;const e=qe[0].x<0,t=qe[0].x>Te-Me,n=qe[0].y<0,o=qe[0].y>Ce-Me;return e||t||n||o}function f(){let e=!1;for(let t in Je){let n=Je[t];if(qe[0].x===n.x&&qe[0].y===n.y){e=!0;break}}return e}function u(e,t,n){return!(Je.length>=he)&&(Je[Je.length]={x:e,y:t,level:n,uuid:crypto.randomUUID()},j(),!0)}function d(e,t){let n=[],o=ie;i=0;for(let r in Je){let a=Je[r];foodX=a.x,foodY=a.y,e!=foodX||t!=foodY?(n[i]=a,i++):o=a.level}return Je=n,j(),o}function y(){let e=d(qe[0].x,qe[0].y),t=Math.max(1,Math.round(K()/2))*ot;t-=Je.length;for(let e=0;e<t;e++){let e,t=!0;for(;t;){e=p(),0==Je.length&&(t=!1);for(let n in Je){let o=Je[n];o.x==e.x&&o.y==e.y||(t=!1)}}if(!u(e.x,e.y,A()))return}return e}function p(){let e=z(),t=G();qe.forEach(n=>{const o=n.x==e&&n.y==t;if(o)return p()});for(let n in Qe){let o=Qe[n].pos;o&&o.forEach(n=>{const o=n.x==e&&n.y==t;if(o)return p()})}return{x:e,y:t}}function h(){if(!(H(qe)<=5))for(let e in qe){let t=qe[e];if(!(t.x<0||t.x>Te-Me||t.y<0||t.y>Ce-Me)&&(0==W(0,5)&&!u(t.x,t.y,A())))return}}function m(){Ae=!0,_([]),h(),qe=[],document.getElementById("score").style.visibility="visible",document.getElementById("score").innerHTML="Your score: "+Ne+'<button id="buttonRetry" class="button retry">Retry (r)</button>',document.getElementById("buttonRetry").addEventListener("click",()=>b())}function g(){w()}function k(e){const t=38,n=87,o=37,r=65,a=40,i=83,c=39,s=68,f=13,u=82,d=e.keyCode,y=_e===-Me,p=_e===Me,h=Xe===Me,m=Xe===-Me;l((d===t||d===n)&&!p,(d===o||d===r)&&!h,(d===a||d===i)&&!y,(d===c||d===s)&&!m),d!==f&&d!==u||b()}function x(e){let t=ve,n=t.getBoundingClientRect(),o=ve.width/Te,r=ve.height/Ce;const a=(e.touches[0].clientX-n.left)/o,i=(e.touches[0].clientY-n.top)/r,c=_e===-Me,s=_e===Me,f=Xe===Me,u=Xe===-Me,d=!(!(Ce/2>i)||Te/4>a||Te-Te/4<a||s),y=Te/4>a&&!f,p=!(!(Ce/2<i)||Te/4>a||Te-Te/4<a||c),h=Te-Te/4<a&&!u;l(d,y,p,h)}function b(){Ae&&(document.getElementById("score").style.visibility="hidden",e())}function w(){const e=ve.clientWidth,t=ve.clientHeight;ve.width=e,ve.height=t,Se.scale(e/Te,t/Ce)}function v(){Se.clearRect(0,0,Te,Ce)}function S(e,t){let n;try{n=new Color(e.toLowerCase())}catch{n=new Color("red")}return t&&(n.alpha=2*Math.abs(tt)/100),n}function T(){if(0==qe.length)return;color=S(Be,Oe>0);let e=ze;qe.forEach(t=>{M(color,t,e),e=void 0})}function C(e){let t=new Color(e),n=t.contrastWCAG21(new Color("#000")),o=t.contrastWCAG21(new Color("#fff")),r=n>=o?"#000":"#fff";return new Color(r)}function M(e,t,n){if(Se.fillStyle=e,Se.strokestyle="black",Se.fillRect(t.x,t.y,Me,Me),Se.strokeRect(t.x,t.y,Me,Me),null!=n){switch(Se.fillStyle=C(e),Se.beginPath(),n){case ke:Se.moveTo(t.x+Me/2,t.y+1),Se.lineTo(t.x,t.y+.25*Me+1),Se.lineTo(t.x+Me,t.y+.25*Me+1);break;case xe:Se.moveTo(t.x+1,t.y+Me/2),Se.lineTo(t.x+.25*Me+1,t.y),Se.lineTo(t.x+.25*Me+1,t.y+Me);break;case be:Se.moveTo(t.x+Me/2,t.y+Me-1),Se.lineTo(t.x,t.y+.75*Me-1),Se.lineTo(t.x+Me,t.y+.75*Me-1);break;case we:Se.moveTo(t.x+Me-1,t.y+Me/2),Se.lineTo(t.x+.75*Me-1,t.y),Se.lineTo(t.x+.75*Me-1,t.y+Me)}Se.closePath(),Se.fill()}}function R(){for(let e in Je){let t=Je[e];Se.fillStyle=F(P(t.level)),Se.strokestyle="black",Se.fillRect(t.x,t.y,Me,Me),Se.strokeRect(t.x,t.y,Me,Me)}tt++}function B(){let e=[],t="";i=0;for(let t in Ve){let n=H(Ve[t].pos)-5;Ne=n>=0&&t==Ye?n:Ne,e[i]={score:n,playerName:t},i++}e.sort((e,t)=>t.score-e.score);for(let n in e){let o=e[n],r=o.score,a=o.playerName,l=Ve[a];t+='<span id="scoreboard" style="color:'+l.color+';">'+O(a)+"</span>: "+(r<-4?"Spectator":r)+"<br>"}document.getElementById("sidebar").innerHTML="Online: "+Y()+"/15<br><br>"+t}function E(){if(Ue>0){Se.font="150px 'Outfit', sans-serif",Se.fillStyle="white";let e=Ue.toString(),t=Se.measureText(e),n=t.width;Se.fillText(e,Te/2-n/2,Ce/2)}for(let e in Ve){let t=Ve[e],n=t.collectedFoodScores;if(!n||!t.pos||!t.pos[0])continue;Se.font="bold 32px 'Outfit', sans-serif";let o=t.pos[0];const r=6,a=6,l=7,i=o.y>Ce/2;let c=i?Me+2:-Me-a-2;for(let e in n){const t=n[e],s=(t.score>=0?"+":"")+t.score.toString(),f=Se.measureText(s),u=f.width,d=f.actualBoundingBoxDescent+f.actualBoundingBoxAscent;let y=o.x+Me/2-u/2-r;y=Math.max(r,Math.min(Te-u-3*r,y));let p=o.y-c-a;const h=u+2*r,m=d+2*a;Se.fillStyle="#444444",Se.beginPath(),Se.roundRect(y,p,h,m,l),Se.fill(),Se.fillStyle=t.score>0?"lime":0==t.score?"white":"red",Se.fillText(s,y+r,p+d+a),c+=i?m+2:-m-2}}}function I(){if(De>oe){qe=[],_([]),alert("Client outdated. Click OK to reload the page and try again.\n\nIf reloading doesn't work after some waiting, try pressing CTRL+SHIFT+R or delete all cookies and data from this page.");try{location.reload(!0)}catch{location.reload()}}else De<oe&&(qe=[],_([]),alert("Database outdated. Please wait for the database to update."),location.reload());Le=!0}function L(){let e=D(),t=e[W(0,e.length-1)];return t}function D(){let e=[],t=[],n=0;for(let t in Qe)otherSnake=Qe[t],null!=otherSnake&&null!=otherSnake.color&&(e[n]=otherSnake.color,n++);n=0;for(let o in ae)Array.from(e).includes(ae[o])||(t[n]=ae[o],n++);return t}function F(e){tt>=50&&(tt=-50);let t=new Color("hsv",[e==pe?(tt+50)/100*360:e,100,e==pe?100:Math.abs(tt)+50]);return t.to("srgb")}function P(e){switch(e){case ce:return ue;case se:return de;case fe:return ye;case ie:return pe;default:return 0}}function A(){if(nt>=0)return nt;let e=W(0,300);return e>=0&&e<100?ce:e>=100&&e<200?se:e>=200&&e<250?fe:ie}function U(e){return 0==e?W(-5,10):e}function O(e){return String(e).replace("&","&").replace("<","<").replace(">",">").replace('"',""")}function W(e,t){return Math.round(Math.random()*(t-e)+e)}function z(e){return e=e||0,Math.round(W(e*Me,Te-Me)/Me)*Me}function G(){return Math.round(W(0,Ce-Me)/Me)*Me}function H(e){let t=0;for(let n in e)t++;return t}function Y(){return H(Ve)}function K(){let e=0;for(let t in Ve){let n=Ve[t];null!=n.pos&&0!=H(n.pos)&&e++}return e}function q(){for(;Y()>=me;)alert("The game is full (15/15). Click OK to retry.")}function N(){for(let e in Qe){let t=Qe[e];if(null==t||null==t.pos)continue;let n=t.headDir;t.pos.forEach(e=>{let o=S(null==t.color?"red":t.color,t.hasSpawnProtection);M(o,e,n),n=void 0})}}function X(){for(let e in Qe){let t=Qe[e].pos;if(null!=t&&!Qe[e].hasSpawnProtection)for(let e=0;e<t.length;e++)if(t[e].x===qe[0].x&&t[e].y===qe[0].y)return!0}return!1}function _(e){We&&(e=[]),Ye&&(Ee.ref("snake/players/"+Ye+"/pos").set(e),Ee.ref("snake/players/"+Ye+"/headDir").set(ze),Ee.ref("snake/players/"+Ye+"/hasSpawnProtection").set(Oe>0),Ee.ref("snake/players/"+Ye+"/collectedFoodScores").set($e))}function Q(){let e=Math.round(performance.now()/1e3);Ee.ref("snake/players/"+Ye+"/lastUpdate").set(e)}function j(){Ee.ref("snake/foods").set(Je)}function V(e){return collectedFood={score:e,ticksRemaining:15},$e.unshift(collectedFood),e}function Z(){Ee.ref("snake/foods").on("value",e=>{data=e.val(),Je=null==data?[]:data}),Ee.ref("snake/variables/forcedFoodLevel").on("value",e=>{data=e.val(),nt=null==data?-1:data}),Ee.ref("snake/variables/foodFactor").on("value",e=>{data=e.val(),ot=null==data?1:data}),Ee.ref("snake/players").on("value",e=>{if(data=e.val(),null==data)return void(Ze=!0);let t=[];for(let e in data)e!=Ye?(t[e]=data[e],(Qe[e]&&t[e].lastUpdate!=Qe[e].lastUpdate||!je[e])&&(je[e]=Math.round(performance.now()/1e3))):data[e].color?Be=data[e].color:Ee.ref("snake/players/"+Ye+"/color").set(Be);Qe=t,Ve=data,Ze=!0}),Ie.ref("snake/players/"+Ye).on("value",e=>{if(data=e.val(),null!=data)for(let e in data)if(e==Ye){let t=data[e].lastUpdate;at=t>0?t:at;break}})}function J(){g(),alert("We use cookies. By using this site, you agree with it.\n\nWe use the Realtime Database of Google Firebase to serve multiplayer. If you want to know how Google proceeds your data, look on their page: https://firebase.google.com/support/privacy/\n\nIf you don't want to agree, close this site. No data has been saved yet.");const e=firebase.initializeApp(lt),t=firebase.initializeApp(lt,"OnlineCheck");Ee=firebase.database(e),Ie=firebase.database(t),Ee.ref("snake/variables/version").on("value",e=>{data=e.val(),De=parseInt(data,10),I()}),$()}function $(){Le?(document.addEventListener("keydown",k),window.addEventListener("resize",g,!1),ve.addEventListener("touchstart",x),window.addEventListener("keydown",function(e){[32,37,38,39,40].indexOf(e.keyCode)>-1&&e.preventDefault()},!1),g(),Z(),ee()):setTimeout($,50)}function ee(){Ze?(q(),ne(),te()):setTimeout(ee,50)}function te(){Ke?(Ee.ref(".info/connected").on("value",e=>{e.val()?(Ee.ref("snake/players/"+Ye).onDisconnect().remove(),console.log("DB connected.")):console.log("DB disconnected.")}),Be=L(),Ee.ref("snake/players/"+Ye+"/color").set(Be),Fe=performance.now(),at=Math.round(performance.now()/1e3),n(),e()):setTimeout(te,50)}function ne(){for(Ke=!1,Ye="";""==Ye;){let e=prompt("Choose a player name (max 16 characters):\n\nOnly alphanumeric and _ characters are allowed.");Ye=null==e?"":e,Ye=Ye.replaceAll(/[^a-zA-ZäöüÄÖÜßẞ0-9_]/g,""),Ye.length>16?(alert("This name is too long."),Ye=""):Ee.ref("snake/players/"+Ye+"/color").get().then(e=>{if(e.exists())return alert("Someone has already chosen this name."),Ye="",void ne();Ke=!0})}}const oe=36,re=125,ae=["Aqua","Yellow","Red","Black","White","DeepPink","LawnGreen","Orange","SaddleBrown","OrangeRed","DarkViolet","Gold","Indigo","Silver","DarkGreen"],le=100,ie=0,ce=1,se=2,fe=3,ue=175,de=110,ye=0,pe=-1,he=50,me=ae.length,ge=-1,ke=0,xe=1,be=2,we=3,ve=document.getElementById("snakeboard"),Se=ve.getContext("2d"),Te=1920,Ce=1080,Me=30,Re=3e3/le;let Be,Ee,Ie,Le=!1,De=0,Fe=0,Pe=0,Ae=!1,Ue=4,Oe=Re,We=!0,ze=we,Ge=ge,He=ge,Ye="",Ke=!1,qe=[],Ne=0,Xe=Me,_e=0,Qe=[],je=[],Ve=[],Ze=!1,Je=[],$e=[],et=0,tt=0,nt=-1,ot=1,rt={timeLastFPSUpdate:0,count:0},at=-1,lt={apiKey:"AIzaSyBbRpK_BcltEmRQzLAUCFykMHEq5PQWWz4",authDomain:"psyched-canto-311609.firebaseapp.com",databaseURL:"https://psyched-canto-311609-default-rtdb.europe-west1.firebasedatabase.app",projectId:"psyched-canto-311609",storageBucket:"psyched-canto-311609.appspot.com",messagingSenderId:"556381649934",appId:"1:556381649934:web:af27169882d8297d78d05f"};J()}();