• [解读]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

  • 相关阅读:
    性能测试入门
    PHP基础
    SpringCloud五大核心组件
    selenium(八)持续集成
    四种隔离级别和脏读、幻读、不可重复读
    RocketMQ【目录】
    ModelAgnostic Counterfactual Reasoning for Eliminating Popularity Bias in Recommender System
    How Powerful is Graph Convolution for Recommendation?
    ScoreBased Generative Modeling through Stochastic Differential Equations
    Graph Embedding for Recommendation against Attribute Inference Attacks
  • 原文地址:https://www.cnblogs.com/wangxinsheng/p/3814519.html
Copyright © 2020-2023  润新知