使用React制作一个贪吃蛇游戏的代码详解

  // App.js

  import React, { Component } from "react";

  import Snake from "http://www.jb51.net/javascript/Components/Snake";

  import Food from "http://www.jb51.net/javascript/Components/Food";

  import Button from "http://www.jb51.net/javascript/Components/Button";

  import Menu from "http://www.jb51.net/javascript/Components/Menu";

  import "http://www.jb51.net/javascript/App.css";

  const getRandomFood = () => {

  let min = 1;

  let max = 98;

  let x = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;

  let y = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;

  return [x, y];

  };

  ​

  const initialState = {

  food: getRandomFood(),

  direction: "RIGHT",

  speed: 100,

  route: "menu",

  snakeDots: [

  [0, 0],

  [0, 2],

  ],

  };

  ​

  class App extends Component {

  constructor() {

  super();

  this.state = initialState;

  }

  ​

  componentDidMount() {

  setInterval(this.moveSnake, this.state.speed);

  document.onkeydown = this.onKeyDown;

  }

  ​

  componentDidUpdate() {

  this.onSnakeOutOfBounds();

  this.onSnakeCollapsed();

  this.onSnakeEats();

  }

  ​

  onKeyDown = (e) => {

  e.preventDefault();

  e = e || window.event;

  switch (e.keyCode) {

  case 37:

  this.setState({ direction: "LEFT" });

  break;

  case 38:

  this.setState({ direction: "UP" });

  break;

  case 39:

  this.setState({ direction: "RIGHT" });

  break;

  case 40:

  this.setState({ direction: "DOWN" });

  break;

  }

  };

  ​

  moveSnake = () => {

  let dots = [...this.state.snakeDots];

  let head = dots[dots.length - 1];

  if (this.state.route === "game") {

  switch (this.state.direction) {

  case "RIGHT":

  head = [head[0] + 2, head[1]];

  break;

  case "LEFT":

  head = [head[0] - 2, head[1]];

  break;

  case "DOWN":

  head = [head[0], head[1] + 2];

  break;

  case "UP":

  head = [head[0], head[1] - 2];

  break;

  }

  dots.push(head);

  dots.shift();

  this.setState({

  snakeDots: dots,

  });

  }

  };

  ​

  onSnakeOutOfBounds() {

  let head = this.state.snakeDots[this.state.snakeDots.length - 1];

  if (this.state.route === "game") {

  if (

  head[0] >= 100 ||

  head[1] >= 100 ||

  head[0] < 0 ||

  head[1] < 0

  ) {

  this.gameOver();

  }

  }

  }

  ​

  onSnakeCollapsed() {

  let snake = [...this.state.snakeDots];

  let head = snake[snake.length - 1];

  snake.pop();

  snake.forEach((dot) => {

  if (head[0] == dot[0] && head[1] == dot[1]) {

  this.gameOver();

  }

  });

  }

  ​

  onSnakeEats() {

  let head = this.state.snakeDots[this.state.snakeDots.length - 1];

  let food = this.state.food;

  if (head[0] == food[0] && head[1] == food[1]) {

  this.setState({

  food: getRandomFood(),

  });

  this.increaseSnake();

  this.increaseSpeed();

  }

  }

  ​

  increaseSnake() {

  let newSnake = [...this.state.snakeDots];

  newSnake.unshift([]);

  this.setState({

  snakeDots: newSnake,

  });

  }

  ​

  increaseSpeed() {

  if (this.state.speed > 10) {

  this.setState({

  speed: this.state.speed - 20,

  });

  }

  }

  ​

  onRouteChange = () => {

  this.setState({

  route: "game",

  });

  };

  ​

  gameOver() {

  alert(`GAME OVER, your score is ${this.state.snakeDots.length - 2}`);

  this.setState(initialState);

  }

  ​

  onDown = () => {

  let dots = [...this.state.snakeDots];

  let head = dots[dots.length - 1];

  ​

  head = [head[0], head[1] + 2];

  dots.push(head);

  dots.shift();

  this.setState({

  direction: "DOWN",

  snakeDots: dots,

  });

  };

  ​

  onUp = () => {

  let dots = [...this.state.snakeDots];

  let head = dots[dots.length - 1];

  ​

  head = [head[0], head[1] - 2];

  dots.push(head);

  dots.shift();

  this.setState({

  direction: "UP",

  snakeDots: dots,

  });

  };

  ​

  onRight = () => {

  let dots = [...this.state.snakeDots];

  let head = dots[dots.length - 1];

  ​

  head = [head[0] + 2, head[1]];

  dots.push(head);

  dots.shift();

  this.setState({

  direction: "RIGHT",

  snakeDots: dots,

  });

  };

  ​

  onLeft = () => {

  let dots = [...this.state.snakeDots];

  let head = dots[dots.length - 1];

  ​

  head = [head[0] - 2, head[1]];

  dots.push(head);

  dots.shift();

  this.setState({

  direction: "LEFT",

  snakeDots: dots,

  });

  };

  ​

  render() {

  const { route, snakeDots, food } = this.state;

  return (

  

  {route === "menu" ? (

  

  

  

  ) : (

  

  

  

  

  

  

  onDown={this.onDown}

  onLeft={this.onLeft}

  onRight={this.onRight}

  onUp={this.onUp}

  />

  

  )}

  

  );

  }

  }

  ​

  export default App;

  ​