Source: Snake.js

/*jslint plusplus: true, white: true, indent: 2, maxlen: 90 */
/**
 *  @author    Wolfgang Kowarschick
 *  @copyright 2013, Wolfgang Kowarschick
 *  <br/>
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted under the terms of the 
 *  Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported    
 *  (CC BY-NC-SA 3.0: http://creativecommons.org/licenses/by-nc-sa/3.0/). 
 */

(function($app$)
{ "use strict";
////////////////////////////////////////////////////////////////////////////////
// Class "Snake"
////////////////////////////////////////////////////////////////////////////////

//import
var Body = $app$.game.snake.Body,
    Food = $app$.game.snake.Food,
    
    l_direction;

/** 
 *  @class
 *  @name $app$.game.snake.Snake
 *  
 *  @param {Object} p_init
 *         Should contain three initialization objects to initialize the snake:
 *         <code>p_init.tail</code>,
 *         <code>p_init.length</code>, and
 *         <code>p_init.direction</code>.
 *  @param {$app$.game.snake.Plane} p_plane 
 *         The plane where the snake is to be placed. 
 */
function Snake(p_init, p_plane)
{ this.v_plane          = p_plane;
  this.v_init_tail      = p_init.tail;
  this.v_init_direction = l_direction[p_init.direction];
  this.v_init_length    = p_init.length;
}

/** @constant {Object} $app$.game.snake.Snake.NORTH */
Snake.NORTH = { x:  0, y: -1 };
/** @constant {Object} $app$.game.snake.Snake.EAST  */
Snake.EAST  = { x: +1, y:  0 };
/** @constant {Object} $app$.game.snake.Snake.SOUTH */
Snake.SOUTH = { x:  0, y: +1 };
/** @constant {Object} $app$.game.snake.Snake.WEST  */
Snake.WEST  = { x: -1, y:  0 };

Snake.NORTH.left  = Snake.WEST;
Snake.NORTH.right = Snake.EAST;
Snake.EAST.left   = Snake.NORTH;
Snake.EAST.right  = Snake.SOUTH;
Snake.SOUTH.left  = Snake.EAST;
Snake.SOUTH.right = Snake.WEST;
Snake.WEST.left   = Snake.SOUTH;
Snake.WEST.right  = Snake.NORTH;

l_direction = { north: Snake.NORTH, east: Snake.EAST, 
                south: Snake.SOUTH, west: Snake.WEST
              };

/** @constant {String} $app$.game.snake.Snake.LEFT  */
Snake.LEFT  = "left";
/** @constant {String} $app$.game.snake.Snake.RIGHT */
Snake.RIGHT = "right";

Snake.prototype =
{ /** 
   *  The current length of the snake.
   *  @var {int} $app$.game.snake.Snake#length  
   */
    
  /**
   *  Resets the snake. 
   *  
   *  @method
   *  @name $app$.game.snake.Snake#reset
   */
  reset:
    function()
    { var i, n,
          l_tail = this.v_init_tail;

      // Cleanup the plane
      this.v_plane.reset();
 
      // Place the initial snake on the plane.
      this.v_head      = 
      this.v_tail      = new Body(l_tail.x, l_tail.y);
      this.v_direction = this.v_init_direction;
      this.v_plane.addItem(this.v_head);
      for (i = 1, n = this.v_init_length; i < n; i++)
      { this.v_growing = true;
        this.move();
      }
      this.length = n;
    },
    
  /**
   *  Moves the snake one field further. If it hits a food item, it grows.
   *  If it hits a wall or body item, it dies.
   *  
   *  @method
   *  @name $app$.game.snake.Snake#move
   *  
   *  @returns {Boolean} 
   *           <code>true</code>, if and only if the snake is dead.
   */
  move:
    function()
    { var l_plane     = this.v_plane,
          l_head      = this.v_head,
          l_head_new,
          l_tail      = this.v_tail,
          l_direction = this.v_direction,
          l_x         = l_head.x + l_direction.x,
          l_y         = l_head.y + l_direction.y,
          l_item      = l_plane.getItem(l_x, l_y);
    
      if (!l_item || l_item instanceof Food)
      { l_head_new  = new Body(l_x, l_y);
        l_head.pred = l_head_new;
        this.v_head = l_head_new;
        l_plane.addItem(l_head_new);
        // If food has been eaten, the snake is growing.
        if (l_item)
        { this.v_growing = true;
          this.length++;
          l_plane.foodNr--;
        }
      }
      else
      { return true; }
    
      // If the snake is not growing, the current tail is removed.
      if (!this.v_growing)
      { this.v_tail = l_tail.pred;
        l_plane.removeItem(l_tail);
      }
      
      this.v_growing = false;
      
      return false;
    },
     
  /**
   *  Turns the snake 90° to the left or to the right. 
   *  
   *  @method
   *  @name $app$.game.snake.Snake#turnLeft
   *  
   *  @param {String} p_direction
   *                  Either <code>Snake.LEFT</code> or <code>Snake.RIGHT</code>.
   */
  turn:
    function(p_direction) 
    { this.v_direction = this.v_direction[p_direction]; }
      
};

$app$.game.snake.Snake = Snake;

////////////////////////////////////////////////////////////////////////////////
// End of Class "Snake"
////////////////////////////////////////////////////////////////////////////////
}(this.$app$));
W. Kowarschick © 2013 (CC BY-NC-SA 3.0: http://creativecommons.org/licenses/by-nc-sa/3.0/)
Documentation generated by JSDoc 3.3.0-dev on Sun Dec 15 2013 11:20:32 GMT+0100 (MEZ) using the DocStrap template.