react in react返回原始值

时间:2017-12-27 05:15:09

标签: javascript reactjs

我正在尝试实施一个像dungeon crawler游戏一样的流氓反应,我在组件安装一次之前渲染地图,然后我使用levelRender()函数重新渲染关卡,但我的状态又回到了它由componentWillMount()函数设置的原始值。调试显示状态正在由levelRender()函数进行查询,但最后它返回到原始状态,我认为不应该发生这种状态。我知道我的代码有点长但我想问题在于我调用componentWillMount()和levelRender()函数。

在游戏中,棕色框是应该触发levelRender的门户,当它被红色框播放器运行时。

这里是我codepen的链接,使用箭头键移动:)

const Map = React.createClass({

  getInitialState() {
    return {

      width: 40,
      height: 50,
      wallRender: 0,
      gameLevel: 0,
      Probabilities: {
        levelA: [3, 5, 2],
        levelB: [3.5, 3, 3.5],
        levelC: [8, 1, 1]
      }

    }
  },

  componentWillMount() {
    document.addEventListener("keydown", this.handleKeyDown, false);


    var map = [];
    var rooms = [];
    var render = [];
    var level = this.state.gameLevel;
    //use rot.js to generate map
    var w = this.state.width,
      h = this.state.height;
    var objects = ["e", "h", "w"];
    var probability;


    var enemies = [];
    var weapon = [];
    var health = []

    if (level == 0) {
      probability = this.state.Probabilities.levelA;
    } else if (level == 1) {
      probability = this.state.Probabilities.levelB;
    } else {
      probability = this.state.Probabilities.levelC;
    }


    // var map = new ROT.Map.Digger();
    var data = {};
    var rotMap = new ROT.Map.Rogue(w, h);

    var display = new ROT.Display({ width: w, height: h, fontSize: 6 });


    rotMap.create(function (x, y, type) {
      data[x + "," + y] = type;
      display.DEBUG(x, y, type);
    })






    map = rotMap.map;
    var rooms = rotMap.rooms;
    // console.log(map);
    // console.log(rooms)



    var playerPosition = [rooms[0][0].x + 1, rooms[0][0].y + 1];
    var portalPosition = [rooms[2][2].x + 2, rooms[2][2].y + 2];
    // console.log(playerPosition)

    map[playerPosition[0]][playerPosition[1]] = "p";
    map[portalPosition[0]][portalPosition[1]] = "*";
    var pp = playerPosition;
    //     
    // set up enemies and health
    rooms.map(function (rooms) {
      rooms.map(function (room) {


        var rx = room.x; var ry = room.y;

        var noe = Math.floor(Math.random() * ((1 + 2) - 2 + 1)) + 2;


        for (var i = 0; i < noe; i++) {
          //     generate enemy postions
          var ex = Math.floor(Math.random() * ((room.width + rx) - rx + 1)) + rx;
          var ey = Math.floor(Math.random() * ((room.height + ry) - ry + 1)) + ry;




          if ((ex >= rx && ex < room.width + rx) && (ey >= ry && ey < room.height + ry)) {

            var totalProbability = eval(probability.join("+"));//get total weight (in this case, 10)
            var weighedObjects = new Array();//new array to hold "weighted" fruits
            var currentObject = 0;

            while (currentObject < objects.length) {
              for (i = 0; i < probability[currentObject]; i++)
                weighedObjects[weighedObjects.length] = objects[currentObject]
              currentObject++
            }

            var randomnumber = Math.floor(Math.random() * totalProbability)
            var x = weighedObjects[randomnumber];

            if (x == 'e') {
              map[ex][ey] = "e";
              var stats = {
                loc: ex + " " + ey,
                health: 50,
                damage: 20
              }
              enemies.push(stats)

            } else if (x == 'h') {
              map[ex][ey] = "h";
              var stats = {
                loc: ex + " " + ey,
                boost: 80
              }
              health.push(stats)

            } else if (x == 'w') {
              map[ex][ey] = "w";
              var stats = {
                loc: ex + " " + ey,
                damageBoost: 40
              }
              weapon.push(stats)
            }






            // console.log(ex + " " + ey + " " + (room.width + rx) + " " + (room.height + ry))
          }




        }





      })
    })



    //     place enemy

    // console.log(enemies);
    // console.log(health);
    // console.log(weapon)



    //    setup field of view
    var fov = this.setFov(pp)

    this.setState({
      gameState: map,
      gameRooms: rooms,
      playerPosition: playerPosition,
      playerHealth: 50,
      playerDamage: 5,
      portalPosition: portalPosition,
      fov: fov,
      enemies: enemies,
      health: health,
      weapon: weapon

    });




  },

  levelRender(){
    console.log("level rendered")
    var map = [];
    var rooms = [];
    var render = [];
    var level=this.state.gameLevel;

    //use rot.js to generate map
    var w = this.state.width,
      h = this.state.height;
    var objects = ["e", "h", "w"];
    var probability;

    var enemies = [];
    var weapon = [];
    var health = []

    if (level == 0) {
      probability = this.state.Probabilities.levelA;
    } else if (level == 1) {
      probability = this.state.Probabilities.levelB;
    } else {
      probability = this.state.Probabilities.levelC;
    }


    // var map = new ROT.Map.Digger();
    var data = {};
    var rotMap = new ROT.Map.Rogue(w, h);

    var display = new ROT.Display({ width: w, height: h, fontSize: 6 });


    rotMap.create(function (x, y, type) {
      data[x + "," + y] = type;
      display.DEBUG(x, y, type);
    })






    map = rotMap.map;
    var rooms = rotMap.rooms;




    var playerPosition = [rooms[0][0].x + 1, rooms[0][0].y + 1];

    if(level==0 || level ==1){
      var portalPosition = [rooms[2][2].x + 2, rooms[2][2].y + 2];
      map[portalPosition[0]][portalPosition[1]] = "*";
    }else{
      var bossPosition = [rooms[2][2].x + 2, rooms[2][2].y + 2];
      map[portalPosition[0]][portalPosition[1]] = "boss";
    }





    map[playerPosition[0]][playerPosition[1]] = "p";

    var pp = playerPosition;
    //     
    // set up enemies and health
    rooms.map(function (rooms) {
      rooms.map(function (room) {


        var rx = room.x; var ry = room.y;

        var noe = Math.floor(Math.random() * ((1 + 2) - 2 + 1)) + 2;


        for (var i = 0; i < noe; i++) {
          //     generate enemy postions
          var ex = Math.floor(Math.random() * ((room.width + rx) - rx + 1)) + rx;
          var ey = Math.floor(Math.random() * ((room.height + ry) - ry + 1)) + ry;




          if ((ex >= rx && ex < room.width + rx) && (ey >= ry && ey < room.height + ry)) {

            var totalProbability = eval(probability.join("+"));//get total weight (in this case, 10)
            var weighedObjects = new Array();//new array to hold "weighted" fruits
            var currentObject = 0;

            while (currentObject < objects.length) {
              for (i = 0; i < probability[currentObject]; i++)
                weighedObjects[weighedObjects.length] = objects[currentObject]
              currentObject++
            }

            var randomnumber = Math.floor(Math.random() * totalProbability)
            var x = weighedObjects[randomnumber];

            if (x == 'e') {
              map[ex][ey] = "e";
              var stats = {
                loc: ex + " " + ey,
                health: 50,
                damage: 20
              }
              enemies.push(stats)

            } else if (x == 'h') {
              map[ex][ey] = "h";
              var stats = {
                loc: ex + " " + ey,
                boost: 80
              }
              health.push(stats)

            } else if (x == 'w') {
              map[ex][ey] = "w";
              var stats = {
                loc: ex + " " + ey,
                damageBoost: 40
              }
              weapon.push(stats)
            }






            // console.log(ex + " " + ey + " " + (room.width + rx) + " " + (room.height + ry))
          }




        }





      })
    })

    //    setup field of view
    var fov = this.setFov(pp)

    console.log(this.state.gameState)

    this.setState({
      gameState: map,
      gameRooms: rooms,
      playerPosition: playerPosition,
      bossPosition:bossPosition,
      portalPosition: portalPosition,
      fov: fov,
      enemies: enemies,
      health: health,
      weapon: weapon

    });
 console.log(this.state.gameState)


  },

  setFov(playerPos) {
    var pp = playerPos;
    var fov = [];
    var x = pp[0]; var y = pp[1];

    fov.push(x - 2 + "," + (y - 1)); fov.push(x - 2 + "," + y); fov.push(x - 2 + "," + (y + 1));
    fov.push(x - 1 + "," + (y - 2)); fov.push(x - 1 + "," + (y - 1)); fov.push(x - 1 + "," + y); fov.push(x - 1 + "," + (y + 1)); fov.push(x - 1 + "," + (y + 2));
    fov.push(x + "," + (y - 2)); fov.push(x + "," + (y - 1)); fov.push(x + "," + y); fov.push(x + "," + (y + 1)); fov.push(x + "," + (y + 2));
    fov.push(x + 1 + "," + (y - 2)); fov.push(x + 1 + "," + (y - 1)); fov.push(x + 1 + "," + y); fov.push(x + 1 + "," + (y + 1)); fov.push(x + 1 + "," + (y + 2));
    fov.push(x + 2 + "," + (y - 1)); fov.push(x + 2 + "," + y); fov.push(x + 2 + "," + (y + 1));
    fov.push(x - 3 + "," + y); fov.push(x + 3 + "," + y); fov.push(x + "," + (y - 3)); fov.push(x + "," + (y + 3))

    return fov;
  },

  handleKeyDown(e) {
    //     left arrow
    var playerLoc = this.state.playerPosition;
    if (e.keyCode == 37) {

      var map = this.state.gameState;
      var playerPos = this.state.playerPosition;
      var x = playerPos[0], y = playerPos[1];

      // console.log(map)
      // console.log(playerPos)
      if (map[(x)][(y - 1)] == 0 || map[(x)][(y - 1)] == "w" || map[(x)][(y - 1)] == "h" || map[(x)][(y - 1)] == "*") {

        if (map[(x)][(y - 1)] == "*") {
           var level = this.state.gameLevel + 1;

         this.setState({
        gameLevel:level
          })
          this.levelRender();

        }

        if (map[(x)][(y - 1)] == "h") {
          var health = this.state.playerHealth + 30;
          this.setState({
            playerHealth: health
          })
        }
        if (map[(x)][(y - 1)] == "w") {
          var damage = this.state.playerDamage + 20;
          this.setState({
            playerDamage: damage
          })
        }

        map[x][y] = 0;
        map[(x)][(y - 1)] = "p";

        playerPos[0] = x
        playerPos[1] = y - 1;
      }
      //      change fov

      var pp = playerPos;

      var fov = this.setFov(pp)




      this.setState({
        gameState: map,
        playerPosition: playerPos,
        fov: fov
      })

    }
    //  up arrow
    if (e.keyCode == 38) {

      var map = this.state.gameState;
      var playerPos = this.state.playerPosition;
      var x = playerPos[0], y = playerPos[1];
      // console.log(map)
      // console.log(playerPos)

      if (map[(x - 1)][(y)] == 0 || map[(x - 1)][(y)] == "w" || map[(x - 1)][(y)] == "h") {

        // update player health and damage
        if (map[(x - 1)][(y)] == "h") {
          var health = this.state.playerHealth + 30;
          this.setState({
            playerHealth: health
          })
        }
        if (map[(x - 1)][(y)] == "w") {
          var damage = this.state.playerDamage + 20;
          this.setState({
            playerDamage: damage
          })
        }


        map[x][y] = 0;
        map[(x - 1)][(y)] = "p";

        playerPos[0] = x - 1
        playerPos[1] = y;
      }

      // console.log(map)
      // console.log(playerPos)
      //      change fov
      var pp = playerPos;

      var fov = this.setFov(pp)

      this.setState({
        gameState: map,
        playerPosition: playerPos,
        fov: fov
      })

    }
    //   right arrow
    if (e.keyCode == 39) {
      var map = this.state.gameState;
      var playerPos = this.state.playerPosition;
      var x = playerPos[0], y = playerPos[1];
      // console.log(map)
      // console.log(playerPos)
      if (map[(x)][(y + 1)] == 0 || map[(x)][(y + 1)] == "w" || map[(x)][(y + 1)] == "h") {

        // update player health and damage
        if (map[(x)][(y + 1)] == "h") {
          var health = this.state.playerHealth + 30;
          this.setState({
            playerHealth: health
          })
        }
        if (map[(x)][(y + 1)] == "w") {
          var damage = this.state.playerDamage + 20;
          this.setState({
            playerDamage: damage
          })
        }


        map[x][y] = 0;
        map[(x)][(y + 1)] = "p";
        playerPos[0] = x
        playerPos[1] = y + 1;;
      }


      //console.log(map)
      //console.log(playerPos)

      //      change fov
      var pp = playerPos;

      var fov = this.setFov(pp)
      this.setState({
        gameState: map,
        playerPosition: playerPos,
        fov: fov
      })
    }
    //    down arrow
    if (e.keyCode == 40) {
      var map = this.state.gameState;
      var playerPos = this.state.playerPosition;
      var x = playerPos[0], y = playerPos[1];

      if (map[(x + 1)][(y)] == 0 || map[(x + 1)][(y)] == "w" || map[(x + 1)][(y)] == "h") {

        // update player health and damage
        if (map[(x + 1)][(y)] == "h") {
          var health = this.state.playerHealth + 30;
          this.setState({
            playerHealth: health
          })
        }
        if (map[(x + 1)][(y)] == "w") {
          var damage = this.state.playerDamage + 20;
          this.setState({
            playerDamage: damage
          })
        }


        map[x][y] = 0;
        map[(x + 1)][(y)] = "p";
        playerPos[0] = x + 1
        playerPos[1] = y;
      }


      // console.log(map)
      // console.log(playerPos)
      //      change fov
      var pp = playerPos;

      var fov = this.setFov(pp)

      this.setState({
        gameState: map,
        playerPosition: playerPos,
        fov: fov
      })
    }


  },

  render() {



    //    rendering map

    var map = this.state.gameState;
    var fov = this.state.fov;

    if(this.state.gameLevel==1){
      console.log(map)
    }


    var render = [];



    for (var i = 0; i < this.state.width; i++) {
      var dummy = [];

      for (var j = 0; j < this.state.height; j++) {
        var arena = { background: "white", color: "white" };
        var wallColor = "grey";






        var wall = { background: wallColor, color: wallColor, border: "2px solid black" };
        var enemy = { background: "blue", color: "blue" };
        var player = { background: "red", color: "red" };
        var health = { background: "green", color: "green" }
        var weapon = { background: "orange", color: "orange" }
        var portal = { background: "brown", color: "brown" }
        var boss ={background:"yellow",color:"yellow"}
        //       check if cell is in fov  
        var val = i + "," + j;




        if (map[i][j] == 0) {
          //           implement field of view
          var x = arena;
          //                       if (fov.includes(val)) {
          //                         x.visibility = "visible";
          //                         console.log(val)

          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td style={x}>00;</td>);
        } else if (map[i][j] == "p") {
          dummy.push(<td style={player}>00;</td>);
        } else if (map[i][j] == "e") {
          var x = enemy;
          //                        if (fov.includes(val)) {
          //                         x.visibility = "visible";


          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td border={5} style={enemy}>00;</td>);
        } else if (map[i][j] == "h") {
          var x = health;
          //                        if (fov.includes(val)) {
          //                         x.visibility = "visible";


          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td style={health}>00;</td>);
        } else if (map[i][j] == "*") {
          var x = portal;
          //                        if (fov.includes(val)) {
          //                         x.visibility = "visible";


          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td style={portal}>00;</td>);
        }

        else if (map[i][j] == "w") {
          var x = weapon;
          //                        if (fov.includes(val)) {
          //                         x.visibility = "visible";


          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td style={weapon}>00;</td>);
        }else if (map[i][j] == "boss") {
          var x = boss;
          //                        if (fov.includes(val)) {
          //                         x.visibility = "visible";


          //                       } else {
          //                         x.visibility = "hidden";
          //                       }

          dummy.push(<td style={boss}>00;</td>);
        }


        else {
          var x = wall;
          //                       if (fov.includes(val)) {
          //                         x.visibility = "visible";
          //             //             console.log(val)

          //                       } else {
          //                         x.visibility = "hidden";
          //                       }
          // generate random hue of colors

          dummy.push(<td style={wall}>00;</td>);
        }
      }

      render.push(<tr>{dummy}</tr>);
    }





    return (
      <div>
        <div id="info">
          <span id="health">Health:{this.state.playerHealth} </span>
          <span id="damage">Damage:{this.state.playerDamage} </span>
          <span id="message">{this.state.playerMessage}</span>
        </div>


        <div id="gameArea" tabIndex="0" >

          <table align="right">
            {render}
          </table>
        </div>
      </div>
    )

  }


})




ReactDOM.render(<Map />, document.getElementById("app"));

1 个答案:

答案 0 :(得分:1)

您正在levelRender中设置状态,并使用之前的状态覆盖相同的状态。

在第452行,正在调用this.leverRender,这实际上设置了新游戏状态(所需)。之后,在485行,状态被变量映射覆盖,变量映射具有旧值,这是造成不希望的输出的原因。这必须通过仅设置一次状态,或者设置两次但使用更新的map值来解决。