[解读]html5游戏app_Sinuous

用到的东西

1. canvas

2. js

---

效果图

PC:

Mobile

---

解读

源码:

SinuousWorld=new function(){function j(){if(n==false){playSound("MusicCalmARR");n=true;o=[];w=[];h=0;r=1;A=I=J=K=0;c.trail=[];c.position.x=y;c.position.y=z;c.shield=0;s.style.display="none";q.style.display="block";B.style.display="none";C=(new Date).getTime()}}function t(){playSound("MusicIdleARR");playSound("fx_explosion");n=false;Q=(new Date).getTime()-C;Z();s.style.display="block";h=Math.round(h);R.innerHTML="Game Over! ("+h+" points)";scoreText="Score: <span>"+Math.round(h)+"</span>";scoreText+=
" Time: <span>"+Math.round(((new Date).getTime()-C)/1E3*100)/100+"s</span>";q.innerHTML=scoreText}function $(){for(var a=g.length<10,b=0;b<g.length;b++)if(h>g[b].score){a=true;break}if(a)if(!D.value||D.value==" ")alert("Name can not be empty.");else{aa();B.style.display="none"}}function Z(){ajax.ghs(function(a){if((g=eval(a))&&n==false){a=1;for(var b=0;b<g.length;b++)g[b].score>h&&a++;if(a<10){if(g.length>1)if(b=g.length>=9?g.pop():{}){b.name="";b.score=Math.round(h);b.date="";newHighscoreData=g.slice(0,
a-1);newHighscoreData.push(b);g=newHighscoreData=newHighscoreData.concat(g.slice(a-1));L()}S.innerHTML="You made #"+a+" on the top list!";B.style.display="block"}}})}function ba(){ajax.ghs(function(a){g=eval(a);L()})}function aa(){var a=D.value;ajax.shs(function(b){g=eval(b);L()},"n="+a+"&s="+h*h*3.14159265*Math.max(a.length,1)+"&d="+Math.round(Q/1E3*100)/100+"&sc="+sc+"&fc="+Math.round(K)+"&fs="+Math.round(J)+"&ms="+Math.round(I)+"&cs="+Math.round(A)+"&f="+Math.round((M+N+u)/3))}function L(){if(g){for(var a=
"",b=0;b<g.length;b++){a+="<li>";a+='<span class="place">'+(b+1)+".</span>";a+='<span class="name">'+g[b].name+"</span>";a+='<span class="score">'+g[b].score+" p</span>";a+='<span class="date">'+g[b].date+"</span>";a+="</li>"}T.innerHTML=a}}function ca(a){y=a.clientX-(window.innerWidth-m)*0.5-6;z=a.clientY-(window.innerHeight-l)*0.5-6}function da(){}function ea(){}function fa(a){if(a.touches.length==1){a.preventDefault();y=a.touches[0].pageX-(window.innerWidth-m)*0.5;z=a.touches[0].pageY-(window.innerHeight-
l)*0.5}}function ga(a){if(a.touches.length==1){a.preventDefault();y=a.touches[0].pageX-(window.innerWidth-m)*0.5-60;z=a.touches[0].pageY-(window.innerHeight-l)*0.5-30}}function ha(){}function U(){m=v?window.innerWidth:900;l=v?window.innerHeight:550;k.width=m;k.height=l;var a=(window.innerWidth-m)*0.5,b=(window.innerHeight-l)*0.5;k.style.position="absolute";k.style.left=a+"px";k.style.top=b+"px";if(v){s.style.left="0px";s.style.top="0px";q.style.left="0px";q.style.top="0px"}else{s.style.left=a+6+"px";
s.style.top=b+200+"px";q.style.left=a+6+"px";q.style.top=b+6+"px"}E.style.position="absolute";E.style.left=a+"px";E.style.top=b-20+"px"}function F(a,b){for(var d=10+Math.random()*15;--d>=0;){var i=new Point;i.position.x=a.x+Math.sin(d)*b;i.position.y=a.y+Math.cos(d)*b;i.velocity={x:-4+Math.random()*8,y:-4+Math.random()*8};i.alpha=1;G.push(i)}}function V(){var a=(new Date).getTime();O++;if(a>P+1E3){u=Math.min(Math.round(O*1E3/(a-P)),x);M=Math.min(M,u);N=Math.max(N,u);P=a;O=0}a=0.01+Math.max(Math.min(u,
x),0)/x*0.99;a*=a;f.clearRect(0,0,k.width,k.height);var b={x:H.x*r,y:H.y*r},d,i;if(n){r+=8.0E-4;pp=c.clonePosition();c.position.x+=(y-c.position.x)*0.14;c.position.y+=(z-c.position.y)*0.14;h+=0.4*r*a;h+=c.distanceTo(pp)*0.1*a;K++;J+=0.4*r*a;I+=c.distanceTo(pp)*0.1*a;c.shield=Math.max(c.shield-1,0);if(c.shield>0&&(c.shield>100||c.shield%3!=0)){f.beginPath();f.fillStyle="#167a66";f.strokeStyle="#00ffcc";f.arc(c.position.x,c.position.y,c.size*(Math.min(c.shield,100)/50),0,Math.PI*2,true);f.fill();f.stroke()}c.trail.push(new Point(c.position.x,
c.position.y));f.beginPath();f.strokeStyle="#648d93";f.lineWidth=2;d=0;for(i=c.trail.length;d<i;d++){p=c.trail[d];p2=c.trail[d+1];if(d==0)f.moveTo(p.position.x,p.position.y);else p2&&f.quadraticCurveTo(p.position.x,p.position.y,p.position.x+(p2.position.x-p.position.x)/2,p.position.y+(p2.position.y-p.position.y)/2);p.position.x+=b.x;p.position.y+=b.y}f.stroke();f.closePath();c.trail.length>60&&c.trail.shift();f.beginPath();f.fillStyle="#8ff1ff";f.arc(c.position.x,c.position.y,c.size/2,0,Math.PI*2,
true);f.fill()}if(n&&(c.position.x<0||c.position.x>m||c.position.y<0||c.position.y>l)){F(c.position,10);t()}for(d=0;d<o.length;d++){p=o[d];if(n)if(c.shield>0&&p.distanceTo(c.position)<(c.size*4+p.size)*0.5){playSound("fx_break");F(p.position,10);o.splice(d,1);d--;h+=10*a;A+=10*a;continue}else if(p.distanceTo(c.position)<(c.size+p.size)*0.5){F(c.position,10);t()}f.beginPath();f.fillStyle="#ff0000";f.arc(p.position.x,p.position.y,p.size/2,0,Math.PI*2,true);f.fill();p.position.x+=b.x*p.force;p.position.y+=
b.y*p.force;if(p.position.x<-p.size||p.position.y>l+p.size){o.splice(d,1);d--}}for(d=0;d<w.length;d++){p=w[d];if(p.distanceTo(c.position)<(c.size+p.size)*0.5&&n){playSound("MusicFunARR");playSound("fx_bubble");c.shield=300;for(i=0;i<o.length;i++){e=o[i];if(e.distanceTo(p.position)<100){playSound("fx_break");F(e.position,10);o.splice(i,1);i--;h+=10*a;A+=10*a}}}f.beginPath();f.fillStyle="#00ffcc";f.arc(p.position.x,p.position.y,p.size/2,0,Math.PI*2,true);f.fill();p.position.x+=b.x*p.force;p.position.y+=
b.y*p.force;if(p.position.x<-p.size||p.position.y>l+p.size||c.shield!=0){w.splice(d,1);d--}}o.length<35*r&&o.push(W(new Enemy));w.length<1&&Math.random()>0.997&&c.shield==0&&w.push(W(new Shield));c.shield==1&&n&&playSound("MusicCalmARR");for(d=0;d<G.length;d++){p=G[d];p.velocity.x+=(b.x-p.velocity.x)*0.04;p.velocity.y+=(b.y-p.velocity.y)*0.04;p.position.x+=p.velocity.x;p.position.y+=p.velocity.y;p.alpha-=0.02;f.fillStyle="rgba(255,255,255,"+Math.max(p.alpha,0)+")";f.fillRect(p.position.x,p.position.y,
1,1);p.alpha<=0&&G.splice(d,1)}if(n){scoreText="Score: <span>"+Math.round(h)+"</span>";scoreText+=" Time: <span>"+Math.round(((new Date).getTime()-C)/1E3*100)/100+"s</span>";scoreText+=' <p class="fps">FPS: <span>'+Math.round(u)+" ("+Math.round(Math.max(Math.min(u/x,x),0)*100)+"%)</span></p>";q.innerHTML=scoreText}}function W(a){if(Math.random()>0.5){a.position.x=Math.random()*m;a.position.y=-20}else{a.position.x=m+20;a.position.y=-l*0.2+Math.random()*l*1.2}return a}var v=navigator.userAgent.toLowerCase().indexOf("android")!=
-1||navigator.userAgent.toLowerCase().indexOf("iphone")!=-1||navigator.userAgent.toLowerCase().indexOf("ipad")!=-1,m=v?window.innerWidth:900,l=v?window.innerHeight:550,x=60,k,f,q,s,R,X,E,o=[],w=[],G=[],c,y=window.innerWidth-m,z=window.innerHeight-l,n=false,h=0,C=0,Q=0,r=1,K=0,J=0,I=0,A=0,H={x:-1.3,y:1},u=0,M=1E3,N=0,P=(new Date).getTime(),O=0,g=[],T,B,D,Y,S;this.init=function(){k=document.getElementById("world");s=document.getElementById("panels");q=document.getElementById("status");document.getElementById("message");
R=document.getElementById("title");X=document.getElementById("startButton");E=document.getElementById("seeMore");document.getElementById("highscoreList");T=document.getElementById("highscoreOutput");B=document.getElementById("highscoreWin");D=document.getElementById("highscoreInput");Y=document.getElementById("highscoreSubmit");S=document.getElementById("highscorePlace");if(k&&k.getContext){f=k.getContext("2d");document.addEventListener("mousemove",ca,false);document.addEventListener("mousedown",
da,false);document.addEventListener("mouseup",ea,false);k.addEventListener("touchstart",fa,false);document.addEventListener("touchmove",ga,false);document.addEventListener("touchend",ha,false);window.addEventListener("resize",U,false);X.addEventListener("click",j,false);Y.addEventListener("click",$,false);c=new Player;U();if(v){document.getElementById("sharing").style.display="none";document.getElementById("panel").style.display="none";q.style.width=m+"px";k.style.border="none";H.x*=2;H.y*=2;setInterval(V,
1E3/30)}else setInterval(V,1E3/x);ba();v||swfobject.embedSWF("swf/sound.swf","sound","1","1","9.0.0","",{},{allowScriptAccess:"always"},{id:"soundSWF"})}};ajax={ghs:function(a){var b=new XMLHttpRequest;parameters="m=ghs";b.open("POST","highscore.php",true);b.setRequestHeader("Content-type","application/x-www-form-urlencoded");if(b){b.onreadystatechange=function(){b.readyState==4&&b.status==200&&a(b.responseText)};b.send(parameters)}},shs:function(a,b){var d=new XMLHttpRequest;b+="&m=shs";if(d){d.open("POST",
"highscore.php",true);d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState==4&&d.status==200&&a(d.responseText)};d.send(b)}}}};function Point(j,t){this.position={x:j,y:t}}Point.prototype.distanceTo=function(j){var t=j.x-this.position.x;j=j.y-this.position.y;return Math.sqrt(t*t+j*j)};Point.prototype.clonePosition=function(){return{x:this.position.x,y:this.position.y}};
function Player(){this.position={x:0,y:0};this.trail=[];this.size=8;this.shield=0}Player.prototype=new Point;function Enemy(){this.position={x:0,y:0};this.size=6+Math.random()*4;this.force=1+Math.random()*0.4}Enemy.prototype=new Point;function Shield(){this.position={x:0,y:0};this.size=10+Math.random()*8;this.force=1+Math.random()*0.4}Shield.prototype=new Point;SinuousWorld.init();function sendToJavaScript(j){j=="SoundController ready and loaded!"&&playSound("MusicIdleARR")}
function playSound(j){navigator.userAgent.toLowerCase().indexOf("android")!=-1||navigator.userAgent.toLowerCase().indexOf("iphone")!=-1||navigator.userAgent.toLowerCase().indexOf("ipad")!=-1||document.getElementById("soundSWF").sendToActionScript(j)};
View Code

