用到的东西
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)};
代码分析:
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下载: