将js转换为反应组件的问题

时间:2018-05-05 00:12:08

标签: javascript reactjs

我想要这个蛇应用程序,作为反应组件,我整天都在工作,没有解决方案。我最近删除了我的内容并意外关闭了文件,所以我从头开始。我想在组件中使用它的原因是因为我想访问状态和道具以供其他用途。



+

/**
 * Namespace
 */
var Game = Game || {};
var Keyboard = Keyboard || {};
var Component = Component || {};

/**
 * Keyboard Map
 */
Keyboard.Keymap = {
  37: 'left',
  38: 'up',
  39: 'right',
  40: 'down'
};

/**
 * Keyboard Events
 */
Keyboard.ControllerEvents = function() {

  // Setts
  var self = this;
  this.pressKey = null;
  this.keymap = Keyboard.Keymap;

  // Keydown Event
  document.onkeydown = function(event) {
    self.pressKey = event.which;
  };

  // Get Key
  this.getKey = function() {
    return this.keymap[this.pressKey];
  };
};

/**
 * Game Component Stage
 */
Component.Stage = function(canvas, conf) {

  // Sets
  this.keyEvent = new Keyboard.ControllerEvents();
  this.width = canvas.width;
  this.height = canvas.height;
  this.length = [];
  this.food = {};
  this.score = 0;
  this.direction = 'right';
  this.conf = {
    cw: 10,
    size: 5,
    fps: 1000
  };

  // Merge Conf
  if (typeof conf == 'object') {
    for (var key in conf) {
      if (conf.hasOwnProperty(key)) {
        this.conf[key] = conf[key];
      }
    }
  }

};

/**
 * Game Component Snake
 */
Component.Snake = function(canvas, conf) {

  // Game Stage
  this.stage = new Component.Stage(canvas, conf);

  // Init Snake
  this.initSnake = function() {

    // Itaration in Snake Conf Size
    for (var i = 0; i < this.stage.conf.size; i++) {

      // Add Snake Cells
      this.stage.length.push({
        x: i,
        y: 0
      });
    }
  };

  // Call init Snake
  this.initSnake();

  // Init Food  
  this.initFood = function() {

    // Add food on stage
    this.stage.food = {
      x: Math.round(Math.random() * (this.stage.width - this.stage.conf.cw) / this.stage.conf.cw),
      y: Math.round(Math.random() * (this.stage.height - this.stage.conf.cw) / this.stage.conf.cw),
    };
  };

  // Init Food
  this.initFood();

  // Restart Stage
  this.restart = function() {
    this.stage.length = [];
    this.stage.food = {};
    this.stage.score = 0;
    this.stage.direction = 'right';
    this.stage.keyEvent.pressKey = null;
    this.initSnake();
    this.initFood();
  };
};

/**
 * Game Draw
 */
Game.Draw = function(context, snake) {

  // Draw Stage
  this.drawStage = function() {

    // Check Keypress And Set Stage direction
    var keyPress = snake.stage.keyEvent.getKey();
    if (typeof(keyPress) != 'undefined') {
      snake.stage.direction = keyPress;
    }

    // Draw White Stage
    context.fillStyle = "white";
    context.fillRect(0, 0, snake.stage.width, snake.stage.height);

    // Snake Position
    var nx = snake.stage.length[0].x;
    var ny = snake.stage.length[0].y;

    // Add position by stage direction
    switch (snake.stage.direction) {
      case 'right':
        nx++;
        break;
      case 'left':
        nx--;
        break;
      case 'up':
        ny--;
        break;
      case 'down':
        ny++;
        break;
    }

    // Check Collision
    if (this.collision(nx, ny) == true) {
      snake.restart();
      return;
    }

    // Logic of Snake food
    if (nx == snake.stage.food.x && ny == snake.stage.food.y) {
      var tail = {
        x: nx,
        y: ny
      };
      snake.stage.score++;
      snake.initFood();
    } else {
      var tail = snake.stage.length.pop();
      tail.x = nx;
      tail.y = ny;
    }
    snake.stage.length.unshift(tail);

    // Draw Snake
    for (var i = 0; i < snake.stage.length.length; i++) {
      var cell = snake.stage.length[i];
      this.drawCell(cell.x, cell.y);
    }

    // Draw Food
    this.drawCell(snake.stage.food.x, snake.stage.food.y);

    // Draw Score
    context.fillText('Score: ' + snake.stage.score, 5, (snake.stage.height - 5));
  };

  // Draw Cell
  this.drawCell = function(x, y) {
    context.fillStyle = 'rgb(170, 170, 170)';
    context.beginPath();
    context.arc((x * snake.stage.conf.cw + 6), (y * snake.stage.conf.cw + 6), 4, 0, 2 * Math.PI, false);
    context.fill();
  };

  // Check Collision with walls
  this.collision = function(nx, ny) {
    if (nx == -1 || nx == (snake.stage.width / snake.stage.conf.cw) || ny == -1 || ny == (snake.stage.height / snake.stage.conf.cw)) {
      return true;
    }
    return false;
  }
};


/**
 * Game Snake
 */
Game.Snake = function(elementId, conf) {

  // Sets
  var canvas = document.getElementById(elementId);
  var context = canvas.getContext("2d");
  var snake = new Component.Snake(canvas, conf);
  var gameDraw = new Game.Draw(context, snake);

  // Game Interval
  setInterval(function() {
    gameDraw.drawStage();
  }, snake.stage.conf.fps);
};


/**
 * Window Load
 */
window.onload = function() {
  var snake = new Game.Snake('stage', {
    fps: 100,
    size: 4
  });
};
&#13;
body {
  text-align: center;
  font-family: helvetica;
}

canvas {
  border: 2px solid rgb(151, 149, 149);
}
&#13;
&#13;
&#13;

我已经制作了我想要的所有自定义mod,但是,因为JavaScript不在组件的一边,所以我无法访问&#34; auth&#34;陈述并发出行动。任何帮助都会很棒!

编辑:

我想访问道具,以便在用户发生碰撞时调用此函数。

<h3>Simple Snake Game</h3>
<canvas id="stage" height="400" width="520"></canvas>

1 个答案:

答案 0 :(得分:0)

将JS包含在React组件或导入的库中,但删除窗口onload代码:

/**
 * Window Load
 */
window.onload = function() {
  var snake = new Game.Snake('stage', {fps: 100, size: 4});
};

并将其添加到您的React组件:

constructor(props) {
     super(props);
     this.snake = null;
}

componentDidMount() {
    this.snake = new Game.Snake('stage', {fps: 100, size: 4});
}

然后你可以访问this.snake for state等。