2017-12-27 3 views
0

저는 반응하는 던전 크롤러 게임과 같은 불량배를 구현하려고합니다. 구성 요소가 마운트되기 전에지도를 렌더링 한 다음 나중에 levelRender() 함수를 사용하여 레벨을 다시 렌더링합니다. 하지만 내 상태는 componentWillMount() function.Debugging에 의해 설정된 원래 값으로 되돌아갑니다. 상태는 levelRender() 함수에 의해 chaged되고 있지만 결국에는 원래 상태로 돌아갑니다. 내 코드는 조금 긴 알아요,하지만 문제는 내가 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")); 
+0

componentWillMount에서 setState를 호출하면 안됩니다. 설명서 (https://reactjs.org/docs/react-component.html#componentwillmount)를 읽으십시오. 제 생각에 당신은 구성 요소가 기대하지 않는 시점에 상태 변이를 생성하려고합니다. –

+0

그래, 맞아, 내 대답을 해결 허용 대답, 난 componentDidMount()와 코드를 업데이 트했는데 호출되지 않습니다, 내가 리팩토링 코드를 맞춰 야지. –

답변

1

당신은 levelRender의 상태를 설정하고 이전 상태와 동일하게 덮어 쓰는 것입니다.

온라인으로 452에서 this.leverRender이 호출되며 실제로 새 게임 상태가 설정됩니다 (원하는 경우). 나중에, 485 행에서, 상태는 원하지 않는 출력을 담당하는 이전 값을 가진 변수 맵으로 겹쳐 쓰여지고 있습니다. 이것은 상태를 한 번만 설정하거나지도를 업데이트 한 값으로 두 번 설정하여 해결해야합니다.

+0

어리석은 나를 어떻게!, 그것을 지적 주셔서 감사합니다 –

관련 문제