javascript - React 中的状态正在返回到原始值

标签 javascript reactjs

我正在尝试在React中实现类似地牢爬行游戏的流氓游戏,我在组件安装之前渲染 map 一次,然后使用levelRender()函数重新渲染关卡,但我的状态正在返回到其原始值这是由 componentWillMount() 函数设置的。调试显示状态正在被 levelRender() 函数更改,但最终它返回到原始状态,我认为这不应该发生。我知道我的代码有点长,但我猜有问题在于我调用 componentWillMount() 和 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"));

最佳答案

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

在第 452 行,正在调用 this.leverRender,这实际上设置了新的游戏状态(所需)。后来,在第 485 行,状态被变量映射覆盖,该变量映射具有旧值,这导致了不期望的输出。必须通过仅设置状态一次或设置两次但更新 map 值来解决此问题。

关于javascript - React 中的状态正在返回到原始值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47986675/

相关文章:

javascript - 我如何从 API 模块分派(dispatch) redux 操作?

javascript - js obj -> json 文件(ajax、php)

javascript - getElementById 给出结果加上字符串

Javascript "this"被事件监听器覆盖

javascript - 无法获取属性 'addEventListener'

javascript - js中如何实现字符串大小写?

javascript - 在图像缩略图中阅读更多内容

reactjs - 如何打开文本字段并在 react 中选择下拉列表中的某个值时设置其值

reactjs - 使用 Cognito 授权者从 API 网关返回 401 - 无论传入什么内容

javascript - net::ERR_CONNECTION_REFUSED 到cube.dv