代码分析:

  1 /*
  2 Object List:
  3 1. SinuousWorld: main Object, the whole game world
  4 2. Point: father Object, subObjects are [Player],[Enemy],[Shield]
  5 3. Player: implements Point
  6 4. Enemy: implements Point
  7 5. Shield: implements Point
  8 -----
  9 Global Function List:
 10 1. *playSound(j): maybe used to judge the webbrowser and play the sound used in mobile [but why not use tag audio?] (call sendToJavaScript)
 11 2. *sendToJavaScript(j): deal with sound
 12 3. ajax: used to get the data about highScore
 13 -----
 14 detail of Object:
 15 --
 16 Point(j,t):
 17     Vars:
 18         position{x=j,y=t}
 19     Function:
 20         Point(j,t) [j=x,t=y]
 21         distanceTo(j) [j={x=..,y=..}]
 22         clonePosition [return {x=..,y=..}]
 23 --
 24 Player:
 25     Var:
 26         position(x=0,y=0)
 27         trail[] (array)
 28         size (int)
 29         shield (flag[0,1])
 30     Function:
 31         Player(j,t) [j=x,t=y]
 32         distanceTo(j) [j={x=..,y=..}]
 33         clonePosition [return {x=..,y=..}]
 34 --
 35 Enemy:
 36     Var:
 37         position(x=0,y=0)
 38         size (int)[random]
 39         force (int)[>=1] (=speed?)
 40     Function:
 41         Player(j,t) [j=x,t=y]
 42         distanceTo(j) [j={x=..,y=..}]
 43         clonePosition [return {x=..,y=..}]
 44 --
 45 Shield(保护罩)
 46     Var:
 47         position(x=0,y=0)
 48         size (int)[random]
 49         force (int)[>=1] (=time?)
 50     Function:
 51         Player(j,t) [j=x,t=y]
 52         distanceTo(j) [j={x=..,y=..}]
 53         clonePosition [return {x=..,y=..}]
 54 --
 55 SinuousWorld(游戏世界)
 56     Var:
 57         v: if is mobile [True] else [False] (=isMobile),
 58         m: if is moblie [fullScreen width] else [900] (=world width),
 59         l: if is moblie [fullScreen height] else [500] (=world height),
 60         x = 60,
 61         k = document.getElementById("world") [# canvas #],
 62         f = canvas.getContext("2d") [used to control canvas],
 63         q = document.getElementById("status"),
 64         s = document.getElementById("panels"),
 65         R = document.getElementById("title"),
 66         X = document.getElementById("startButton"),
 67         E = document.getElementById("seeMore"),
 68         o = [],
 69         w = [],
 70         G = [] (碰撞粒子),
 71         c(new Player),
 72         y: if is mobile [0] else [blank width] (=player's position left),
 73         z: if is mobile [0] else [blank height] (=player's position top),
 74         n = false,
 75         h = 0 (=Score),
 76         C = 0,
 77         Q = 0,
 78         r = 1,
 79         K = 0,
 80         J = 0,
 81         I = 0,
 82         A = 0,
 83         H = {
 84             x: -1.3,
 85             y: 1
 86         }, (方向向量,碰撞粒子有被向左下角吹去的效果)
 87         u = 0 (=FPS),
 88         M = 1E3,
 89         N = 0,
 90         P = (new Date).getTime() (=timer?),
 91         O = 0,
 92         g = [],
 93         T = document.getElementById("highscoreOutput"),
 94         B = document.getElementById("highscoreWin"),
 95         D = document.getElementById("highscoreInput"),
 96         Y = document.getElementById("highscoreSubmit"),
 97         S = document.getElementById("highscorePlace");
 98     Function:
 99         init: 
100             1. initialize the Game World's vars,
101             2. bind the event
102                 1) doc mousemove -> ca
103                 2) doc mousedown -> da
104                 3) doc mouseup -> ea
105                 4) canvas touchstart -> fa
106                 5) doc touchmove -> ga
107                 6) doc touchend -> ha
108                 7) window resize -> U
109                 8) X[startButton] click -> j
110                 9) Y[highscoreSubmit] click -> $ (why you use the dollor singal.... )
111             3. new Player
112             4. call U() to resize the window;
113             5. if is mobile
114                 hide [sharing] and [panel]
115                 set [status] fullscreen width
116                 set [world] no border
117                 H.x *= 2;
118                 H.y *= 2;
119                 setInterval(V, 1E3 / 30) [每秒30帧,执行V]
120                esle
121                 setInterval(V, 1E3 / x) [每秒60帧,执行V]
122             6. call ba() [deal with score]
123             7. dealwith sound [something with mobile and swf]
124         U:
125             resize
126                 [world(width,height,left,top)],
127                 [panels/status(left,top)],
128                 [seeMore(left,top)]
129         ba: dealwith highScore
130         ca(a): [doc mousemove]
131             y = a.clientX - (window.innerWidth - m) * 0.5 - 6 (=player's position left)
132             z = a.clientY - (window.innerHeight - l) * 0.5 - 6 (=player's position top)
133         da: [doc mousedown]
134             empty
135         ea: [doc mouseup]
136             empty
137         fa(a): [canvas touchstart]
138             if (a.touches.length == 1) {
139                 a.preventDefault();
140                 y = a.touches[0].pageX - (window.innerWidth - m) * 0.5
141                 z = a.touches[0].pageY - (window.innerHeight - l) * 0.5
142             }
143         ga(a): [doc touchmove]
144             if (a.touches.length == 1) {
145                 a.preventDefault();
146                 y = a.touches[0].pageX - (window.innerWidth - m) * 0.5 - 60
147                 z = a.touches[0].pageY - (window.innerHeight - l) * 0.5 - 30
148             }
149         ha: [doc touchend]
150             empty
151         $: deal with submit score and highscore
152         j:
153             if n == false(first time[initialzie vars when click to play])
154                 1. play sound
155                 2. init var
156                     n = true
157                     o = []
158                     w = []
159                     h = 0
160                     r = 1
161                     A,I,J,K = 0
162                     c.trail = []
163                     c.position.x = y;
164                     c.position.y = z;
165                     c.shield = 0
166                     C =  startTime (now)
167                     [panels] hide
168                     [status] show
169                     [highscoreWin] hide
170         V: ***Main function***
171             0. get now time to Var a
172             1. O = 0, ++; count the call times (used to calcute the FPS)
173             2. per second update the FPS and set MaxFPS -> N, MinFPS -> M
174             3. calculate a......
175             4. clear canvas
176             5. if is playing
177                 r += 8.0E-4; (init = 1)
178                 // 记录当前Player位置
179                 pp = c.clonePosition();
180                 // 延迟移动
181                 c.position.x += (y - c.position.x) * 0.14;
182                 c.position.y += (z - c.position.y) * 0.14;
183                 h += 0.4 * r * a;
184                 h += c.distanceTo(pp) * 0.1 * a;
185                 K++;
186                 J += 0.4 * r * a;
187                 I += c.distanceTo(pp) * 0.1 * a;
188                 // 保护罩
189                 c.shield = Math.max(c.shield - 1, 0);
190                 if (c.shield > 0 && (c.shield > 100 || c.shield % 3 != 0)) {
191                     f.beginPath();
192                     f.fillStyle = "#167a66";
193                     f.strokeStyle = "#00ffcc";
194                     f.arc(c.position.x, c.position.y, c.size * (Math.min(c.shield, 100) / 50), 0, Math.PI * 2, true);
195                     f.fill();
196                     f.stroke()
197                 }
198                 // 尾巴
199                 c.trail.push(new Point(c.position.x, c.position.y));
200                 f.beginPath();
201                 f.strokeStyle = "#648d93";
202                 f.lineWidth = 2;
203                 d = 0;
204                 for (i = c.trail.length; d < i; d++) {
205                     p = c.trail[d];
206                     p2 = c.trail[d + 1];
207                     if (d == 0) f.moveTo(p.position.x, p.position.y);
208                     // 二次贝塞尔曲线
209                     else p2 && f.quadraticCurveTo(p.position.x, p.position.y, p.position.x + (p2.position.x - p.position.x) / 2, p.position.y + (p2.position.y - p.position.y) / 2);
210                     p.position.x += b.x;
211                     p.position.y += b.y
212                 }
213                 f.stroke();
214                 f.closePath();
215                 c.trail.length > 60 && c.trail.shift();
216                 // draw Player
217                 f.beginPath();
218                 f.fillStyle = "#8ff1ff";
219                 f.arc(c.position.x, c.position.y, c.size / 2, 0, Math.PI * 2, true);
220                 f.fill()
221             6. 
222                 // 如果Player超出可见范围
223                 if (n && (c.position.x < 0 || c.position.x > m || c.position.y < 0 || c.position.y > l)) {
224                     // 发生碰撞
225                     F(c.position, 10);
226                     // game over
227                     t()
228                 }
229             7.
230                 // draw Enemy
231                 for (d = 0; d < o.length; d++) {
232                     p = o[d];
233                     if (n) if (c.shield > 0 && p.distanceTo(c.position) < (c.size * 4 + p.size) * 0.5) {
234                         // crash to Player and Be killed
235                         playSound("fx_break");
236                         F(p.position, 10);
237                         o.splice(d, 1);
238                         d--;
239                         h += 10 * a;
240                         A += 10 * a;
241                         continue
242                     } else if (p.distanceTo(c.position) < (c.size + p.size) * 0.5) {
243                         // crash to Player and Game Over
244                         F(c.position, 10);
245                         // game over
246                         t()
247                     }
248                     // draw Enemy
249                     f.beginPath();
250                     f.fillStyle = "#ff0000";
251                     f.arc(p.position.x, p.position.y, p.size / 2, 0, Math.PI * 2, true);
252                     f.fill();
253                     // move itself
254                     p.position.x += b.x * p.force;
255                     p.position.y += b.y * p.force;
256                     // ??
257                     if (p.position.x < -p.size || p.position.y > l + p.size) {
258                         o.splice(d, 1);
259                         d--
260                     }
261                 }
262             8.
263                 // draw 保护罩
264                 for (d = 0; d < w.length; d++) {
265                     p = w[d];
266                     if (p.distanceTo(c.position) < (c.size + p.size) * 0.5 && n) {
267                         // 吃到保护罩
268                         playSound("MusicFunARR");
269                         playSound("fx_bubble");
270                         c.shield = 300;
271                         for (i = 0; i < o.length; i++) {
272                             // 马上消灭Enemy
273                             e = o[i];
274                             if (e.distanceTo(p.position) < 100) {
275                                 playSound("fx_break");
276                                 F(e.position, 10);
277                                 o.splice(i, 1);
278                                 i--;
279                                 h += 10 * a;
280                                 A += 10 * a
281                             }
282                         }
283                     }
284                     // draw 保护罩
285                     f.beginPath();
286                     f.fillStyle = "#00ffcc";
287                     f.arc(p.position.x, p.position.y, p.size / 2, 0, Math.PI * 2, true);
288                     f.fill();
289                     // move 保护罩
290                     p.position.x += b.x * p.force;
291                     p.position.y += b.y * p.force;
292                     if (p.position.x < -p.size || p.position.y > l + p.size || c.shield != 0) {
293                         // 消除保护罩,Player 无法吃多个保护罩
294                         w.splice(d, 1);
295                         d--
296                     }
297                 }
298             9.
299                 // 生成 enemy
300                 o.length < 35 * r && o.push(W(new Enemy));
301                 // 生成 保护罩
302                 w.length < 1 && Math.random() > 0.997 && c.shield == 0 && w.push(W(new Shield));
303                 // 保护罩消失前提示
304                 c.shield == 1 && n && playSound("MusicCalmARR");
305             10.
306                 // draw碰撞粒子
307                 for (d = 0; d < G.length; d++) {
308                     p = G[d];
309                     p.velocity.x += (b.x - p.velocity.x) * 0.04;
310                     p.velocity.y += (b.y - p.velocity.y) * 0.04;
311                     p.position.x += p.velocity.x;
312                     p.position.y += p.velocity.y;
313                     p.alpha -= 0.02;
314                     f.fillStyle = "rgba(255,255,255," + Math.max(p.alpha, 0) + ")";
315                     f.fillRect(p.position.x, p.position.y, 1, 1);
316                     p.alpha <= 0 && G.splice(d, 1)
317                 }
318             11.
319                 // update the score and status
320                 // also show the FPS(播放速度 帧/秒)
321                 if (n) {
322                     scoreText = "Score: <span>" + Math.round(h) + "</span>";
323                     scoreText += " Time: <span>" + Math.round(((new Date).getTime() - C) / 1E3 * 100) / 100 + "s</span>";
324                     scoreText += ' <p class="fps">FPS: <span>' + Math.round(u) + " (" + Math.round(Math.max(Math.min(u / x, x), 0) * 100) + "%)</span></p>";
325                     q.innerHTML = scoreText
326                 }
327         W(a):
328             随机Enemy's Position
329 代码混淆后,识别还真不容易,还好这个代码写得简单易懂。 哈哈
330 ------
331 js拓展
332 1.
333     Array.splice()
334     它可以用于插入、删除或替换数组的元素
335         1)删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数)
336         2)插入-向数组指定位置插入任意项元素。三个参数,第一个参数(其实位置),第二个参数(0),第三个参数(插入的项)
337         3)替换-向数组指定位置插入任意项元素,同时删除任意数量的项,三个参数。第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项) 
338 
339 */

