/*******************Reset Previous Content******************/ $('body')[0].innerHTML='' +'' +'' +''; if (timer) window.clearInterval(timer); /*******************Create Canvas**********************/ var width=document.documentElement.clientWidth; var height=document.documentElement.clientHeight; $('body').prepend('Please use a modern browser.'); var canvasEl=$('#canv')[0]; var cv=canvasEl.getContext('2d'); /*******************Math Helpers********************/ var cos=Math.cos, sin=Math.sin, random=Math.random, PI=Math.PI, atan2=Math.atan2, floor=Math.floor, sqrt=Math.sqrt; function cube(x) { return x*x; } function rad(d) { return d/180*PI; } function xy(u) { return {x:u.r*cos(u.t), y:u.r*sin(u.t)}; } function dis2(x1,y1,x2,y2) { return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } function ran(a,b) { return a+(b-a)*random(); } function ranInt(a,b) { return floor(a+(b-a+1)*random()); } function min(a,b) { return a>b?b:a; } /*******************Strings*************************/ var _gamename='ENDLESS SEA'; var _instructions='TUTORIAL'; var _about='ABOUT'; var _startgame='START GAME'; var _pause='PAUSE'; var _continue='CONTINUE'; var _gameover='DREAM AWAKE'; var _scoreis='YOUR SCORE: '; var _ranking='RANKING'; var _tryagain='TRY AGAIN'; var _settings='SETTINGS'; var _fullscreen='FULLSCREEN'; var _windowed='WINDOWED'; var _scorereset='RESET SCORES'; var _autopause='AUTO PAUSED'; var _top_score='Score: '; var _top_life='Life: '; var _top_level='Level: '; var _life='Life: '; var _wudi='Superfish'; var _jiansu='Speed Down'; var _qingping='Big Bomb'; var _1up='1 UP'; var _bianxiao='Small World'; /*******************Globals And Constants***************/ var mx,my,bg,pl,plSize,cursorSize,ballSize,bigBallSize,bSize,butterflySize,starSize,d1,d2,d3,t1,t2,score,u1,u2, fps,planeShape,butterflyLine,butterflyShape,diamondShape,Star_6,balls,bigBalls,butterflys,stars,diamonds,waves,ballSpeed, bigBallSpeed,butterflySpeed,starSpeed,waveSpeed,waveRSpeed,waveWidth,waveMaxR,waveR,waveNum,ballDensity,bigBallDensity,butterflyDensity,starDensity,diamondDensity,ballStyle,instructionsContent,aboutContent, clock,died,level,judge,startBgColor=ranInt(0,359),bgColorTimer=0,life,wudi,wudiTimer,smallTimer,slowTimer,timer,flash,pause,pauseTimes,scoreArr,gameStarted,slowFactor,smallFactor,pixelRatio,pauseMessage; var scoreArr = []; var STORAGE_KEYS = { scores: 'endlessSea.scores', settings: 'endlessSea.settings' }; var DEFAULT_SETTINGS = { musicVolume: 55, sfxVolume: 80, muted: false, autoPause: true, keyboardControl: true }; var settings = loadSettings(); var keyState = {left:false,right:false,up:false,down:false}; function loadScores() { var raw = window.localStorage.getItem(STORAGE_KEYS.scores); if (!raw) return []; try { var parsed = JSON.parse(raw); if (!Array.isArray(parsed)) return []; return parsed.filter(function(item) { return typeof item === 'number' && !isNaN(item); }); } catch (err) { return []; } } function saveScores(scores) { window.localStorage.setItem(STORAGE_KEYS.scores, JSON.stringify(scores)); } function clamp(value, lower, upper) { return min(max(value, lower), upper); } function loadSettings() { var raw = window.localStorage.getItem(STORAGE_KEYS.settings); if (!raw) return { musicVolume: DEFAULT_SETTINGS.musicVolume, sfxVolume: DEFAULT_SETTINGS.sfxVolume, muted: DEFAULT_SETTINGS.muted, autoPause: DEFAULT_SETTINGS.autoPause, keyboardControl: DEFAULT_SETTINGS.keyboardControl }; try { var parsed = JSON.parse(raw); return { musicVolume: clamp(Number(parsed.musicVolume === undefined ? DEFAULT_SETTINGS.musicVolume : parsed.musicVolume), 0, 100), sfxVolume: clamp(Number(parsed.sfxVolume === undefined ? DEFAULT_SETTINGS.sfxVolume : parsed.sfxVolume), 0, 100), muted: !!parsed.muted, autoPause: parsed.autoPause === undefined ? DEFAULT_SETTINGS.autoPause : !!parsed.autoPause, keyboardControl: parsed.keyboardControl === undefined ? DEFAULT_SETTINGS.keyboardControl : !!parsed.keyboardControl }; } catch (err) { return { musicVolume: DEFAULT_SETTINGS.musicVolume, sfxVolume: DEFAULT_SETTINGS.sfxVolume, muted: DEFAULT_SETTINGS.muted, autoPause: DEFAULT_SETTINGS.autoPause, keyboardControl: DEFAULT_SETTINGS.keyboardControl }; } } function saveSettings() { window.localStorage.setItem(STORAGE_KEYS.settings, JSON.stringify(settings)); } function recordScore(totalScore) { var scores = loadScores(); scores.push(totalScore); scores.sort(function(a, b) { return b - a; }); saveScores(scores); return scores; } function getTopScores(limit) { var scores = loadScores().sort(function(a, b) { return b - a; }); while (scores.length < limit) scores.push(0); return scores.slice(0, limit); } function renderRanking(scores) { var rankContent = ''; for (var i = 0; i < scores.length; i++) { rankContent += '
' + (i + 1) + '. ' + scores[i] + '
'; } $('#right2')[0].innerHTML = rankContent; } function clearLoop() { if (timer) { window.clearInterval(timer); timer = null; } } function syncCursor() { $('html').css({cursor: (gameStarted && !pause && !died) ? 'none' : 'default'}); } function safePlayAudio(audio) { if (!audio) return; var playPromise = audio.play(); if (playPromise && playPromise.catch) playPromise.catch(function() {}); } function applyAudioSettings() { var music = $('#music')[0]; if (music) { music.volume = settings.musicVolume / 100; music.muted = settings.muted; } var soundIds = ['diesound', 'killsound', 'diamondsound']; for (var i = 0; i < soundIds.length; i++) { var sound = $('#' + soundIds[i])[0]; if (sound) { sound.volume = settings.sfxVolume / 100; sound.muted = settings.muted; } } } function playMusic() { applyAudioSettings(); safePlayAudio($('#music')[0]); } function pauseMusic() { var music = $('#music')[0]; if (music) music.pause(); } function playSound(id) { var sound = $('#' + id)[0]; if (!sound) return; applyAudioSettings(); try { sound.pause(); sound.currentTime = 0; } catch (err) { } safePlayAudio(sound); } function syncCanvasResolution() { pixelRatio = max(window.devicePixelRatio || 1, 1); canvasEl.width = floor(width * pixelRatio); canvasEl.height = floor(height * pixelRatio); $('#canv').css({width: width+'px', height: height+'px'}); cv.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); } function isFullscreen() { return !!document.fullscreenElement; } function toggleFullscreen() { if (isFullscreen()) { if (document.exitFullscreen) document.exitFullscreen(); return; } var target = document.documentElement; if (target.requestFullscreen) target.requestFullscreen().catch(function() {}); } function renderSettingsPanel() { if (!$('#settingspanel').length) return; $('#music-volume').val(settings.musicVolume); $('#music-volume-value').text(settings.musicVolume+'%'); $('#sfx-volume').val(settings.sfxVolume); $('#sfx-volume-value').text(settings.sfxVolume+'%'); $('#mute-toggle').prop('checked', settings.muted); $('#autopause-toggle').prop('checked', settings.autoPause); $('#keyboard-toggle').prop('checked', settings.keyboardControl); $('#fullscreen-toggle').text(isFullscreen() ? _windowed : _fullscreen); } function addSettingsPanel() { $('body').append( '
' + '
'+_settings+'
' + '
' + '' + '' + '
' + '
' + '' + '' + '
' + '
Mute Audio
' + '
Auto Pause On Blur
' + '
Keyboard Steering
' + '
' + '
' + '
'+_scorereset+'
' + '
CLOSE
' + '
' + '
Desktop and browser settings are saved in local storage. Press F for fullscreen and M to mute at any time.
' + '
' ); renderSettingsPanel(); } function toggleSettingsPanel(forceOpen) { if (!$('#settingspanel').length) return; var shouldOpen = forceOpen; if (typeof shouldOpen !== 'boolean') shouldOpen = $('#settingspanel').css('display') === 'none'; if (shouldOpen) { renderSettingsPanel(); $('#settingspanel').fadeIn(150); } else { $('#settingspanel').fadeOut(120); } } function resetScores() { window.localStorage.removeItem(STORAGE_KEYS.scores); scoreArr = []; addRankingInfo(); } function updateKeyboardCursor() { if (!settings.keyboardControl) return; var dx = 0; var dy = 0; if (keyState.left) dx -= 1; if (keyState.right) dx += 1; if (keyState.up) dy -= 1; if (keyState.down) dy += 1; if (!dx && !dy) return; var speed = 10; if (dx && dy) speed *= 0.78; mx = clamp(mx + dx * speed, 0, width); my = clamp(my + dy * speed, 0, height); } function startGame() { $('#startgame').remove(); $('.title').remove(); $('#left').fadeOut(300); $('#right').fadeOut(300); toggleSettingsPanel(false); gameStarted = true; pause = false; syncCursor(); clockStart(); playMusic(); } function showPauseOverlay(message) { pauseMessage = message || ''; if ($('#pause').length) $('#pause').remove(); if ($('.title').length) $('.title').remove(); $('body').append('
'+_pause+'
'+_instructions+'
'+ '
'+_about+'
'+_settings+'
'+_fullscreen+'
'+_continue+'
'+pauseMessage+'
'); layoutPanels(); } function pauseGame(consumePause, message) { if (pause || !gameStarted || died || $('#startgame').length) return; if (consumePause && pauseTimes < 0) return; pause = true; if (consumePause) pauseTimes--; showPauseOverlay(message); syncCursor(); pauseMusic(); } function layoutPanels() { var sideWidth = max(width/2-240, 150); var rightLeft = max(width/2+220, 20); if ($('#startgame').length) { $('#startgame').css({left: width/2-200+'px', top: height/2-100+'px'}); } if ($('#pause').length) { $('#pause').css({left: width/2-200+'px', top: height/2-100+'px'}); } if ($('#die').length) { $('#die').css({left: width/2-200+'px', top: height/2-100+'px'}); } if ($('.title').length) { $('.title').css({top: height/2-200+'px', left: width/2-$('.title').width()/2+'px'}); } if ($('#left').length) { $('#left').css({left: '20px', width: sideWidth+'px', top: height/2-100+'px'}); } if ($('#right').length) { $('#right').css({left: rightLeft+'px', width: sideWidth+'px', top: height/2-100+'px'}); } if ($('#right2').length) { $('#right2').css({left: rightLeft+'px', top: height/2-100+'px'}); if (!$('#die').length) { $('#right2').css({width: sideWidth+'px', 'padding-top': 0+'px'}); } } if ($('#settingspanel').length) { $('#settingspanel').css({left: max(width-340, 20)+'px', top: '20px'}); } } function resizeGame() { width = document.documentElement.clientWidth; height = document.documentElement.clientHeight; syncCanvasResolution(); mx = clamp(mx || 0, 0, width); my = clamp(my || 0, 0, height); if (pl) { pl.x = clamp(pl.x, 0, width); pl.y = clamp(pl.y, 0, height); } layoutPanels(); renderSettingsPanel(); drawBG(); } function bindOverlayHover(triggerSelector, panelSelector) { $(document).off('mouseenter mouseleave', triggerSelector); $(document).on('mouseenter', triggerSelector, function() { $(triggerSelector).css('background','#1954c0'); $(panelSelector).fadeIn(500); }); $(document).on('mouseleave', triggerSelector, function() { $(triggerSelector).css('background','#3369cd'); $(panelSelector).fadeOut(300); }); } function max(a,b) { return a>b?a:b; } function rebuildScaledShapes() { Star_6 = [{r:starSize,t:rad(90)},{r:starSize/2*1.5,t:rad(60)},{r:starSize,t:rad(30)},{r:starSize/2*1.5,t:rad(0)},{r:starSize,t:rad(-30)},{r:starSize/2*1.5,t:rad(-60)},{r:starSize,t:rad(-90)},{r:starSize/2*1.5,t:rad(-120)},{r:starSize,t:rad(-150)},{r:starSize/2*1.5,t:rad(-180)},{r:starSize,t:rad(-210)},{r:starSize/2*1.5,t:rad(-240)}]; planeShape=[{r:plSize*1,t:PI+3.14},{r:plSize*0.716,t:PI+-2.98},{r:plSize*0.443,t:PI+-2.49},{r:plSize*0.443,t:PI-0.65},{r:plSize*0.716,t:PI-0.25},{r:plSize*1,t:PI+0},{r:plSize*1,t:PI+0},{r:plSize*0.716,t:PI+0.25},{r:plSize*0.443,t:PI+0.65},{r:plSize*0.443,t:PI+2.49},{r:plSize*0.716,t:PI+2.98}]; } function rebuildJudge(diamondRadius) { judge={ ball:cube(plSize/4+ballSize), bigBall:cube(plSize/4+bigBallSize), butterfly:cube(plSize/4+butterflySize), star:cube(plSize/4+starSize), diamond:cube(plSize/4+diamondRadius) }; } function resetGameState() { mx=width/7,my=height/2; bg; pl={x:width/9,y:height/2,vx:0,vy:0,ax:0,ay:0,arc:0}; plSize=20; cursorSize=6; ballSize=4; bigBallSize=40; bSize=10; butterflySize=bSize-2; starSize=6; d1 = 25;d2 = d1/25*30;d3 = d1/25*27;t1 = 20;t2 = 40; u1=6,u2=80; fps=60; ballStyle='#eef'; butterflyLine=[{r:3,t:rad(15)},{r:3,t:rad(345)}]; butterflyShape=[{r:1,t:0},{r:2.7,t:rad(35)},{r:3.5,t:rad(45)},{r:3.2,t:rad(55)},{r:2.33,t:rad(95)},{r:1,t:rad(90)},{r:2,t:rad(120)},{r:2.1,t:rad(150)},{r:1,t:rad(180)},{r:2.1,t:rad(210)},{r:2,t:rad(240)},{r:1,t:rad(270)},{r:2.33,t:rad(265)},{r:3.2,t:rad(305)},{r:3.5,t:rad(315)},{r:2.7,t:rad(325)}]; diamondShape = [{r:d1,t:PI+rad(90+t1+t2/2)},{r:d2,t:PI+rad(90+t2/2)},{r:d2,t:PI+rad(90-t2/2)},{r:d1,t:PI+rad(90-t1-t2/2)},{r:0,t:PI}]; rebuildScaledShapes(); for (var i in butterflyShape) butterflyShape[i].r*=bSize; balls=[]; bigBalls=[]; butterflys=[]; stars=[]; diamonds=[]; waves=[]; ballSpeed=4.2; bigBallSpeed=3.8; butterflySpeed=0.35; starSpeed=6; waveSpeed=ballSpeed; waveNum=8; waveR=5; waveRSpeed=0.7; waveWidth=6; waveMaxR=100; ballDensity=0.5; bigBallDensity=0.08; butterflyDensity=5; starDensity=8; diamondDensity=0.0012; rebuildJudge(20); clock=0; score=0; died=false; level=0; life=5; wudi=false; window.clearTimeout(wudiTimer); window.clearTimeout(smallTimer); window.clearTimeout(slowTimer); flash=0; instructionsContent='

TUTORIAL

Move the mouse or use WASD / arrow keys.

Collect diamonds for power-ups.

Press Space, Enter or P to pause.

Press F for fullscreen and M to mute.

'; aboutContent='

ABOUT

Original project by Bobwei Zhou and Yangmei Lin.

All visuals are drawn in code without image sprites.

Desktop and browser builds share the same game logic.

'; pause=false; pauseMessage = ''; pauseTimes=30; gameStarted = false; keyState = {left:false,right:false,up:false,down:false}; slowFactor = 1; smallFactor = 1; scoreArr = []; } /*******************Start Game************************/ resetGameState(); syncCanvasResolution(); applyAudioSettings(); drawBG(); $('body').append('
'+_gamename+'
' +'
'+_instructions+'
'+ '
'+_about+'
'+ '
'+_settings+'
'+ '
'+_fullscreen+'
'+ '
'+_startgame+'
'); $('body').append('
'); $('body').append(''); $('body').append('
'); addSettingsPanel(); layoutPanels(); addHelpInfo(); addAboutInfo(); addRankingInfo(); /*******************Drawing Functions********************/ function hsvToRgb(h,s,v) { var hi = floor(h/60); var f = h/60-hi; var u = floor(255*v); var p = floor(255*v*(1-s)); var q = floor(255*v*(1-f*s)); var t = floor(255*v*(1-(1-f)*s)); var res=[ {r:u,g:t,b:p}, {r:q,g:u,b:p}, {r:p,g:u,b:t}, {r:p,g:q,b:u}, {r:t,g:p,b:u}, {r:u,g:p,b:q} ]; return res[hi]; } function drawBG() { if (bgColorTimer%10==0) { var b=hsvToRgb((startBgColor+bgColorTimer/10)%360,0.14,0.92); var c=hsvToRgb((startBgColor+bgColorTimer/10)%360,0.57,0.77); bg=cv.createLinearGradient(0,0,0,height); bg.addColorStop(0,'rgb('+b.r+','+b.g+','+b.b+')'); bg.addColorStop(1,'rgb('+c.r+','+c.g+','+c.b+')'); } cv.save(); cv.fillStyle=bg; cv.fillRect(0,0,width,height); cv.restore(); } function drawItem(p,x,y,d) { cv.beginPath(); var len=p.length; cv.moveTo(x+p[0].r*cos(p[0].t+d), y+p[0].r*sin(p[0].t+d)); for (var i=0;iwaveNum) waves.splice(0,1); } /*********************Movement And Collision********************/ function ballMove() { for (var i=balls.length-1;i>=0;i--) { balls[i].pos.x+=balls[i].speed*cos(balls[i].degree); balls[i].pos.y+=balls[i].speed*sin(balls[i].degree); if (dis2(balls[i].pos.x,balls[i].pos.y,pl.x,pl.y)=0;i--) { bigBalls[i].pos.x+=bigBalls[i].speed*cos(bigBalls[i].degree); bigBalls[i].pos.y+=bigBalls[i].speed*sin(bigBalls[i].degree); if (dis2(bigBalls[i].pos.x,bigBalls[i].pos.y,pl.x,pl.y)=0;i--) { butterflys[i].pos+=butterflys[i].rspeed; butterflys[i].deg=(butterflys[i].rspeed>0)?(butterflys[i].pos+rad(90)):(butterflys[i].pos-rad(90)); butterflys[i].x=butterflys[i].cx+butterflys[i].r*cos(butterflys[i].pos); butterflys[i].y=butterflys[i].cy+butterflys[i].r*sin(butterflys[i].pos); if (dis2(butterflys[i].x,butterflys[i].y,pl.x,pl.y)0&&butterflys[i].y<-50||butterflys[i].rspeed<0&&butterflys[i].y>height+50) butterflys.splice(i,1); } } function starMove() { for (var i=stars.length-1;i>=0;i--) { stars[i].deg+=stars[i].rspeed; stars[i].x+=starSpeed*cos(stars[i].aim); stars[i].y+=starSpeed*sin(stars[i].aim); if (dis2(stars[i].x,stars[i].y,pl.x,pl.y)=0;i--) { diamonds[i].y+=diamonds[i].speed; if (dis2(diamonds[i].x,diamonds[i].y-15,pl.x,pl.y)height+50) diamonds.splice(i,1); } } function waveMove() { for (var i=waves.length-1;i>=0;i--) { waves[i].x-=waveSpeed; waves[i].r+=waveRSpeed; } } function planeMove() { var dd=dis2(mx,my,pl.x,pl.y); pl.ax=(mx-(pl.x+plSize*cos(pl.arc)))-pl.vx/u1; pl.ay=(my-(pl.y+plSize*sin(pl.arc)))-pl.vy/u1; var vv=dis2(pl.vx,pl.vy,0,0); pl.x+=pl.vx/u2; pl.y+=pl.vy/u2; pl.vx+=pl.ax; pl.vy+=pl.ay; pl.arc=atan2(100,-(my-(pl.y+plSize*sin(pl.arc))))-PI/2; } /*********************Main Loop**********************/ function clockStart(){ clearLoop(); gameStarted = true; timer=setInterval(function() { if (!pause) { drawBG(); drawCursor(); waveMove(); drawWaves(); updateKeyboardCursor(); planeMove(); if (!died) drawPlane(); ballMove(); drawBalls(); bigBallMove(); drawBigBalls(); butterflyMove(); drawButterflys(); starMove(); drawStars(); diamondMove(); drawDiamonds(); if (!died&&(level==1&&clock%25==0||level>1&&clock%20==0)) addWave(); if (random()=1200&&random()6) { if (random()=6) { if (clock%100==0) addButterfly(); } if (level==3||level==4||level>=6) { if (clock%starDensity==0) addStar(); } if (!died) { cv.save(); var txt=_top_score+(clock+score)+'0 '+_top_life; txt+=' x'+life; txt+=' '+_top_level+(level>6?'MAX':level+1); cv.font="20px Arial"; var u=min(1,dis2(pl.x,pl.y,0,0)/cube(height)); cv.fillStyle='rgba(221,51,85,'+u+')'; cv.fillText(txt,30,30); cv.font="14px Arial"; cv.fillStyle='rgba(17,31,61,0.7)'; cv.fillText('Mouse / WASD / Arrows | P Pause | F Fullscreen | M Mute',30,height-20); cv.restore(); } clock++; bgColorTimer++; if (clock==1800) level++; if (clock>1800&&clock%1200==600) level++; if (flash==8||flash==7||flash==2||flash==1) { cv.save(); cv.fillStyle='rgba(255,255,255,0.5)'; cv.fillRect(0,0,width,height); cv.restore(); flash--; } else if (flash) { flash--; } } }, 1000/fps); } /*********************Event Listeners**************************/ document.addEventListener('mousemove',function(e) { mx=e.clientX; my=e.clientY; }); document.addEventListener('touchstart',function(e) { if (!e.touches.length) return; mx=e.touches[0].clientX; my=e.touches[0].clientY; }, {passive:true}); document.addEventListener('touchmove',function(e) { if (!e.touches.length) return; mx=e.touches[0].clientX; my=e.touches[0].clientY; }, {passive:true}); document.addEventListener('click',function(e) { if (e.target.id=='retry') retry(); else if (e.target.id=='startbutton') { startGame(); } else if (e.target.id=='continue') { stopPause(); } else if (e.target.id=='settingsbutton') { toggleSettingsPanel(); } else if (e.target.id=='close-settings') { toggleSettingsPanel(false); } else if (e.target.id=='fullscreenbutton' || e.target.id=='fullscreen-toggle') { toggleFullscreen(); } else if (e.target.id=='reset-scores') { resetScores(); } }); document.addEventListener('keydown',startPause); document.addEventListener('keydown',function(e) { var key = e.key.toLowerCase(); if (key === 'arrowleft' || key === 'a') keyState.left = true; if (key === 'arrowright' || key === 'd') keyState.right = true; if (key === 'arrowup' || key === 'w') keyState.up = true; if (key === 'arrowdown' || key === 's') keyState.down = true; if (key === 'f') { e.preventDefault(); toggleFullscreen(); } if (key === 'm') { settings.muted = !settings.muted; saveSettings(); applyAudioSettings(); renderSettingsPanel(); } }); document.addEventListener('keyup',function(e) { var key = e.key.toLowerCase(); if (key === 'arrowleft' || key === 'a') keyState.left = false; if (key === 'arrowright' || key === 'd') keyState.right = false; if (key === 'arrowup' || key === 'w') keyState.up = false; if (key === 'arrowdown' || key === 's') keyState.down = false; }); $(document).on('input', '#music-volume', function() { settings.musicVolume = clamp(parseInt(this.value, 10), 0, 100); saveSettings(); applyAudioSettings(); renderSettingsPanel(); }); $(document).on('input', '#sfx-volume', function() { settings.sfxVolume = clamp(parseInt(this.value, 10), 0, 100); saveSettings(); applyAudioSettings(); renderSettingsPanel(); }); $(document).on('change', '#mute-toggle', function() { settings.muted = !!this.checked; saveSettings(); applyAudioSettings(); renderSettingsPanel(); }); $(document).on('change', '#autopause-toggle', function() { settings.autoPause = !!this.checked; saveSettings(); renderSettingsPanel(); }); $(document).on('change', '#keyboard-toggle', function() { settings.keyboardControl = !!this.checked; saveSettings(); if (!settings.keyboardControl) keyState = {left:false,right:false,up:false,down:false}; renderSettingsPanel(); }); window.addEventListener('resize', resizeGame); window.addEventListener('fullscreenchange', renderSettingsPanel); document.addEventListener('visibilitychange', function() { if (document.hidden && settings.autoPause) pauseGame(false, _autopause); }); window.addEventListener('blur', function() { if (settings.autoPause) pauseGame(false, _autopause); }); /*********************Help And About************************/ bindOverlayHover('#instructions', '#left'); bindOverlayHover('#about', '#right'); function addHelpInfo() { $('#left').append(instructionsContent); } function addAboutInfo() { $('#right').append(aboutContent); } function addRankingInfo(t) { if (typeof t === 'number') { scoreArr = recordScore(t); } else { scoreArr = loadScores(); } renderRanking(getTopScores(5)); } /*********************Pause*************************/ function startPause(e) { if (e.repeat) return; if (e.keyCode!=13&&e.keyCode!=32&&e.keyCode!=80) return; if (pause) { stopPause(); return; } if ($('#die').length) { retry(); return; } if ($('#startgame').length) { startGame(); return; } pauseGame(true, 'Paused'); } function stopPause() { pause=false; pauseMessage = ''; $('#pause').remove(); $('.title').remove(); $('#left').fadeOut(300); $('#right').fadeOut(300); toggleSettingsPanel(false); syncCursor(); playMusic(); } /*********************Diamond Effects***************************/ function eatDiamond(f) { if (!died) { playSound('diamondsound'); switch(f) { case 0: var s=ranInt(3,6);showInfo('Score +'+s+'000');func_addScore(s);break; case 1: showInfo(_jiansu);func_slow(2);break; case 2: showInfo(_1up);func_oneUp();break; case 3: showInfo(_wudi);func_wudi(6000);break; case 4: showInfo(_qingping);func_clear();break; case 5: showInfo(_bianxiao);func_small(2);break; } } } function showInfo(s) { var t=clock; $('body').append('
'+s+'
'); $('#info'+t).css('left',pl.x-100+'px'); $('#info'+t).css('top',pl.y-50+'px'); $('#info'+t).fadeOut(1500); } function func_addScore(s) { score+=s*100; } function func_slow(t) { var i; if (slowFactor !== 1) { for (i = 0; i < balls.length; i++) balls[i].speed *= slowFactor; for (i = 0; i < bigBalls.length; i++) bigBalls[i].speed *= slowFactor; for (i = 0; i < butterflys.length; i++) butterflys[i].rspeed *= slowFactor; ballSpeed *= slowFactor; bigBallSpeed *= slowFactor; butterflySpeed *= slowFactor; starSpeed *= slowFactor; ballDensity *= slowFactor; bigBallDensity *= slowFactor; butterflyDensity *= slowFactor; starDensity /= slowFactor; waveSpeed *= slowFactor; window.clearTimeout(slowTimer); slowFactor = 1; } for (i = 0; i < balls.length; i++) balls[i].speed/=t; for (i = 0; i < bigBalls.length; i++) bigBalls[i].speed/=t; for (i = 0; i < butterflys.length; i++) butterflys[i].rspeed/=t; ballSpeed/=t; bigBallSpeed/=t; butterflySpeed/=t; starSpeed/=t; ballDensity/=t; bigBallDensity/=t; butterflyDensity/=t; starDensity*=t; waveSpeed/=t; slowFactor = t; slowTimer=setTimeout(function() { for (var resetBall = 0; resetBall < balls.length; resetBall++) balls[resetBall].speed *= slowFactor; for (var resetBigBall = 0; resetBigBall < bigBalls.length; resetBigBall++) bigBalls[resetBigBall].speed *= slowFactor; for (var resetButterfly = 0; resetButterfly < butterflys.length; resetButterfly++) butterflys[resetButterfly].rspeed *= slowFactor; ballSpeed*=slowFactor; bigBallSpeed*=slowFactor; butterflySpeed*=slowFactor; starSpeed*=slowFactor; ballDensity*=slowFactor; bigBallDensity*=slowFactor; butterflyDensity*=slowFactor; starDensity/=slowFactor; waveSpeed*=slowFactor; slowFactor = 1; },8000); flash=8; } function func_oneUp() { life++; } function func_wudi(time) { if (wudiTimer) window.clearTimeout(wudiTimer); wudi=true; wudiTimer=setTimeout(function() { wudi=false; },time); } function func_clear() { balls=[]; bigBalls=[]; butterflys=[]; stars=[]; flash=8; } function func_small(t) { var i; if (smallFactor !== 1) { for (i = 0; i < bigBalls.length; i++) bigBalls[i].size*=smallFactor; bigBallSize*=smallFactor; bSize*=smallFactor; butterflySize*=smallFactor; starSize*=smallFactor; plSize*=smallFactor; for (i = 0; i < butterflyShape.length; i++) butterflyShape[i].r*=smallFactor; rebuildScaledShapes(); rebuildJudge(20); window.clearTimeout(smallTimer); smallFactor = 1; } for (i = 0; i < bigBalls.length; i++) bigBalls[i].size/=t; bigBallSize/=t; bSize/=t; butterflySize/=t; starSize/=t; plSize/=t; for (i = 0; i < butterflyShape.length; i++) butterflyShape[i].r/=t; rebuildScaledShapes(); rebuildJudge(15); smallFactor = t; smallTimer=setTimeout(function() { for (var resetSize = 0; resetSize < bigBalls.length; resetSize++) bigBalls[resetSize].size*=smallFactor; bigBallSize*=smallFactor; bSize*=smallFactor; butterflySize*=smallFactor; starSize*=smallFactor; plSize*=smallFactor; for (var resetShape = 0; resetShape < butterflyShape.length; resetShape++) butterflyShape[resetShape].r*=smallFactor; rebuildScaledShapes(); rebuildJudge(15); smallFactor = 1; },8000); flash=8; } /*********************Player Death*****************************/ function kill() { if (!wudi&&!died) { life--; showInfo(_life+life); func_wudi(2500); playSound('killsound'); } if (!life) { die(); } } function die() { if (died) return; died=true; clearLoop(); toggleSettingsPanel(false); syncCursor(); var t=clock+score; $('body').append('
'+_gameover+'
'+_scoreis+(t)+'0
'+ '
'+_ranking+'
'+_settings+'
'+_fullscreen+'
'+_tryagain+'
'); addRankingInfo(t*10); layoutPanels(); $('#right2').css('width',150+'px'); $('#right2').css('vertical-align','center'); bindOverlayHover('#ranking', '#right2'); playSound('diesound'); } function retry() { $('#die').remove(); $('.title').remove(); $('.info').remove(); toggleSettingsPanel(false); resetGameState(); applyAudioSettings(); pauseMusic(); $('#music')[0].currentTime=0; clockStart(); playMusic(); syncCursor(); $("#right2").fadeOut(300); }