zoukankan      html  css  js  c++  java
  • JS实现——贪吃蛇

    把以下代码保存成Snake.html文件,使用Google或360浏览器打开

    <!DOCTYPE HTML>
    <html>
    
    <head>
      <meta charset="utf-8" />
      <title>Snake</title>
    <style>
    </style>
    </head>
    
    <body>
    <div style="position: relative">
    
      <div style=" 400px; font-size: 22px; border: 3px solid black;">
        分数:<span id="score"></span>
      </div>
    
      <canvas id="myCanvas">your browser does not support the canvas</canvas>
    
      <div id="help" style="position: absolute; left: 420px; top: 40px;">
        Esc: 重新开始</br>
        Enter: 开始/暂停/继续</br>
        方向键: 改变蛇的移动方向</br>
        Ctrl: 切换控制模式(影响手感)</br>
        数字1: 加速</br>
        数字2: 减速</br>
      </div>
    
      <div id="gameStates" style="position: absolute; left: 420px; top: 200px; color: red">
        控制模式: <span id="controlMode"></span></br>
        运动状态: <span id="pause"></span></br>
        蛇的方向: <span id="snakeDir"></span></br>
        蛇的速度: <span id="snakeSpeed"></span></br>
        蛇的长度: <span id="snakeLength"></span></br>
        <span id="info"></span>
      </div>
    
    </div>
    </body>
    
    <script type="text/javascript">
    /*
     By Problue,2015.10.15
    */
    var KEY_L = 37;
    var KEY_U = 38;
    var KEY_R = 39;
    var KEY_D = 40;
    var KEY_RESET = 27 
    var KEY_PAUSE = 13;
    var KEY_CHANGE_CONTROL_MODE = 17;
    var KEY_INC_SPEED = 49;
    var KEY_DEC_SPEED = 50;
    var MAP_R = 20;
    var MAP_C = 20;
    var SNAKE_LENGTH_MAX = MAP_R * MAP_C;
    var OBJ_SIZE = 20;
    var OBJ = {
      EMPTY: 0,
      SNAKE_HEAD: 1,
      SNAKE_BODY: 2,
      SNAKE_TAIL: 3,
      FOOD: 4,
      STONE: 5
    };
    var colors = ['white', 'midnightblue', 'darkblue', 'mediumblue', 'midnightblue', 'dimgray'];
    
    var mapData = "
    00000000000000000000
    00000000000000000000
    00000000000000000000
    50000000500000055000
    00000000000000005000
    00055000000005500000
    00050000000000500000
    00000550000550000000
    00000500000050000000
    00000000000000000000
    00000000000000000000
    00000005000050000000
    00000005500550000000
    00000500000000500000
    00000550000005500000
    00050000000000000000
    00055000000000050005
    00000000000000000000
    00000000000000000000
    00000000000000000000";
    
    var map = [];
    
    var snake = new Snake();
    var food = new Point(0, 0);
    //var time;
    
    var pause;
    var over;
    var controlQueueMode;
    var controlQueue = new Queue();
    var score;
    
    function Snake() {
      this.nodes = [];
      this.dir = 0;
      this.msSpeed = 0;
    }
    
    function Point(x, y) {
      this.x = x;
      this.y = y;
    }
    
    Point.prototype.clone = function() {
      return new Point(this.x, this.y);
    }
    
    Point.prototype.equals = function(other) {
      if(other === this)
        return true;
      if(!(other instanceof Point))
        return false;
      return this.x == other.x && this.y == other.y;
    }
    
    function Queue() {
      this.arr = [];
      this.head = 0;
      this.tail = 0;
    }
    
    Queue.prototype.enQueue = function(elem) {
      this.tail++;
      this.arr[this.tail] = elem;
    }
    
    Queue.prototype.deQueue = function() {
      this.head++;
      return this.arr[this.head];
    }
    
    Queue.prototype.empty = function() {
      return this.head >= this.tail;
    }
    
    Queue.prototype.clear = function() {
      this.arr.length = 0;
      this.head = 0;
      this.tail = 0;
    }
    
    start();
    
    function start() {
      initGame();
      initMap();
      initSnake();
      drawMap();
      showGameStates();
      updateScore();
      drawSnake();
      randFood();
      drawObj(food, OBJ.FOOD);
    }
    
    function initGame() {
      canvas = document.getElementById('myCanvas');
      cxt = canvas.getContext('2d');
      canvas.width = MAP_C * OBJ_SIZE;
      canvas.height = MAP_R * OBJ_SIZE;
      canvas.style.border = '3px solid black';
      document.onkeydown = keydown;
      //time = +new Date;
      pause = true;
      over = 0;
      controlQueueMode = true;
      score = 0;
    }
    
    function initMap() {
      for(var r = 0; r < MAP_R; r++) {
        map.push([]);
        for(var c = 0; c < MAP_C; c++) {
          var obj = mapData[r * MAP_C + c] - 0;
          map[r][c] = obj;
        }
      }
    }
    
    function initSnake() {
      snake.nodes.length = 0;
      snake.nodes.push(new Point(2, 0));
      snake.nodes.push(new Point(1, 0));
      snake.nodes.push(new Point(0, 0));
      snake.dir = KEY_R;
      snake.msSpeed = 150;
    }
    
    function keydown(event) {
      var key = window.event ? event.keyCode : event.which;
      switch(key) {
      case KEY_U:
        if(snake.dir != KEY_D) {
          snake.dir = key;
          controlQueue.enQueue(snake.dir);
        }
        break;
      case KEY_D:
        if(snake.dir != KEY_U) {
          snake.dir = key;
          controlQueue.enQueue(snake.dir);
        }
        break;
      case KEY_L:
        if(snake.dir != KEY_R) {
          snake.dir = key;
          controlQueue.enQueue(snake.dir);
        }
        break;
      case KEY_R:
        if(snake.dir != KEY_L) {
          snake.dir = key;
          controlQueue.enQueue(snake.dir);
        }
        break;
      case KEY_RESET:
        start();
        break;
      case KEY_PAUSE:
        pause = !pause;
        if(!pause) {
          controlQueue.clear();
          move();
        }
        break;
      case KEY_CHANGE_CONTROL_MODE:
        controlQueueMode = !controlQueueMode;
        controlQueue.clear();
        break;
      case KEY_INC_SPEED:
        snake.msSpeed -= 10;
        break;
      case KEY_DEC_SPEED:
        snake.msSpeed += 10;
        break;
      default: ;
      }
      showGameStates();
    }
    
    function moveStep() {
      showGameStates();
      var newHead = snake.nodes[0].clone();
      var oldTail = snake.nodes[snake.nodes.length - 1].clone();
    
      switch(snake.dir) {
      case KEY_U:
        newHead.y--;
        break;
      case KEY_R:
        newHead.x++;
        break;
      case KEY_L:
        newHead.x--;
        break;
      case KEY_D:
        newHead.y++;
        break;
      }
    
      var coord = '坐标(' + snake.nodes[0].x + ',' + snake.nodes[0].y + ')是';
      info(coord + '空');
      if((newHead.x > MAP_C - 1 || newHead.x < 0) ||
         (newHead.y > MAP_R - 1 || newHead.y < 0)) {
        info(coord + '墙壁');
        over = 1;
        return;
      }
    
      if(isInSnake(newHead)) {
        info(coord + '自己');
        over = 2;
        return;
      }
      
      var thing = map[newHead.y][newHead.x];
    
      if(thing == OBJ.STONE) {
        info(coord + '石头');
        over = 3;
        return;
      }
      
      if(thing == OBJ.FOOD) {
        info(coord + '食物');
        snake.nodes.push(new Point(0, 0));
        map[newHead.y][newHead.x] = OBJ.EMPTY;
        randFood();
        drawObj(food, OBJ.FOOD);
        updateScore();
        showGameStates();
      }
    
      for(var i = snake.nodes.length - 1; i >= 1; i--)
        snake.nodes[i] = snake.nodes[i - 1].clone();
      snake.nodes[0] = newHead;
      drawObj(oldTail, OBJ.EMPTY);
      drawSnake();
    }
    
    function move() {
      if(pause)
        return;
    
      if(controlQueueMode && !controlQueue.empty())
        snake.dir = controlQueue.deQueue();
    
      moveStep();
    
      if(over) {
        over = 0;
        var turn = [];
        turn[KEY_U] = KEY_R;
        turn[KEY_D] = KEY_L;
        turn[KEY_L] = KEY_U;
        turn[KEY_R] = KEY_D;
        snake.dir = turn[snake.dir];
      }
    
      setTimeout(move, snake.msSpeed);
    }
    
    function isInSnake(point) {
      for(var i = 0; i < snake.nodes.length; i++)
        if(snake.nodes[i].equals(point))
          return true;
      return false;
    }
    
    function randFood() {
      function randInt(n, m) {
        return Math.floor(Math.random() * (m - n)) + n;
      }
      function smart(pt) {
        if(pt.x == snake.nodes[0].x) {
          if(snake.dir == KEY_U)
            return pt.x - snake.nodes[0].x < 0;
          if(snake.dir == KEY_D)
            return pt.x - snake.nodes[0].x > 0;
        }
        if(pt.y == snake.nodes[0].y) {
          if(snake.dir == KEY_L)
            return pt.y - snake.nodes[0].y < 0;
          if(snake.dir == KEY_R)
            return pt.y - snake.nodes[0].y > 0;
        }
        return false;
      }
      do
      {
        food.x = randInt(0, MAP_C);
        food.y = randInt(0, MAP_R);
      } while(isInSnake(food) || smart(food) ||
        map[food.y][food.x] != OBJ.EMPTY);
      map[food.y][food.x] = OBJ.FOOD;
    }
    
    function info(str) {
      $('info').innerHTML = str;
    }
    
    function showGameStates() {
      $('pause').innerHTML = pause ? '静止' : '移动';
      $('controlMode').innerHTML = controlQueueMode ? '队列' : '普通';
      var toText = [];
      toText[KEY_L] = '左';
      toText[KEY_U] = '上';
      toText[KEY_R] = '右';
      toText[KEY_D] = '下';
      $('snakeDir').innerHTML = toText[snake.dir];
      $('snakeSpeed').innerHTML = snake.msSpeed + 'ms/' + OBJ_SIZE + 'px';
      $('snakeLength').innerHTML = snake.nodes.length;
    }
    
    function updateScore() {
      $('score').innerHTML = score++;
    }
    
    
    function drawMap() {
      var pt = new Point(0, 0);
      for(var r = 0; r < MAP_R; r++) {
        for(var c = 0; c < MAP_C; c++) {
          if(map[r][c] == OBJ.STONE) {
            pt.x = c;
            pt.y = r;
            drawObj(pt, OBJ.STONE);
          }
        }
      }
    }
    
    function drawSnake() {
      drawObj(snake.nodes[0], OBJ.SNAKE_HEAD);
      for(var i = 1; i < snake.nodes.length - 1; i++)
        drawObj(snake.nodes[i], OBJ.SNAKE_BODY);
      drawObj(snake.nodes[snake.nodes.length - 1], OBJ.SNAKE_TAIL);
    }
    
    function drawObj(point, type) {
      cxt.fillStyle = colors[type];
      cxt.fillRect(point.x * OBJ_SIZE, point.y * OBJ_SIZE,
        OBJ_SIZE, OBJ_SIZE);
    }
    
    function $(id) {
      return document.getElementById(id);
    }
    </script>
    
    </html>

    出处:qq群--编程算法&思想 459909287

  • 相关阅读:
    Zabbix5 Frame 嵌套
    Zabbix5 对接 SAML 协议 SSO
    CentOS7 安装 Nexus
    CentOS7 安装 SonarQube
    GitLab 后台修改用户密码
    GitLab 查看版本号
    GitLab Admin Area 500 Error
    Linux 安装 PostgreSQL
    Liger ui grid 参数
    vue.js 是一个怪东西
  • 原文地址:https://www.cnblogs.com/mq0036/p/4946076.html
Copyright © 2011-2022 走看看