类似于是XX就坚持5秒的页游,控制星星躲开球体碰撞。PC端可用键盘上下左右控制,手机端可用重力感应控制。已知的问题是碰撞有点不准确,有功夫的话改用像素检测会好很多。另外在稍低端的手机上会有点卡顿,性能优化是个难题。

demo:http://wx.karlew.com/star/

  1. <!doctype html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8">
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.     <title>你能撑过10秒吗</title>
  7.     <style>
  8.         html,body{
  9.             overflow: hidden;
  10.             margin: 0;
  11.             padding: 0;
  12.         }
  13.     </style>
  14. </head>
  15. <body>
  16.     <canvas id="canvas" width="300px" height="300px">您的浏览器不支持canvas</canvas>
  17.     <div style="display: none;">
  18.         <img id="star_img" src="http://wx.karlew.com/star/star.png">
  19.     </div>
  20. </body>
  21. <script>
  22.     var canvas = document.getElementById("canvas");
  23.     var ctx = canvas.getContext("2d");
  24.     var cw = window.innerWidth;
  25.     var ch = window.innerHeight;
  26.     canvas.width = cw;
  27.     canvas.height = ch;
  28.     var starImg = document.getElementById("star_img");
  29.     var star = {
  30.         x:cw/2,
  31.         y:ch/2,
  32.         speedX:0,
  33.         speedY:0,
  34.         size:60,
  35.         time:0
  36.     }
  37.     items = [];
  38.     itemSize = 12;
  39.     itemsCount = 0;
  40.     itemsMax = 49;
  41.     itemSpeed = 5;
  42.     //先创建十个初始球类
  43.     for(var i=0;i<10;i++){
  44.         pushItem();
  45.     }
  46.     //每0.2秒增加一个球
  47.     intPushItem = setInterval(pushItem, 200);
  48.     function pushItem(){
  49.         var randNum = parseInt(Math.random()*4);
  50.         itemsCount++;
  51.         if(itemsCount>itemsMax){
  52.             clearInterval(intPushItem);
  53.             clearInterval(intDraw);
  54.             if(confirm("you win: "+itemsCount/5+"s, again?")){
  55.                 location.reload();
  56.             }
  57.         }
  58.         var item = {
  59.             x:0,
  60.             y:0,
  61.             speedX:0,
  62.             speedY:0,
  63.             covar:Math.random()+0.2  //自定义随机速度系数,为了让球类速度不一样
  64.         }
  65.         switch (randNum) {
  66.             case 0:
  67.                 item.x=0
  68.                 item.y=Math.random()*ch
  69.                 break;
  70.             case 1:
  71.                 item.x=Math.random()*cw
  72.                 item.y=0
  73.                 break;
  74.             case 2:
  75.                 item.x=cw
  76.                 item.y=Math.random()*ch
  77.                 break;
  78.             case 3:
  79.                 item.x=Math.random()*cw
  80.                 item.y=ch
  81.                 break;
  82.             default:
  83.                 break;
  84.         }
  85.         items.push(item)
  86.     }
  87.     setTime = 18;
  88.     intDraw = setInterval(drawCanvas, setTime);
  89.     function drawCanvas(){
  90.         ctx.clearRect(0,0,cw,ch);
  91.         drawStar();
  92.         drawItem();
  93.         //判断是否碰到四周边缘
  94.         if(star.x-star.size/2<0||star.y-star.size/2<0||star.x+star.size/2>cw||star.y+star.size/2>ch){
  95.             clearInterval(intPushItem);
  96.             clearInterval(intDraw);
  97.             if(confirm("you lose: "+itemsCount/5+"s, again?")){
  98.                 location.reload();
  99.             }
  100.         }
  101.     }
  102.     function drawStar(){
  103.         star.x += star.speedX;
  104.         star.y += star.speedY;
  105.         ctx.save();
  106.         ctx.translate(star.x, star.y);  //重置始点坐标为星星中心点    
  107.         ctx.rotate(star.time * Math.PI / 180);  //旋转角度
  108.         ctx.beginPath();
  109.         ctx.drawImage(starImg,-star.size/2, -star.size/2,star.size,star.size);
  110.         ctx.closePath();
  111.         ctx.restore();
  112.         star.time += 4;
  113.     }
  114.     function drawItem(){
  115.         items.forEach(function(item){
  116.             var dist = Math.sqrt(Math.pow(item.x-star.x,2) + Math.pow(item.y-star.y,2));
  117.             if(Math.abs(dist)<itemSize+star.size/2){
  118.                 clearInterval(intPushItem);
  119.                 clearInterval(intDraw);
  120.                 if(confirm("you lose: "+itemsCount/5+"s, again?")){
  121.                     location.reload();
  122.                 }
  123.             }
  124.             var speedNarrow = 0.007/setTime; //用于限制球类速度
  125.             if(Math.abs(item.speedX+(star.x-item.x)*speedNarrow)<=10){
  126.                 item.speedX += (star.x-item.x)*speedNarrow;
  127.             }
  128.             if(Math.abs(item.speedY+(star.y-item.y)*speedNarrow)<=10){
  129.                 item.speedY += (star.y-item.y)*speedNarrow;
  130.             }
  131.             item.x += item.speedX*item.covar;
  132.             item.y += item.speedY*item.covar;
  133.             ctx.beginPath();
  134.             ctx.arc(item.x, item.y, itemSize, 0, 360, false);
  135.             ctx.closePath();
  136.             ctx.fillStyle = "#D26962";
  137.             ctx.fill();
  138.         })
  139.     }
  140.     //PC端用拖动事件
  141.     //不结合onmousedown和onmouseup做成拖动的原因在于拖动的时候setInterval速度会受影响,导致球体速度变慢
  142.     var dragFlag = false;
  143.     canvas.onclick = function(event){
  144.         x=event.clientX;
  145.         y=event.clientY;
  146.         if(Math.abs(x-star.x)<=star.size/2&&Math.abs(y-star.y)<=star.size/2){
  147.             dragFlag = true;
  148.         }
  149.         console.log(dragFlag);
  150.     }
  151.     canvas.onmousemove = function(){
  152.         if(dragFlag){
  153.             star.x=event.clientX;
  154.             star.y=event.clientY;
  155.         }
  156.     }
  157.     //手机平板类用重力感应事件
  158.     window.addEventListener("deviceorientation"function(event){
  159.         if((event.gamma>=3&&event.gamma<=90)||(event.gamma<=-3&&event.gamma>=-90)){
  160.             star.speedX = 0.5*event.gamma;
  161.         }else{
  162.             star.speedX = 0;
  163.         }
  164.         if((event.beta>=3&&event.beta<=90)||(event.beta<=-3&&event.beta>=-90)){
  165.             star.speedY = 0.5*event.beta;
  166.         }else{
  167.             star.speedY = 0;
  168.         }
  169.     }, true);
  170. </script>
  171. </html>

欢迎留言