修改后的代码:(因为太懒,去掉了很多功能)

  1 /*
  2 * 迷你无声单机版 (^◇^)
  3 * 偷懒就不重命名 代码混乱后的代码了
  4 * 也是偷懒,把声音去掉吧
  5 * 索性再偷懒下,就只留一个canvas 和 分数 吧
  6 */
  7 SinuousWorld = new
  8 function() {
  9     function j() {
 10         /*click start*/
 11         if (n == false) {
 12             //playSound("MusicCalmARR");
 13             n = true;
 14             o = [];
 15             w = [];
 16             h = 0;
 17             r = 1;
 18             A = I = J = K = 0;
 19             c.trail = [];
 20             c.position.x = y;
 21             c.position.y = z;
 22             c.shield = 0;
 23             //s.style.display = "none";
 24             //q.style.display = "block";
 25             //B.style.display = "none";
 26             C = (new Date).getTime();
 27         }
 28     }
 29     /*game finish and show the score*/
 30     function t() {
 31         //playSound("MusicIdleARR");
 32         //playSound("fx_explosion");
 33         n = false; // finish flag
 34         Q = (new Date).getTime() - C;
 35         //Z();
 36         //s.style.display = "block";
 37         h = Math.round(h);
 38         //R.innerHTML = "Game Over! (" + h + " points)";
 39         //scoreText = "Score: <span>" + Math.round(h) + "</span>";
 40         //scoreText += " Time: <span>" + Math.round(((new Date).getTime() - C) / 1E3 * 100) / 100 + "s</span>";
 41         //q.innerHTML = scoreText
 42         btn_ss.style.display = "inline";
 43     }
 44     /*deal with score >delete*/
 45     /*function $() {
 46         for (var a = g.length < 10,
 47         b = 0; b < g.length; b++) if (h > g[b].score) {
 48             a = true;
 49             break
 50         }
 51         if (a) if (!D.value || D.value == " ") alert("Name can not be empty.");
 52         else {
 53             aa();
 54             B.style.display = "none"
 55         }
 56     }*/
 57     /*deal with score >delete*/
 58     /*
 59     function Z() {
 60         ajax.ghs(function(a) {
 61             if ((g = eval(a)) && n == false) {
 62                 a = 1;
 63                 for (var b = 0; b < g.length; b++) g[b].score > h && a++;
 64                 if (a < 10) {
 65                     if (g.length > 1) if (b = g.length >= 9 ? g.pop() : {}) {
 66                         b.name = "";
 67                         b.score = Math.round(h);
 68                         b.date = "";
 69                         newHighscoreData = g.slice(0, a - 1);
 70                         newHighscoreData.push(b);
 71                         g = newHighscoreData = newHighscoreData.concat(g.slice(a - 1));
 72                         L()
 73                     }
 74                     S.innerHTML = "You made #" + a + " on the top list!";
 75                     B.style.display = "block"
 76                 }
 77             }
 78         })
 79     }*/
 80     /*deal with score >delete*/
 81     /*function ba() {
 82         ajax.ghs(function(a) {
 83             g = eval(a);
 84             L()
 85         })
 86     }*/
 87     /*deal with score >delete*/
 88     /*function aa() {
 89         var a = D.value;
 90         ajax.shs(function(b) {
 91             g = eval(b);
 92             L()
 93         },
 94         "n=" + a + "&s=" + h * h * 3.14159265 * Math.max(a.length, 1) + "&d=" + Math.round(Q / 1E3 * 100) / 100 + "&sc=" + sc + "&fc=" + Math.round(K) + "&fs=" + Math.round(J) + "&ms=" + Math.round(I) + "&cs=" + Math.round(A) + "&f=" + Math.round((M + N + u) / 3))
 95     }*/
 96     /*deal with score >delete*/
 97     /*function L() {
 98         if (g) {
 99             for (var a = "",
100             b = 0; b < g.length; b++) {
101                 a += "<li>";
102                 a += '<span class="place">' + (b + 1) + ".</span>";
103                 a += '<span class="name">' + g[b].name + "</span>";
104                 a += '<span class="score">' + g[b].score + " p</span>";
105                 a += '<span class="date">' + g[b].date + "</span>";
106                 a += "</li>"
107             }
108             T.innerHTML = a
109         }
110     }*/
111     /*[doc mousemove]*/
112     function ca(a) {
113         y = a.clientX - (window.innerWidth - m) * 0.5 - 6;
114         z = a.clientY - (window.innerHeight - l) * 0.5 - 6
115     }
116     /*[doc mousedown]*/
117     function da() {}
118     /*[doc mouseup]*/
119     function ea() {}
120     /*[canvas touchstart]*/
121     function fa(a) {
122         if (a.touches.length == 1) {
123             a.preventDefault();
124             y = a.touches[0].pageX - (window.innerWidth - m) * 0.5;
125             z = a.touches[0].pageY - (window.innerHeight - l) * 0.5
126         }
127     }
128     /*[doc touchmove]*/
129     function ga(a) {
130         if (a.touches.length == 1) {
131             a.preventDefault();
132             y = a.touches[0].pageX - (window.innerWidth - m) * 0.5 - 60;
133             z = a.touches[0].pageY - (window.innerHeight - l) * 0.5 - 30
134         }
135     }
136     /*[doc touchend]*/
137     function ha() {}
138     /*add btn_ss_click*/
139     function btn_ss_click(e){
140         e.preventDefault();
141         btn_ss.style.display = "none";
142         n = false;
143         j();
144     }
145     /*resize*/
146     function U() {
147         m = v ? window.innerWidth: 900;
148         l = v ? window.innerHeight: 550;
149         k.width = m;
150         k.height = l;
151         var a = (window.innerWidth - m) * 0.5,
152         b = (window.innerHeight - l) * 0.5;
153         k.style.position = "absolute";
154         /*add 简单点,直接居中*/
155         k.style.left = a + "px";
156         k.style.top = b +"px";
157         /* add start ,score */
158         var btn_ss_l = (window.innerWidth - 100) * 0.5,
159         btn_ss_l_t = (window.innerHeight - 50) * 0.5;
160         btn_ss.style.position = "absolute";
161         btn_ss.style.left = btn_ss_l + "px";
162         btn_ss.style.top = btn_ss_l_t + "px";
163         btn_p.style.width = m + "px";
164         btn_p.style.position = "absolute";
165         btn_p.style.left = a + "px";
166         btn_p.style.top = b + ( v ? 0 : 6 ) + "px";
167         /*k.style.left = a + "px";
168         k.style.top = b + "px";
169         if (v) {
170             s.style.left = "0px";
171             s.style.top = "0px";
172             q.style.left = "0px";
173             q.style.top = "0px"
174         } else {
175             s.style.left = a + 6 + "px";
176             s.style.top = b + 200 + "px";
177             q.style.left = a + 6 + "px";
178             q.style.top = b + 6 + "px"
179         }
180         E.style.position = "absolute";
181         E.style.left = a + "px";
182         E.style.top = b - 20 + "px"*/
183     }
184     /*添加撞击粒子*/
185     function F(a, b) {
186         for (var d = 10 + Math.random() * 15; --d >= 0;) {
187             var i = new Point;
188             i.position.x = a.x + Math.sin(d) * b;
189             i.position.y = a.y + Math.cos(d) * b;
190             i.velocity = {
191                 x: -4 + Math.random() * 8,
192                 y: -4 + Math.random() * 8
193             };
194             i.alpha = 1;
195             G.push(i)
196         }
197     }
198     /*游戏动画*/
199     function V() {
200         var a = (new Date).getTime();
201         O++;
202         if (a > P + 1E3) {
203             u = Math.min(Math.round(O * 1E3 / (a - P)), x);
204             M = Math.min(M, u);
205             N = Math.max(N, u);
206             P = a;
207             O = 0
208         }
209         a = 0.01 + Math.max(Math.min(u, x), 0) / x * 0.99;
210         a *= a;
211         f.clearRect(0, 0, k.width, k.height);
212         var b = {
213             x: H.x * r,
214             y: H.y * r
215         },
216         d,
217         i;
218         if (n) {
219             r += 8.0E-4;
220             pp = c.clonePosition();
221             c.position.x += (y - c.position.x) * 0.14;
222             c.position.y += (z - c.position.y) * 0.14;
223             h += 0.4 * r * a;
224             h += c.distanceTo(pp) * 0.1 * a;
225             K++;
226             J += 0.4 * r * a;
227             I += c.distanceTo(pp) * 0.1 * a;
228             c.shield = Math.max(c.shield - 1, 0);
229             if (c.shield > 0 && (c.shield > 100 || c.shield % 3 != 0)) {
230                 f.beginPath();
231                 f.fillStyle = "#167a66";
232                 f.strokeStyle = "#00ffcc";
233                 f.arc(c.position.x, c.position.y, c.size * (Math.min(c.shield, 100) / 50), 0, Math.PI * 2, true);
234                 f.fill();
235                 f.stroke()
236             }
237             c.trail.push(new Point(c.position.x, c.position.y));
238             f.beginPath();
239             f.strokeStyle = "#648d93";
240             f.lineWidth = 2;
241             d = 0;
242             for (i = c.trail.length; d < i; d++) {
243                 p = c.trail[d];
244                 p2 = c.trail[d + 1];
245                 if (d == 0) f.moveTo(p.position.x, p.position.y);
246                 else p2 && f.quadraticCurveTo(p.position.x, p.position.y, p.position.x + (p2.position.x - p.position.x) / 2, p.position.y + (p2.position.y - p.position.y) / 2);
247                 p.position.x += b.x;
248                 p.position.y += b.y
249             }
250             f.stroke();
251             f.closePath();
252             c.trail.length > 60 && c.trail.shift();
253             f.beginPath();
254             f.fillStyle = "#8ff1ff";
255             f.arc(c.position.x, c.position.y, c.size / 2, 0, Math.PI * 2, true);
256             f.fill()
257         }
258         if (n && (c.position.x < 0 || c.position.x > m || c.position.y < 0 || c.position.y > l)) {
259             F(c.position, 10);
260             t()
261         }
262         for (d = 0; d < o.length; d++) {
263             p = o[d];
264             if (n) if (c.shield > 0 && p.distanceTo(c.position) < (c.size * 4 + p.size) * 0.5) {
265                 //playSound("fx_break");
266                 F(p.position, 10);
267                 o.splice(d, 1);
268                 d--;
269                 h += 10 * a;
270                 A += 10 * a;
271                 continue
272             } else if (p.distanceTo(c.position) < (c.size + p.size) * 0.5) {
273                 F(c.position, 10);
274                 t()
275             }
276             f.beginPath();
277             f.fillStyle = "#ff0000";
278             f.arc(p.position.x, p.position.y, p.size / 2, 0, Math.PI * 2, true);
279             f.fill();
280             p.position.x += b.x * p.force;
281             p.position.y += b.y * p.force;
282             if (p.position.x < -p.size || p.position.y > l + p.size) {
283                 o.splice(d, 1);
284                 d--
285             }
286         }
287         for (d = 0; d < w.length; d++) {
288             p = w[d];
289             if (p.distanceTo(c.position) < (c.size + p.size) * 0.5 && n) {
290                 //playSound("MusicFunARR");
291                 //playSound("fx_bubble");
292                 c.shield = 300;
293                 for (i = 0; i < o.length; i++) {
294                     e = o[i];
295                     if (e.distanceTo(p.position) < 100) {
296                         //playSound("fx_break");
297                         F(e.position, 10);
298                         o.splice(i, 1);
299                         i--;
300                         h += 10 * a;
301                         A += 10 * a
302                     }
303                 }
304             }
305             f.beginPath();
306             f.fillStyle = "#00ffcc";
307             f.arc(p.position.x, p.position.y, p.size / 2, 0, Math.PI * 2, true);
308             f.fill();
309             p.position.x += b.x * p.force;
310             p.position.y += b.y * p.force;
311             if (p.position.x < -p.size || p.position.y > l + p.size || c.shield != 0) {
312                 w.splice(d, 1);
313                 d--
314             }
315         }
316         o.length < 35 * r && o.push(W(new Enemy));
317         w.length < 1 && Math.random() > 0.997 && c.shield == 0 && w.push(W(new Shield));
318         //c.shield == 1 && n && playSound("MusicCalmARR");
319         for (d = 0; d < G.length; d++) {
320             p = G[d];
321             p.velocity.x += (b.x - p.velocity.x) * 0.04;
322             p.velocity.y += (b.y - p.velocity.y) * 0.04;
323             p.position.x += p.velocity.x;
324             p.position.y += p.velocity.y;
325             p.alpha -= 0.02;
326             f.fillStyle = "rgba(255,255,255," + Math.max(p.alpha, 0) + ")";
327             f.fillRect(p.position.x, p.position.y, 1, 1);
328             p.alpha <= 0 && G.splice(d, 1)
329         }
330         if (n) {
331             /*scoreText = "Score: <span>" + Math.round(h) + "</span>";
332             scoreText += " Time: <span>" + Math.round(((new Date).getTime() - C) / 1E3 * 100) / 100 + "s</span>";
333             scoreText += ' <p class="fps">FPS: <span>' + Math.round(u) + " (" + Math.round(Math.max(Math.min(u / x, x), 0) * 100) + "%)</span></p>";*/
334             //q.innerHTML = scoreText
335             scoreText = "得分: <span style='color:lightblue;'> " + Math.round(h) + " </span>";
336             scoreText += " 持续: <span style='color:lightblue;'>" + Math.round(((new Date).getTime() - C) / 1E3 * 100) / 100 + "秒</span>";
337             scoreText += "<span style='float:right;'>FPS: <span style='color:lightblue;'>" + Math.round(u) + " (" + Math.round(Math.max(Math.min(u / x, x), 0) * 100) + "%)</span></span>";
338             btn_p.innerHTML = scoreText;
339         }
340     }
341     /*generate enemy*/
342     function W(a) {
343         if (Math.random() > 0.5) {
344             a.position.x = Math.random() * m;
345             a.position.y = -20
346         } else {
347             a.position.x = m + 20;
348             a.position.y = -l * 0.2 + Math.random() * l * 1.2
349         }
350         return a
351     }
352     var v = navigator.userAgent.toLowerCase().indexOf("android") != -1 || navigator.userAgent.toLowerCase().indexOf("iphone") != -1 || navigator.userAgent.toLowerCase().indexOf("ipad") != -1,
353     m = v ? window.innerWidth: 900,
354     l = v ? window.innerHeight: 550,
355     x = 60,
356     k,
357     f,
358     q,
359     s,
360     R,
361     X,
362     E,
363     o = [],
364     w = [],
365     G = [],
366     c,
367     y = window.innerWidth - m,
368     z = window.innerHeight - l,
369     n = false,
370     h = 0,
371     C = 0,
372     Q = 0,
373     r = 1,
374     K = 0,
375     J = 0,
376     I = 0,
377     A = 0,
378     H = {
379         x: -1.3,
380         y: 1
381     },
382     u = 0,
383     M = 1E3,
384     N = 0,
385     P = (new Date).getTime(),
386     O = 0,
387     g = [],
388     T,
389     B,
390     D,
391     Y,
392     S,
393     //add
394     btn_ss,
395     btn_p;
396     this.init = function() {
397         /*canvas*/
398         k = document.getElementById("world");
399         btn_ss = document.getElementById("btn_ss");
400         btn_p = document.getElementById("btn_p");
401         //s = document.getElementById("panels");
402         //q = document.getElementById("status");
403         //document.getElementById("message");
404         //R = document.getElementById("title");
405         //X = document.getElementById("startButton");
406         //E = document.getElementById("seeMore");
407         //document.getElementById("highscoreList");
408         //T = document.getElementById("highscoreOutput");
409         //B = document.getElementById("highscoreWin");
410         //D = document.getElementById("highscoreInput");
411         //Y = document.getElementById("highscoreSubmit");
412         //S = document.getElementById("highscorePlace");
413         if (k && k.getContext) {
414             f = k.getContext("2d");
415             document.addEventListener("mousemove", ca, false);
416             document.addEventListener("mousedown", da, false);
417             document.addEventListener("mouseup", ea, false);
418             k.addEventListener("touchstart", fa, false);
419             document.addEventListener("touchmove", ga, false);
420             document.addEventListener("touchend", ha, false);
421             window.addEventListener("resize", U, false);
422             /*start botton event*/
423             btn_ss.addEventListener("touchstart", btn_ss_click, false);
424             btn_ss.addEventListener("click", btn_ss_click, false);
425             //X.addEventListener("click", j, false);
426             //Y.addEventListener("click", $, false);
427             c = new Player;
428             U();
429             if (v) {
430                 /*deal with sharing and some others*/
431                 //document.getElementById("sharing").style.display = "none";
432                 //document.getElementById("panel").style.display = "none";
433                 //q.style.width = m + "px";
434                 /*是手机的时候*/
435                 k.style.border = "none";
436                 H.x *= 2;
437                 H.y *= 2;
438                 setInterval(V, 1E3 / 30)
439             } else setInterval(V, 1E3 / x);
440             //ba();
441             /*v || swfobject.embedSWF("swf/sound.swf", "sound", "1", "1", "9.0.0", "", {},
442             {
443                 allowScriptAccess: "always"
444             },
445             {
446                 id: "soundSWF"
447             })*/
448         }
449     };
450     /*deal with score >delete*/
451     /*ajax = {
452         ghs: function(a) {
453             var b = new XMLHttpRequest;
454             parameters = "m=ghs";
455             b.open("POST", "highscore.php", true);
456             b.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
457             if (b) {
458                 b.onreadystatechange = function() {
459                     b.readyState == 4 && b.status == 200 && a(b.responseText)
460                 };
461                 b.send(parameters)
462             }
463         },
464         shs: function(a, b) {
465             var d = new XMLHttpRequest;
466             b += "&m=shs";
467             if (d) {
468                 d.open("POST", "highscore.php", true);
469                 d.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
470                 d.onreadystatechange = function() {
471                     d.readyState == 4 && d.status == 200 && a(d.responseText)
472                 };
473                 d.send(b)
474             }
475         }
476     }*/
477 };
478 function Point(j, t) {
479     this.position = {
480         x: j,
481         y: t
482     }
483 }
484 Point.prototype.distanceTo = function(j) {
485     var t = j.x - this.position.x;
486     j = j.y - this.position.y;
487     return Math.sqrt(t * t + j * j)
488 };
489 Point.prototype.clonePosition = function() {
490     return {
491         x: this.position.x,
492         y: this.position.y
493     }
494 };
495 function Player() {
496     this.position = {
497         x: 0,
498         y: 0
499     };
500     this.trail = [];
501     this.size = 8;
502     this.shield = 0
503 }
504 Player.prototype = new Point;
505 function Enemy() {
506     this.position = {
507         x: 0,
508         y: 0
509     };
510     this.size = 6 + Math.random() * 4;
511     this.force = 1 + Math.random() * 0.4
512 }
513 Enemy.prototype = new Point;
514 function Shield() {
515     this.position = {
516         x: 0,
517         y: 0
518     };
519     this.size = 10 + Math.random() * 8;
520     this.force = 1 + Math.random() * 0.4
521 }
522 Shield.prototype = new Point;
523 SinuousWorld.init();
524 /*deal with sound >delete*/
525 /*function sendToJavaScript(j) {
526     j == "SoundController ready and loaded!" && playSound("MusicIdleARR")
527 }
528 function playSound(j) {
529     navigator.userAgent.toLowerCase().indexOf("android") != -1 || navigator.userAgent.toLowerCase().indexOf("iphone") != -1 || navigator.userAgent.toLowerCase().indexOf("ipad") != -1 || document.getElementById("soundSWF").sendToActionScript(j)
530 };*/

---

CSDN下载:

http://download.csdn.net/detail/wangxsh42/7566753

原文地址:https://www.cnblogs.com/wangxinsheng/p/3814519.html