Webフロントエンド学習ノート——JavaScriptの対象向けゲームケース:貪食蛇


相手向けゲームケース:蛇食い
ケース関連のソースコード以上がGitHubに伝わった:https://github.com/lipengzhou/new-snake
ケース紹介
ゲームのデモ
オンラインのデモンストレーション住所:食いしん坊蛇
ケースターゲット
ゲームの目的はjsの高級文法の使用を体得するために抽象的な対象の能力が必要ではなく、対象に向かう方式で問題を分析するには、長いプロセスが必要です.
機能の実現
ページを構築する
容器を置いてゲームシーンdiv〓〓mapを入れて、スタイルを設定します.
#map {
  width: 800px;
  height: 600px;
  background-color: #ccc;
  position: relative;
}
オブジェクトを分析
  • ゲームオブジェクト
  • 蛇の対象
  • 食べ物の対象
  • オブジェクトを作成
  • Food
  • 属性
  • x
  • y
  • width
  • ヘight
  • c
  • 方法
  • renderはランダムに食べ物のオブジェクトを作成し、mapに
  • を出力します.
  • は、Foodの構造関数を作成し、属性
  • を設定します.
    var position = 'absolute';
    var elements = [];
    function Food(x, y, width, height, color) {
      this.x = x || 0;
      this.y = y || 0;
      //         (  )
      this.width = width || 20;
      this.height = height || 20;
      //      
      this.color = color || 'green';
    }
    
  • プロトタイプによるレンダー方式の設定により、ランダムに食べ物を生成する対象を実現し、mapにレンダリングする
  • .
    Food.prototype.render = function (map) {
      //        ,map.  /food.  ,      food   ,    。     food   
      this.x = parseInt(Math.random() * map.offsetWidth / this.width) * this.width;
      this.y = parseInt(Math.random() * map.offsetHeight / this.height) * this.height;
    
      //          div
      var div = document.createElement('div');
      map.appendChild(div);
      div.style.position = position;
      div.style.left = this.x + 'px';
      div.style.top = this.y + 'px';
      div.style.width = this.width + 'px';
      div.style.height = this.height + 'px';
      div.style.backgroundColor = this.color;
      elements.push(div);
    }
    
  • は、自己起動関数によってパッケージ化され、Windowsを介してFoodオブジェクト
  • を露出する.
    window.Food = Food;
    
    蛇のオブジェクトを作成
  • Snake
  • 属性
  • width蛇祭りの幅は、デフォルトでは
  • です.
  • ヘight蛇祭りの高さはデフォルトです.
  • body配列、蛇の頭と体、最初の位置は蛇の頭
  • です.
  • direction蛇の動きの方向は、デフォルトのrightは、left top bottom
  • であることができます.
  • 方法
  • render蛇をmapにレンダリングする
  • Snake構造関数
  • var position = 'absolute';
    var elements = [];
    function Snake(width, height, direction) {
      //           
      this.width = width || 20;
      this.height = height || 20;
      //       ,        
      this.body = [
        {x: 3, y: 2, color: 'red'},
        {x: 2, y: 2, color: 'red'},
        {x: 1, y: 2, color: 'red'}
      ];
      this.direction = direction || 'right';
    }
    
  • レンダー方法
  • Snake.prototype.render = function(map) {
      for(var i = 0; i < this.body.length; i++) {
        var obj = this.body[i];
        var div = document.createElement('div');
        map.appendChild(div);
        div.style.left = obj.x * this.width + 'px';
        div.style.top = obj.y * this.height + 'px';
        div.style.position = position;
        div.style.backgroundColor = obj.color;
        div.style.width = this.width + 'px';
        div.style.height = this.height + 'px';
      }
    }
    
  • 在自呼び出し関数におけるSnakeオブジェクトの露出
  • window.Snake = Snake;
    
    ゲームオブジェクトを作成
    ゲームオブジェクトは、ゲーム中のすべてのオブジェクトを管理し、ゲームを開始します.
  • Game
  • 属性
  • food
  • snake
  • map
  • 方法
  • スタートゲーム(すべてのゲームのオブジェクトを描画)
  • 構築関数
  • function Game(map) {
      this.food = new Food();
      this.snake = new Snake();
      this.map = map;
    }
    
  • ゲームを開始し、オブジェクトとヘビ
  • をレンダリングします.
    Game.prototype.start = function () {
      this.food.render(this.map);
      this.snake.render(this.map);
    }
    
    ゲームの論理
    蛇のmove方法を書きます
  • 蛇のオブジェクト(snake.js)に、Snakeのプロトタイプにmove方法
  • を追加する.
  • 蛇を移動させ、蛇の体の一部を前に移動させます.
  • 蛇頭部分は、方向によってどこに移動するかを決めます.
    Snake.prototype.move = function (food, map) {
      //                
      var i = this.body.length - 1;
      for(; i > 0; i--) {
        this.body[i].x = this.body[i - 1].x;
        this.body[i].y = this.body[i - 1].y;
      }
      //        ,        
      switch(this.direction) {
        case 'left': 
          this.body[0].x -= 1;
          break;
        case 'right':
          this.body[0].x += 1;
          break;
        case 'top':
          this.body[0].y -= 1;
          break;
        case 'bottom':
          this.body[0].y += 1;
          break;
      }
    }
    
  • gameで
  • をテストします.
    this.snake.move(this.food, this.map);
    this.snake.render(this.map);
    
    蛇を自分で動かす
  • プライベート方法
           ?
                
            ?
               
    
  • game.jsにrun Snakeのプライベートメソッドを追加し、タイマーを開いて蛇のmoveとrender方法を呼び出し、蛇を動かします.
  • 蛇が壁にぶつかったかどうかを判断する
  • .
    function runSnake() {
      var timerId = setInterval(function() {
        this.snake.move(this.food, this.map);
        //     ,      
        this.snake.render(this.map);
    
        //        
        var maxX = this.map.offsetWidth / this.snake.width;
        var maxY = this.map.offsetHeight / this.snake.height;
        var headX = this.snake.body[0].x;
        var headY = this.snake.body[0].y;
        if (headX < 0 || headX >= maxX) {
          clearInterval(timerId);
          alert('Game Over');
        }
    
        if (headY < 0 || headY >= maxY) {
          clearInterval(timerId);
          alert('Game Over');
        }
    
      }.bind(that), 150);
    }
    
  • スネークに蛇を削除するプライベート方法を追加し、レンダーに
  • を呼び出します.
    function remove() {
      //       
      var i = elements.length - 1;
      for(; i >= 0; i--) {
        //          
        elements[i].parentNode.removeChild(elements[i]);
        //   elements      
        elements.splice(i, 1);
      }
    }
    
  • gameでは、ヘビの移動方向をキーボードで制御する
  • .
    function bindKey() {
      document.addEventListener('keydown', function(e) {
        switch (e.keyCode) {
          case 37:
            // left
            this.snake.direction = 'left';
            break;
          case 38:
            // top
            this.snake.direction = 'top';
            break;
          case 39:
            // right
            this.snake.direction = 'right';
            break;
          case 40:
            // bottom
            this.snake.direction = 'bottom';
            break;
        }
      }.bind(that), false);
    }
    
  • start方法で
  • を呼び出します.
    bindKey();
    
    蛇が食べ物を食べたかどうかを判断します.
    //  Snake move   
    
    //                 
    //                   
    //         ,         ,    
    var headX = this.body[0].x * this.width;
    var headY = this.body[0].y * this.height;
    if (headX === food.x && headY === food.y) {
      //     ,         
      var last = this.body[this.body.length - 1];
      this.body.push({
        x: last.x,
        y: last.y,
        color: last.color
      })
      //           ,             
      food.render(map);
    }
    
    その他の処理
    html中のjsコードをindex.jsにセットします.
    jsコードが発生するのを避ける.
    コール機能のパラメータ
    (function (window, undefined) {
      var document = window.document;
    
    }(window, undefined))
    
  • はwindowオブジェクト
  • に伝えられました.
    将来コードを圧縮するときは、いいですよね.function(window)をfunction(w)に圧縮します.
  • はundefined
  • に伝えられました.
    将来他の人が書いているコードを見るとundefinedを関数としてのパラメータ(現在の例は使用されていません)があります.古いバージョンのブラウザでundefinedが再割り当てされ、undefinedが再割り当てされるのを防ぐためです.
    コードを整理する
    今のコードの構造ははっきりしています.問題があったら、対応するjsファイルを見つけたらいいです.自己起動関数により、変数名の汚染を防止しました.
    しかし、jsファイル数が多いので、ページで引用する必要があります.ファイル依存の問題(先にそのjsを導入して、どのjsを導入しますか?)が発生します.将来はツールを通じてjsファイルを統合して圧縮します.手動でjsファイルをマージしてデモを行います.
  • 問題1
  • //                  ,      
    //        
    (function () {
    }())
    
    (function () {
    }())
    //                       
    //         
    ;(function () {
    }())
    
    ;(function () {
    }())
    
  • 問題2
  • //                ,           
    //           ,  ;
    var a = function () {
      alert('11');
    }
        
    (function () {
      alert('22');
    }())