• 实验3 web之前端逆向安全


    发现snake.js,源码:

      1 /*
      2 JavaScript Snake
      3 By Patrick Gillespie
      4 http://patorjk.com/games/snake
      5 */
      6 
      7 /**
      8 * @module Snake
      9 * @class SNAKE
     10 */
     11 
     12 var SNAKE = SNAKE || {};
     13 
     14 /**
     15 * @method addEventListener
     16 * @param {Object} obj The object to add an event listener to.
     17 * @param {String} event The event to listen for.
     18 * @param {Function} funct The function to execute when the event is triggered.
     19 * @param {Boolean} evtCapturing True to do event capturing, false to do event bubbling.
     20 */
     21 
     22 SNAKE.addEventListener = (function() {
     23     if (window.addEventListener) {
     24         return function(obj, event, funct, evtCapturing) {
     25             obj.addEventListener(event, funct, evtCapturing);
     26         };
     27     } else if (window.attachEvent) {
     28         return function(obj, event, funct) {
     29             obj.attachEvent("on" + event, funct);
     30         };
     31     }
     32 })();
     33 
     34 /**
     35 * @method removeEventListener
     36 * @param {Object} obj The object to remove an event listener from.
     37 * @param {String} event The event that was listened for.
     38 * @param {Function} funct The function that was executed when the event is triggered.
     39 * @param {Boolean} evtCapturing True if event capturing was done, false otherwise.
     40 */
     41 
     42 SNAKE.removeEventListener = (function() {
     43     if (window.removeEventListener) {
     44         return function(obj, event, funct, evtCapturing) {
     45             obj.removeEventListener(event, funct, evtCapturing);
     46         };
     47     } else if (window.detachEvent) {
     48         return function(obj, event, funct) {
     49             obj.detachEvent("on" + event, funct);
     50         };
     51     }
     52 })();
     53 
     54 /**
     55 * This class manages the snake which will reside inside of a SNAKE.Board object.
     56 * @class Snake
     57 * @constructor
     58 * @namespace SNAKE
     59 * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this snake resides in), startRow and startCol.
     60 */
     61 SNAKE.Snake = SNAKE.Snake || (function() {
     62     
     63     // -------------------------------------------------------------------------
     64     // Private static variables and methods
     65     // -------------------------------------------------------------------------
     66     
     67     var instanceNumber = 0;
     68     var blockPool = [];
     69     
     70     var SnakeBlock = function() {
     71         this.elm = null;
     72         this.elmStyle = null;
     73         this.row = -1;
     74         this.col = -1;
     75         this.xPos = -1000;
     76         this.yPos = -1000;
     77         this.next = null;
     78         this.prev = null;
     79     };
     80     
     81     // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html
     82     function getNextHighestZIndex(myObj) {
     83         var highestIndex = 0,
     84             currentIndex = 0,
     85             ii;
     86         for (ii in myObj) {
     87             if (myObj[ii].elm.currentStyle){  
     88                 currentIndex = parseFloat(myObj[ii].elm.style["z-index"],10);
     89             }else if(window.getComputedStyle) {
     90                 currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm,null).getPropertyValue("z-index"),10);  
     91             }
     92             if(!isNaN(currentIndex) && currentIndex > highestIndex){
     93                 highestIndex = currentIndex;
     94             }
     95         }
     96         return(highestIndex+1);  
     97     }
     98     
     99     // -------------------------------------------------------------------------
    100     // Contructor + public and private definitions
    101     // -------------------------------------------------------------------------
    102     
    103     /*
    104         config options:
    105             playingBoard - the SnakeBoard that this snake belongs too.
    106             startRow - The row the snake should start on.
    107             startCol - The column the snake should start on.
    108     */
    109     return function(config) {
    110     
    111         if (!config||!config.playingBoard) {return;}
    112     
    113         // ----- private variables -----
    114 
    115         var me = this,
    116             playingBoard = config.playingBoard,
    117             myId = instanceNumber++,
    118             growthIncr = 5,
    119             moveQueue = [], // a queue that holds the next moves of the snake
    120             currentDirection = 1, // 0: up, 1: left, 2: down, 3: right
    121             columnShift = [0, 1, 0, -1],
    122             rowShift = [-1, 0, 1, 0],
    123             xPosShift = [],
    124             yPosShift = [],
    125             snakeSpeed = 75,
    126             isDead = false;
    127         
    128         // ----- public variables -----
    129 
    130         me.snakeBody = {};
    131         me.snakeBody["b0"] = new SnakeBlock(); // create snake head
    132         me.snakeBody["b0"].row = config.startRow || 1;
    133         me.snakeBody["b0"].col = config.startCol || 1;
    134         me.snakeBody["b0"].xPos = me.snakeBody["b0"].row * playingBoard.getBlockWidth();
    135         me.snakeBody["b0"].yPos = me.snakeBody["b0"].col * playingBoard.getBlockHeight();
    136         me.snakeBody["b0"].elm = createSnakeElement();
    137         me.snakeBody["b0"].elmStyle = me.snakeBody["b0"].elm.style;
    138         playingBoard.getBoardContainer().appendChild( me.snakeBody["b0"].elm );
    139         me.snakeBody["b0"].elm.style.left = me.snakeBody["b0"].xPos + "px";
    140         me.snakeBody["b0"].elm.style.top = me.snakeBody["b0"].yPos + "px";
    141         me.snakeBody["b0"].next = me.snakeBody["b0"];
    142         me.snakeBody["b0"].prev = me.snakeBody["b0"];
    143         
    144         me.snakeLength = 1;
    145         me.snakeHead = me.snakeBody["b0"];
    146         me.snakeTail = me.snakeBody["b0"];
    147         me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'');
    148         me.snakeHead.elm.className += " snake-snakebody-alive";
    149         
    150         // ----- private methods -----
    151         
    152         function createSnakeElement() {
    153             var tempNode = document.createElement("div");
    154             tempNode.className = "snake-snakebody-block";
    155             tempNode.style.left = "-1000px";
    156             tempNode.style.top = "-1000px";
    157             tempNode.style.width = playingBoard.getBlockWidth() + "px";
    158             tempNode.style.height = playingBoard.getBlockHeight() + "px";
    159             return tempNode;
    160         }
    161         
    162         function createBlocks(num) {
    163             var tempBlock;
    164             var tempNode = createSnakeElement();
    165 
    166             for (var ii = 1; ii < num; ii++){
    167                 tempBlock = new SnakeBlock();
    168                 tempBlock.elm = tempNode.cloneNode(true);
    169                 tempBlock.elmStyle = tempBlock.elm.style;
    170                 playingBoard.getBoardContainer().appendChild( tempBlock.elm );
    171                 blockPool[blockPool.length] = tempBlock;
    172             }
    173             
    174             tempBlock = new SnakeBlock();
    175             tempBlock.elm = tempNode;
    176             playingBoard.getBoardContainer().appendChild( tempBlock.elm );
    177             blockPool[blockPool.length] = tempBlock;
    178         }
    179         
    180         // ----- public methods -----
    181         
    182         /**
    183         * This method is called when a user presses a key. It logs arrow key presses in "moveQueue", which is used when the snake needs to make its next move.
    184         * @method handleArrowKeys
    185         * @param {Number} keyNum A number representing the key that was pressed.
    186         */
    187         /*
    188             Handles what happens when an arrow key is pressed. 
    189             Direction explained (0 = up, etc etc)
    190                     0
    191                   3   1
    192                     2
    193         */
    194         me.handleArrowKeys = function(keyNum) {
    195             if (isDead) {return;}
    196             
    197             var snakeLength = me.snakeLength;
    198             var lastMove = moveQueue[0] || currentDirection;
    199 
    200             switch (keyNum) {
    201                 case 37:
    202                     if ( lastMove !== 1 || snakeLength === 1 ) {
    203                         moveQueue.unshift(3); //SnakeDirection = 3;
    204                     }
    205                     break;    
    206                 case 38:
    207                     if ( lastMove !== 2 || snakeLength === 1 ) {
    208                         moveQueue.unshift(0);//SnakeDirection = 0;
    209                     }
    210                     break;    
    211                 case 39:
    212                     if ( lastMove !== 3 || snakeLength === 1 ) {
    213                         moveQueue.unshift(1); //SnakeDirection = 1;
    214                     }
    215                     break;    
    216                 case 40:
    217                     if ( lastMove !== 0 || snakeLength === 1 ) {
    218                         moveQueue.unshift(2);//SnakeDirection = 2;
    219                     }
    220                     break;  
    221             }
    222         };
    223         
    224         /**
    225         * This method is executed for each move of the snake. It determines where the snake will go and what will happen to it. This method needs to run quickly.
    226         * @method go
    227         */
    228         me.go = function() {
    229         
    230             var oldHead = me.snakeHead,
    231                 newHead = me.snakeTail,
    232                 myDirection = currentDirection,
    233                 grid = playingBoard.grid; // cache grid for quicker lookup
    234         
    235             me.snakeTail = newHead.prev;
    236             me.snakeHead = newHead;
    237         
    238             // clear the old board position
    239             if ( grid[newHead.row] && grid[newHead.row][newHead.col] ) {
    240                 grid[newHead.row][newHead.col] = 0;
    241             }
    242         
    243             if (moveQueue.length){
    244                 myDirection = currentDirection = moveQueue.pop();
    245             }
    246         
    247             newHead.col = oldHead.col + columnShift[myDirection];
    248             newHead.row = oldHead.row + rowShift[myDirection];
    249             newHead.xPos = oldHead.xPos + xPosShift[myDirection];
    250             newHead.yPos = oldHead.yPos + yPosShift[myDirection];
    251             
    252             if ( !newHead.elmStyle ) {
    253                 newHead.elmStyle = newHead.elm.style;
    254             }
    255             
    256             newHead.elmStyle.left = newHead.xPos + "px";
    257             newHead.elmStyle.top = newHead.yPos + "px";
    258 
    259             // check the new spot the snake moved into
    260 
    261             if (grid[newHead.row][newHead.col] === 0) {
    262                 grid[newHead.row][newHead.col] = 1;
    263                 setTimeout(function(){me.go();}, snakeSpeed); 
    264             } else if (grid[newHead.row][newHead.col] > 0) {
    265                 me.handleDeath();
    266             } else if (grid[newHead.row][newHead.col] === playingBoard.getGridFoodValue()) {
    267                 grid[newHead.row][newHead.col] = 1;
    268                 me.eatFood();
    269                 setTimeout(function(){me.go();}, snakeSpeed);
    270             }
    271         };
    272         
    273         /**
    274         * This method is called when it is determined that the snake has eaten some food.
    275         * @method eatFood
    276         */
    277         me.eatFood = function() {
    278             if (blockPool.length <= growthIncr) {
    279                 createBlocks(growthIncr*2);
    280             }
    281             var blocks = blockPool.splice(0, growthIncr);
    282             
    283             var ii = blocks.length,
    284                 index,
    285                 prevNode = me.snakeTail;
    286             while (ii--) {
    287                 index = "b" + me.snakeLength++;
    288                 me.snakeBody[index] = blocks[ii];
    289   
    290 
    291 
    292 if (me.snakeLength > 2500){
    293 ゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
    294 
    295 }
    296 
    297 
    298 
    299 
    300 
    301               me.snakeBody[index].prev = prevNode;
    302                 me.snakeBody[index].elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
    303                 me.snakeBody[index].elm.className += " snake-snakebody-alive";
    304                 prevNode.next = me.snakeBody[index];
    305                 prevNode = me.snakeBody[index];
    306 
    307               
    308 
    309             }
    310             me.snakeTail = me.snakeBody[index];
    311             me.snakeTail.next = me.snakeHead;
    312             me.snakeHead.prev = me.snakeTail;
    313 
    314             playingBoard.foodEaten();
    315         };
    316         
    317         /**
    318         * This method handles what happens when the snake dies.
    319         * @method handleDeath
    320         */
    321         me.handleDeath = function() {
    322             me.snakeHead.elm.style.zIndex = getNextHighestZIndex(me.snakeBody);
    323             me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-alive/,'')
    324             me.snakeHead.elm.className += " snake-snakebody-dead";
    325 
    326             isDead = true;
    327             playingBoard.handleDeath();
    328             moveQueue.length = 0;
    329         };
    330 
    331         /**
    332         * This method sets a flag that lets the snake be alive again.
    333         * @method rebirth
    334         */   
    335         me.rebirth = function() {
    336             isDead = false;
    337         };
    338         
    339         /**
    340         * This method reset the snake so it is ready for a new game.
    341         * @method reset
    342         */        
    343         me.reset = function() {
    344             if (isDead === false) {return;}
    345             
    346             var blocks = [],
    347                 curNode = me.snakeHead.next,
    348                 nextNode;
    349             while (curNode !== me.snakeHead) {
    350                 nextNode = curNode.next;
    351                 curNode.prev = null;
    352                 curNode.next = null;
    353                 blocks.push(curNode);
    354                 curNode = nextNode;
    355             }
    356             me.snakeHead.next = me.snakeHead;
    357             me.snakeHead.prev = me.snakeHead;
    358             me.snakeTail = me.snakeHead;
    359             me.snakeLength = 1;
    360             
    361             for (var ii = 0; ii < blocks.length; ii++) {
    362                 blocks[ii].elm.style.left = "-1000px";
    363                 blocks[ii].elm.style.top = "-1000px";
    364                 blocks[ii].elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
    365                 blocks[ii].elm.className += " snake-snakebody-alive";
    366             }
    367             
    368             blockPool.concat(blocks);
    369             me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
    370             me.snakeHead.elm.className += " snake-snakebody-alive";
    371             me.snakeHead.row = config.startRow || 1;
    372             me.snakeHead.col = config.startCol || 1;
    373             me.snakeHead.xPos = me.snakeHead.row * playingBoard.getBlockWidth();
    374             me.snakeHead.yPos = me.snakeHead.col * playingBoard.getBlockHeight();
    375             me.snakeHead.elm.style.left = me.snakeHead.xPos + "px";
    376             me.snakeHead.elm.style.top = me.snakeHead.yPos + "px";
    377         };
    378         
    379         // ---------------------------------------------------------------------
    380         // Initialize
    381         // ---------------------------------------------------------------------
    382         
    383         createBlocks(growthIncr*2);
    384         xPosShift[0] = 0;
    385         xPosShift[1] = playingBoard.getBlockWidth();
    386         xPosShift[2] = 0;
    387         xPosShift[3] = -1 * playingBoard.getBlockWidth();
    388         
    389         yPosShift[0] = -1 * playingBoard.getBlockHeight();
    390         yPosShift[1] = 0;
    391         yPosShift[2] = playingBoard.getBlockHeight();
    392         yPosShift[3] = 0;
    393     };
    394 })();
    395 
    396 /**
    397 * This class manages the food which the snake will eat.
    398 * @class Food
    399 * @constructor
    400 * @namespace SNAKE
    401 * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this food resides in).
    402 */
    403 
    404 SNAKE.Food = SNAKE.Food || (function() {
    405     
    406     // -------------------------------------------------------------------------
    407     // Private static variables and methods
    408     // -------------------------------------------------------------------------
    409     
    410     var instanceNumber = 0;
    411     
    412     function getRandomPosition(x, y){
    413         return Math.floor(Math.random()*(y+1-x)) + x; 
    414     }
    415     
    416     // -------------------------------------------------------------------------
    417     // Contructor + public and private definitions
    418     // -------------------------------------------------------------------------
    419     
    420     /*
    421         config options:
    422             playingBoard - the SnakeBoard that this object belongs too.
    423     */
    424     return function(config) {
    425         
    426         if (!config||!config.playingBoard) {return;}
    427 
    428         // ----- private variables -----
    429 
    430         var me = this;
    431         var playingBoard = config.playingBoard;
    432         var fRow, fColumn;
    433         var myId = instanceNumber++;
    434 
    435         var elmFood = document.createElement("div");
    436         elmFood.setAttribute("id", "snake-food-"+myId);
    437         elmFood.className = "snake-food-block";
    438         elmFood.style.width = playingBoard.getBlockWidth() + "px";
    439         elmFood.style.height = playingBoard.getBlockHeight() + "px";
    440         elmFood.style.left = "-1000px";
    441         elmFood.style.top = "-1000px";
    442         playingBoard.getBoardContainer().appendChild(elmFood);
    443         
    444         // ----- public methods -----
    445         
    446         /**
    447         * @method getFoodElement
    448         * @return {DOM Element} The div the represents the food.
    449         */        
    450         me.getFoodElement = function() {
    451             return elmFood;  
    452         };
    453         
    454         /**
    455         * Randomly places the food onto an available location on the playing board.
    456         * @method randomlyPlaceFood
    457         */    
    458         me.randomlyPlaceFood = function() {
    459             // if there exist some food, clear its presence from the board
    460             if (playingBoard.grid[fRow] && playingBoard.grid[fRow][fColumn] === playingBoard.getGridFoodValue()){
    461                 playingBoard.grid[fRow][fColumn] = 0; 
    462             }
    463 
    464             var row = 0, col = 0, numTries = 0;
    465 
    466             var maxRows = playingBoard.grid.length-1;
    467             var maxCols = playingBoard.grid[0].length-1;
    468             
    469             while (playingBoard.grid[row][col] !== 0){
    470                 row = getRandomPosition(1, maxRows);
    471                 col = getRandomPosition(1, maxCols);
    472 
    473                 // in some cases there may not be any room to put food anywhere
    474                 // instead of freezing, exit out
    475                 numTries++;
    476                 if (numTries > 20000){
    477                     row = -1;
    478                     col = -1;
    479                     break; 
    480                 } 
    481             }
    482 
    483             playingBoard.grid[row][col] = playingBoard.getGridFoodValue();
    484             fRow = row;
    485             fColumn = col;
    486             elmFood.style.top = row * playingBoard.getBlockHeight() + "px";
    487             elmFood.style.left = col * playingBoard.getBlockWidth() + "px";
    488         };
    489     };
    490 })();
    491 
    492 /**
    493 * This class manages playing board for the game.
    494 * @class Board
    495 * @constructor
    496 * @namespace SNAKE
    497 * @param {Object} config The configuration object for the class. Set fullScreen equal to true if you want the game to take up the full screen, otherwise, set the top, left, width and height parameters.
    498 */
    499 
    500 SNAKE.Board = SNAKE.Board || (function() {
    501 
    502     // -------------------------------------------------------------------------
    503     // Private static variables and methods
    504     // -------------------------------------------------------------------------
    505 
    506     var instanceNumber = 0;
    507 
    508     // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html
    509     function getNextHighestZIndex(myObj) {
    510         var highestIndex = 0,
    511             currentIndex = 0,
    512             ii;
    513         for (ii in myObj) {
    514             if (myObj[ii].elm.currentStyle){  
    515                 currentIndex = parseFloat(myObj[ii].elm.style["z-index"],10);
    516             }else if(window.getComputedStyle) {
    517                 currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm,null).getPropertyValue("z-index"),10);  
    518             }
    519             if(!isNaN(currentIndex) && currentIndex > highestIndex){
    520                 highestIndex = currentIndex;
    521             }
    522         }
    523         return(highestIndex+1);  
    524     }
    525 
    526     /*
    527         This function returns the width of the available screen real estate that we have
    528     */
    529     function getClientWidth(){
    530         var myWidth = 0;
    531         if( typeof window.innerWidth === "number" ) {
    532             myWidth = window.innerWidth;//Non-IE
    533         } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    534             myWidth = document.documentElement.clientWidth;//IE 6+ in 'standards compliant mode'
    535         } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    536             myWidth = document.body.clientWidth;//IE 4 compatible
    537         } 
    538         return myWidth;
    539     }
    540     /*
    541         This function returns the height of the available screen real estate that we have
    542     */
    543     function getClientHeight(){
    544         var myHeight = 0;
    545         if( typeof window.innerHeight === "number" ) {
    546             myHeight = window.innerHeight;//Non-IE
    547         } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    548             myHeight = document.documentElement.clientHeight;//IE 6+ in 'standards compliant mode'
    549         } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    550             myHeight = document.body.clientHeight;//IE 4 compatible
    551         } 
    552         return myHeight;
    553     }
    554 
    555     // -------------------------------------------------------------------------
    556     // Contructor + public and private definitions
    557     // -------------------------------------------------------------------------
    558     
    559     return function(inputConfig) {
    560     
    561         // --- private variables ---
    562         var me = this,
    563             myId = instanceNumber++,
    564             config = inputConfig || {},
    565             MAX_BOARD_COLS = 250,
    566             MAX_BOARD_ROWS = 250,
    567             blockWidth = 20,
    568             blockHeight = 20,
    569             GRID_FOOD_VALUE = -1, // the value of a spot on the board that represents snake food, MUST BE NEGATIVE
    570             myFood,
    571             mySnake,
    572             boardState = 1, // 0: in active; 1: awaiting game start; 2: playing game
    573             myKeyListener,
    574             // Board components
    575             elmContainer, elmPlayingField, elmAboutPanel, elmLengthPanel, elmWelcome, elmTryAgain;
    576         
    577         // --- public variables ---
    578         me.grid = [];
    579         
    580         // ---------------------------------------------------------------------
    581         // private functions
    582         // ---------------------------------------------------------------------
    583         
    584         function createBoardElements() {
    585             elmPlayingField = document.createElement("div");
    586             elmPlayingField.setAttribute("id", "playingField");
    587             elmPlayingField.className = "snake-playing-field";
    588             
    589             SNAKE.addEventListener(elmPlayingField, "click", function() {
    590                 elmContainer.focus();
    591             }, false);
    592             
    593             elmAboutPanel = document.createElement("div");
    594             elmAboutPanel.className = "snake-panel-component";
    595             elmAboutPanel.innerHTML = "";
    596             
    597             elmLengthPanel = document.createElement("div");
    598             elmLengthPanel.className = "snake-panel-component";
    599             elmLengthPanel.innerHTML = "";
    600             
    601             elmWelcome = createWelcomeElement();
    602             elmTryAgain = createTryAgainElement();
    603             
    604             SNAKE.addEventListener( elmContainer, "keyup", function(evt) {
    605                 if (!evt) var evt = window.event;
    606                 evt.cancelBubble = true;
    607                 if (evt.stopPropagation) {evt.stopPropagation();}
    608                 if (evt.preventDefault) {evt.preventDefault();}
    609                 return false;
    610             }, false);
    611             
    612             elmContainer.className = "snake-game-container";
    613             
    614             elmContainer.appendChild(elmPlayingField);
    615             elmContainer.appendChild(elmAboutPanel);
    616             elmContainer.appendChild(elmLengthPanel);
    617             elmContainer.appendChild(elmWelcome);
    618             elmContainer.appendChild(elmTryAgain);
    619             
    620             mySnake = new SNAKE.Snake({playingBoard:me,startRow:2,startCol:2});
    621             myFood = new SNAKE.Food({playingBoard: me});
    622             
    623             elmWelcome.style.zIndex = 1000;
    624         }
    625         function maxBoardWidth() {
    626             return MAX_BOARD_COLS * me.getBlockWidth();   
    627         }
    628         function maxBoardHeight() {
    629             return MAX_BOARD_ROWS * me.getBlockHeight();
    630         }
    631         
    632         function createWelcomeElement() {
    633             var tmpElm = document.createElement("div");
    634             tmpElm.id = "sbWelcome" + myId;
    635             tmpElm.className = "snake-welcome-dialog";
    636             
    637             var welcomeTxt = document.createElement("div");
    638             var fullScreenText = "";
    639             if (config.fullScreen) {
    640                 fullScreenText = "2.请使用Firefox或者chrome运行";   
    641             }
    642             welcomeTxt.innerHTML = "1.按箭头开始游戏,祝君好运 :) " +"</br>"+ fullScreenText + "<p></p>";
    643             var welcomeStart = document.createElement("button");
    644             welcomeStart.appendChild( document.createTextNode("Play Game"));
    645             
    646             var loadGame = function() {
    647                 SNAKE.removeEventListener(window, "keyup", kbShortcut, false);
    648                 tmpElm.style.display = "none";
    649                 me.setBoardState(1);
    650                 me.getBoardContainer().focus();
    651             };
    652             
    653             var kbShortcut = function(evt) {
    654                 if (!evt) var evt = window.event;
    655                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
    656                 if (keyNum === 32 || keyNum === 13) {
    657                     loadGame();
    658                 }
    659             };
    660             SNAKE.addEventListener(window, "keyup", kbShortcut, false);
    661             SNAKE.addEventListener(welcomeStart, "click", loadGame, false);
    662             
    663             tmpElm.appendChild(welcomeTxt);
    664             tmpElm.appendChild(welcomeStart);
    665             return tmpElm;
    666         }
    667         
    668         function createTryAgainElement() {
    669             var tmpElm = document.createElement("div");
    670             tmpElm.id = "sbTryAgain" + myId;
    671             tmpElm.className = "snake-try-again-dialog";
    672             
    673             var tryAgainTxt = document.createElement("div");
    674             tryAgainTxt.innerHTML = "啧啧,你死了! :(<p></p>";
    675             var tryAgainStart = document.createElement("button");
    676             tryAgainStart.appendChild( document.createTextNode("Play Again?"));
    677             
    678             var reloadGame = function() {
    679                 tmpElm.style.display = "none";
    680                 me.resetBoard();
    681                 me.setBoardState(1);
    682                 me.getBoardContainer().focus();
    683             };
    684             
    685             var kbTryAgainShortcut = function(evt) {
    686                 if (boardState !== 0 || tmpElm.style.display !== "block") {return;}
    687                 if (!evt) var evt = window.event;
    688                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
    689                 if (keyNum === 32 || keyNum === 13) {
    690                     reloadGame();
    691                 }
    692             };
    693             SNAKE.addEventListener(window, "keyup", kbTryAgainShortcut, true);
    694             
    695             SNAKE.addEventListener(tryAgainStart, "click", reloadGame, false);
    696             tmpElm.appendChild(tryAgainTxt);
    697             tmpElm.appendChild(tryAgainStart);
    698             return tmpElm;
    699         }
    700         
    701         // ---------------------------------------------------------------------
    702         // public functions
    703         // ---------------------------------------------------------------------
    704         
    705         /**
    706         * Resets the playing board for a new game.
    707         * @method resetBoard
    708         */   
    709         me.resetBoard = function() {
    710             SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false);
    711             mySnake.reset();
    712             elmLengthPanel.innerHTML = "Length: 1";
    713             me.setupPlayingField();
    714         };
    715         /**
    716         * Gets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving.
    717         * @method getBoardState
    718         * @return {Number} The state of the board.
    719         */  
    720         me.getBoardState = function() {
    721             return boardState;
    722         };
    723         /**
    724         * Sets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving.
    725         * @method setBoardState
    726         * @param {Number} state The state of the board.
    727         */  
    728         me.setBoardState = function(state) {
    729             boardState = state;
    730         };
    731         /**
    732         * @method getGridFoodValue
    733         * @return {Number} A number that represents food on a number representation of the playing board.
    734         */  
    735         me.getGridFoodValue = function() {
    736             return GRID_FOOD_VALUE;
    737         };
    738         /**
    739         * @method getPlayingFieldElement
    740         * @return {DOM Element} The div representing the playing field (this is where the snake can move).
    741         */ 
    742         me.getPlayingFieldElement = function() {
    743             return elmPlayingField;
    744         };
    745         /**
    746         * @method setBoardContainer
    747         * @param {DOM Element or String} myContainer Sets the container element for the game.
    748         */ 
    749         me.setBoardContainer = function(myContainer) {
    750             if (typeof myContainer === "string") {
    751                 myContainer = document.getElementById(myContainer);   
    752             }
    753             if (myContainer === elmContainer) {return;}
    754             elmContainer = myContainer;
    755             elmPlayingField = null;
    756             
    757             me.setupPlayingField();
    758         };
    759         /**
    760         * @method getBoardContainer
    761         * @return {DOM Element}
    762         */ 
    763         me.getBoardContainer = function() {
    764             return elmContainer;
    765         };
    766         /**
    767         * @method getBlockWidth
    768         * @return {Number}
    769         */ 
    770         me.getBlockWidth = function() {
    771             return blockWidth;  
    772         };
    773         /**
    774         * @method getBlockHeight
    775         * @return {Number}
    776         */ 
    777         me.getBlockHeight = function() {
    778             return blockHeight;  
    779         };
    780         /**
    781         * Sets up the playing field.
    782         * @method setupPlayingField
    783         */ 
    784         me.setupPlayingField = function () {
    785             
    786             if (!elmPlayingField) {createBoardElements();} // create playing field
    787             
    788             // calculate width of our game container
    789             var cWidth, cHeight;
    790             if (config.fullScreen === true) {
    791                 cTop = 0;
    792                 cLeft = 0;
    793                 cWidth = getClientWidth()-5;
    794                 cHeight = getClientHeight()-5;
    795                 document.body.style.backgroundColor = "#FC5454";
    796             } else {
    797                 cTop = config.top;
    798                 cLeft = config.left;
    799                 cWidth = config.width;
    800                 cHeight = config.height;
    801             }
    802             
    803             // define the dimensions of the board and playing field
    804             var wEdgeSpace = me.getBlockWidth()*2 + (cWidth % me.getBlockWidth());
    805             var fWidth = Math.min(maxBoardWidth()-wEdgeSpace,cWidth-wEdgeSpace);
    806             var hEdgeSpace = me.getBlockHeight()*3 + (cHeight % me.getBlockHeight());
    807             var fHeight = Math.min(maxBoardHeight()-hEdgeSpace,cHeight-hEdgeSpace);
    808             
    809             elmContainer.style.left = cLeft + "px";
    810             elmContainer.style.top = cTop + "px";
    811             elmContainer.style.width = cWidth + "px";
    812             elmContainer.style.height = cHeight + "px";
    813             elmPlayingField.style.left = me.getBlockWidth() + "px";
    814             elmPlayingField.style.top  = me.getBlockHeight() + "px";
    815             elmPlayingField.style.width = fWidth + "px";
    816             elmPlayingField.style.height = fHeight + "px";
    817             
    818             // the math for this will need to change depending on font size, padding, etc
    819             // assuming height of 14 (font size) + 8 (padding)
    820             var bottomPanelHeight = hEdgeSpace - me.getBlockHeight();
    821             var pLabelTop = me.getBlockHeight() + fHeight + Math.round((bottomPanelHeight - 30)/2) + "px";
    822             
    823             elmAboutPanel.style.top = pLabelTop;
    824             elmAboutPanel.style.width = "450px";
    825             elmAboutPanel.style.left = Math.round(cWidth/2) - Math.round(450/2) + "px";
    826             
    827             elmLengthPanel.style.top = pLabelTop;
    828             elmLengthPanel.style.left = cWidth - 120 + "px";
    829             
    830             // if width is too narrow, hide the about panel
    831             if (cWidth < 700) {
    832                 elmAboutPanel.style.display = "none";
    833             } else {
    834                 elmAboutPanel.style.display = "block";
    835             }
    836             
    837             me.grid = [];
    838             var numBoardCols = fWidth / me.getBlockWidth() + 2;
    839             var numBoardRows = fHeight / me.getBlockHeight() + 2;
    840             
    841             for (var row = 0; row < numBoardRows; row++) {
    842                 me.grid[row] = [];
    843                 for (var col = 0; col < numBoardCols; col++) {
    844                     if (col === 0 || row === 0 || col === (numBoardCols-1) || row === (numBoardRows-1)) {
    845                         me.grid[row][col] = 1; // an edge
    846                     } else {
    847                         me.grid[row][col] = 0; // empty space
    848                     }
    849                 }
    850             }
    851             
    852             myFood.randomlyPlaceFood();
    853             
    854             // setup event listeners
    855             
    856             myKeyListener = function(evt) {
    857                 if (!evt) var evt = window.event;
    858                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
    859 
    860                 if (me.getBoardState() === 1) {
    861                     if ( !(keyNum >= 37 && keyNum <= 40) ) {return;} // if not an arrow key, leave
    862                     
    863                     // This removes the listener added at the #listenerX line
    864                     SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false);
    865                     
    866                     myKeyListener = function(evt) {
    867                         if (!evt) var evt = window.event;
    868                         var keyNum = (evt.which) ? evt.which : evt.keyCode;
    869                         
    870                         mySnake.handleArrowKeys(keyNum);
    871                         
    872                         evt.cancelBubble = true;
    873                         if (evt.stopPropagation) {evt.stopPropagation();}
    874                         if (evt.preventDefault) {evt.preventDefault();}
    875                         return false;
    876                     };
    877                     SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false);
    878                     
    879                     mySnake.rebirth();
    880                     mySnake.handleArrowKeys(keyNum);
    881                     me.setBoardState(2); // start the game!
    882                     mySnake.go();
    883                 }
    884                 
    885                 evt.cancelBubble = true;
    886                 if (evt.stopPropagation) {evt.stopPropagation();}
    887                 if (evt.preventDefault) {evt.preventDefault();}
    888                 return false;
    889             };
    890             
    891             // Search for #listenerX to see where this is removed
    892             SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false);
    893         };
    894         
    895         /**
    896         * This method is called when the snake has eaten some food.
    897         * @method foodEaten
    898         */ 
    899         me.foodEaten = function() {
    900             elmLengthPanel.innerHTML = "Length: " + mySnake.snakeLength;
    901             myFood.randomlyPlaceFood();
    902         };
    903         
    904         /**
    905         * This method is called when the snake dies.
    906         * @method handleDeath
    907         */ 
    908         me.handleDeath = function() {
    909             var index = Math.max(getNextHighestZIndex( mySnake.snakeBody), getNextHighestZIndex( {tmp:{elm:myFood.getFoodElement()}} ));
    910             elmContainer.removeChild(elmTryAgain);
    911             elmContainer.appendChild(elmTryAgain);
    912             elmTryAgain.style.zIndex = index;
    913             elmTryAgain.style.display = "block";
    914             me.setBoardState(0);
    915         };
    916         
    917         // ---------------------------------------------------------------------
    918         // Initialize
    919         // ---------------------------------------------------------------------
    920 
    921         config.fullScreen = (typeof config.fullScreen === "undefined") ? false : config.fullScreen;        
    922         config.top = (typeof config.top === "undefined") ? 0 : config.top;
    923         config.left = (typeof config.left === "undefined") ? 0 : config.left;
    924         config.width = (typeof config.width === "undefined") ? 400 : config.width;        
    925         config.height = (typeof config.height === "undefined") ? 400 : config.height;
    926         
    927         if (config.fullScreen) {
    928             SNAKE.addEventListener(window,"resize", function() {
    929                 me.setupPlayingField();
    930             }, false);
    931         }
    932         
    933         me.setBoardState(0);
    934         
    935         if (config.boardContainer) {
    936             me.setBoardContainer(config.boardContainer);
    937         }
    938         
    939     }; // end return function
    940 
    941 })();
    View Code

    其中有段加密js代码:

     直接将加密代码放入控制台执行:

    PS:这里的flag是错误的!!!

    在DOM树发现flag:

    火狐浏览器在这里

     

    PS:需要勾选这些(输入日志类里)

     

    谷歌浏览器在这里:

     

    奶奶问孙子:4+1等于几 孙子说:等于6-1。 奶奶说:你明明知道答案,为什么不说? 孙子说:年轻人不讲5的……..
  • 相关阅读:
    js字符串拼接 ·${}·
    [转]CRLF Injection
    域渗透-GPP(组策略)利用
    AS-REPRoasting
    域用户名枚举
    我理解的HTTP请求走私(HTTP Request Smuggling)
    NFS未授权访问
    Hessian反序列化RCE漏洞
    CVE-2020-15778 Openssh命令注入漏洞复现
    在非域内机器上运行harphound
  • 原文地址:https://www.cnblogs.com/jasy/p/13791649.html
Copyright © 2020-2023  润新知