天天看點

001-HTML5-Canvas貪吃蛇

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style>
      #myCanvas{
        background-color: #FFFFFF;
        
      }
    </style>
  </head>
  <!--
  第一步: 建立一個舞台
      1. canvas幕布,設定大小,背景以及邊界顔色
      2. span成績顯示
      3. button開始按鈕,設定點選事件
  第二步: 建立蛇對象:屬性和動作
      1. bodyArray蛇身體屬性,一個數組,每一塊有x與y坐标,例如bodyArray[i]=[{x:1},{y:2}]
      2. move移動動作,不幹涉頭部,身體其他部位依次向前.
      3. moveup, movedown, moveleft and moveright:具體控制頭部移動,之後調用2move方法移動身體,例如,向上移動則x不變,y-1
      4. eatFood蛇吃食物動作,蛇吃掉食物之後,身體向後增長,這裡需要根據最後兩節身體來判斷增長方向,
      在複雜一點需要考慮牆的因素,這裡還需要初始化食物對象,food=[{x:1},{y:2}],隻要頭部和food坐标重合就是吃掉.
      然後食物重新重新整理,這裡還要考慮分數,隻要吃掉食物,就将分數增加,這裡有需要一個變量MyScore and score
      5. changeDirection變向,如果6isChangeDirection允許變向就把currentDirection改變
      6. isChangeDirection是否可以變向,可以用一個二維數組,前後一組,左右一組,找到目前方向一組,如果變向也在改組就不能變,同樣除了這四個方向外其他都不能變
      這裡我們需要設定一個二維數組directionTwoArray=[['left','right'],['up','down']];另外判斷是否是四個方向還需要一個一維數組directionOneArrray=['left','right','up','down'];
  第三步: 設定遊戲規則:蛇撞死
      1. isSnakeKnockWall判斷蛇是否撞牆方法:隻要判斷頭部坐标就可以, 這裡需要根據變量unit判斷,是以需要兩個新變量wUnitNumber, hUnitNumber
      2. isSnakeKnockBody怕那頓蛇是否撞到身體:這個周遊依次就可以
  第四步: 鍵盤控制
      1. 使用WASD分别控制up, left, down and right,隻要是正确的方向,蛇就移動,執行具體的3moveSomeDirevtion方法
  第五步: 繪制蛇和食物
      1. drawSnake畫蛇方法,畫蛇用到了Canvas繪制,這裡我們隻要周遊就可以了,這裡需要三個變量一個canvas,一個canvas的上下文ctx,
      以及每節身體占多少格子的unit
      2. drawFood畫食物方法, 畫食物和畫蛇差不多,不過需要随機生成而已,但是setInterval循環的時候我不确定是不是會重新整理掉,是以可能會拆成兩個辦法
      3. clearScreen清屏方法,這是為了重新開始遊戲設定的.開始遊戲之前也要設定一遍
  第六步: 遊戲初始化和循環
      1. startGame開始遊戲方法,首先應該是初始化食物和蛇,然後進入循環,根據目前方向currentDirect一直向前走,除非按鍵改變方向.
      另外開始遊戲的時候還要打破循環,也就是clearInternal(window.looper),否則還是會繼續畫.
  -->
  <body>
    <canvas id="myCanvas" style="width: 300px; height: 300px;"></canvas><br>
    <span>你的成績是:</span><span id="myScore"></span><br>
    <button type="button" onclick="startGame();">開始遊戲</button>
    <script>
      var width = 300;
      var height = 300;
      var unit = 6;
      var wUnitNumber = width/unit;
      var hUnitNumber = height/unit;
      var myCanvas = document.getElementById('myCanvas');
      var ctx = myCanvas.getContext("2d");
      var directionTwoArray=[['left','right'],['up','down']];
      var directionOneArrray=['left','right','up','down'];
      var myScore = document.getElementById('myScore');
      var score = 0;
      var food = {x:1, y:2};
      var snake = {
        currentDirect :'right',
        directionTwoArray:[['left','right'],['up','down']],
        directionOneArrray:['left','right','up','down'],
        bodyArray: [{x:3, y:0},{x:2, y:0},{x:1, y:0}],
        move:function(preBody){
          //debugger
          var tempBody;
          
          for(var i = 1; i < this.bodyArray.length; i ++){
            tempBody = this.bodyArray[i];
            this.bodyArray[i] = preBody;
            preBody = tempBody;
            // console.log("body["+i+"]"+this.bodyArray[i].x+","+this.bodyArray[i].y+" ");
          }
        },
        moveup:function(){
          //debugger
          var oldHead = this.bodyArray[0];
          this.bodyArray[0]= {x:oldHead.x,y:oldHead.y-1};
          this.move(oldHead);
        },
        movedown:function(){
          //debugger
          var oldHead = this.bodyArray[0];
          this.bodyArray[0]= {x:oldHead.x,y:oldHead.y+1};
          this.move(oldHead);
        },
        moveleft:function(){
          //debugger
          var oldHead = this.bodyArray[0];
          this.bodyArray[0]= {x:oldHead.x-1,y:oldHead.y};
          this.move(oldHead);
        },
        moveright:function(){
          //debugger
          var oldHead = this.bodyArray[0];
          this.bodyArray[0]= {x:oldHead.x+1,y:oldHead.y};
          //console.log(oldHead.x+","+oldHead.y);
          this.move(oldHead);
        },
        eatFood:function(){
          var head = this.bodyArray[0];
          if(head.x == food.x && head.y == food.y){
            //debugger
            //todo 還可能碰到牆
            lastBody = this.bodyArray[this.bodyArray.length-1];
            lastButOneBody = this.bodyArray[this.bodyArray.length-2];
            var xMin = lastBody.x - lastButOneBody.x;
            var yMin = lastBody.y - lastButOneBody.y;
            var oneBody = {x:lastBody.x+xMin, y:lastBody.y+yMin}
            this.bodyArray.push(oneBody);
            score++;
            myScore.innerHTML=score;
            initFood();
          }
        },
        isChangeDirection:function(direction){
          //如果不是四個方向裡面的
          if(directionOneArrray.indexOf(this.currentDirect) == -1){
            return false;
          }
          var tempTwoDirection=null;
          for(var i in this.directionTwoArray){
            //如果是這一組的一個方向
            if(this.directionTwoArray[i].indexOf(this.currentDirect) != -1){
              tempTwoDirection = this.directionTwoArray[i];
              break;
            }
          }
          if(tempTwoDirection.indexOf(direction) != -1){
            return false;
          }
          return true;
        },
        changeDirection:function(direction){
          if(this.isChangeDirection(direction)){
            this.currentDirect = direction;
          }else{
            console.log("不能變向");
          }
          console.log("curentDirection: "+snake.currentDirect);
          
        }
      }
      function isSnakeKnockWall(){
        var head = snake.bodyArray[0];
        if((head.x < 0 || head.y < 0) || ((head.x > wUnitNumber-1) || (head.y > hUnitNumber-1))){
          return true;
        }
        return false;
      };
      function isSnakeKnockBody(){
        var head = snake.bodyArray[0];
        for(var i = 1; i < snake.bodyArray.length; i ++){
          if(head.x == snake.bodyArray[i].x && head.y==snake.bodyArray[i].y){
            return true;
          }
        }
        return false;
      };
      window.onkeyup=function(key){
        var direction = '';
        console.log("keyCode: "+key.keyCode);
        switch(key.keyCode){
          case 65:
            direction='left';
            snake.moveleft();
            break;
          case 68:
            direction='right';
            snake.moveright();
            break;
          case 87:
            direction='up';
            snake.moveup();
            break;
          case 83:
            direction='down';
            snake.movedown();
            break;
          default:
            break;
        }
        if(direction=='') return;
        snake.changeDirection(direction);
      };
      function  drawSnake(){
        //console.log("snake.length: "+snake.bodyArray.length);
        for(var i = 0; i < snake.bodyArray.length; i ++){
          //console.log("body["+i+"]"+snake.bodyArray[i].x+","+snake.bodyArray[i].y+" ");
          // ctx.fillStyle="#FF0000";
          
          ctx.rect(snake.bodyArray[i].x*unit, snake.bodyArray[i].y*unit, unit, unit);
          
        }
        ctx.stroke();
      };
      function initFood(){
        food.x = Math.floor(Math.random()*wUnitNumber/4);
        food.y = Math.floor(Math.random()*hUnitNumber/4);
        
        
      }
      function drawFood(){
        ctx.rect(food.x*unit, food.y*unit, unit, unit);
        ctx.stroke();
      }
      function clearScreen(){
        ctx.clearRect(0,0,width, height);
      }
      function startGame(){
        //debugger;
        clearInterval(window.looper);
        //debugger;
        snake.bodyArray=[{x:3, y:0},{x:2, y:0},{x:1, y:0}];
        snake.currentDirect = 'right';
        //clearScreen();
        ctx.beginPath();
        
        initFood();
        drawFood();
        drawSnake();
        ctx.stroke();
        window.looper=setInterval(function(){
          //debugger;
          //console.log("curentDirection: "+snake.currentDirect);
          switch(snake.currentDirect){
            case 'left':
              snake.moveleft();
              break;
            case 'right':
            //console.log("right");
              snake.moveright();
              break;
            case 'up':
            //console.log("up");
              snake.moveup();
              break;
            case 'down':
            //console.log("down");
              snake.movedown();
              break;
            default:
              break;
          }
          this.clearScreen();
          ctx.beginPath();
          
          snake.eatFood();
          drawSnake();
          drawFood();
          if(isSnakeKnockWall()){
            clearInterval(window.looper);
            alert("GAME OVER and you SCORE:"+score);
            
          }
          
        },300);
      }
    </script>
  </body>
</html>      

繼續閱讀