2017-12-27 5 views
0

Ich versuche ein Rogue wie Dungeon Crawler Spiel in reagieren zu implementieren, rendere ich die Karte vor der Komponente einmal montiert und ich render später das Level mit LevelRender() -Funktion, aber mein Zustand kehrt zu seinem ursprünglichen Wert zurück, der durch die Funktion componentWillMount() gesetzt wird.Debugging zeigt, dass der Zustand durch die Funktion levelRender() verändert wird, aber am Ende kehrt er in den ursprünglichen Zustand zurück, was meiner Meinung nach nicht passieren sollte Ich weiß, dass mein Code ein bisschen lang ist, aber ich vermute, dass das Problem darin liegt, wie ich componentWillMount() und levelRender() aufrufen kann.state in react ist zurück auf den ursprünglichen Wert

In dem Spiel, braune Box ist das Portal, das den levelRender auslösen sollte, wenn es von Spieler, der rote Box ist, überfahren wird.

hier ist Link zu meinen codepen, mit den Pfeiltasten zu bewegen :)

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

Sie sollten setState nicht über componentWillMount aufrufen. Lesen Sie die Dokumentation (https://reactjs.org/docs/react-component.html#componentwillmount). Ich denke, Sie versuchen, zu einem Zeitpunkt, an dem die Komponenten das nicht erwarten, Zustandsänderungen zu generieren. –

+0

yeah, Sie haben Recht, akzeptierte Antwort löste mein Problem, ich versuchte Code mit componentDidMount() zu aktualisieren, aber es wird nicht aufgerufen, rate ich muss Refactor code.T –

Antwort

1

Sie den Zustandes in levelRender Einstellung und das gleiche mit dem vorherigen Zustand zu überschreiben.

In Zeile 452 wird this.leverRender aufgerufen, wodurch der neue Spielstatus tatsächlich festgelegt wird (gewünscht). Später wird in Zeile 485 der Zustand mit der Variablenkarte überschrieben, die die alten Werte hat, die für die unerwünschte Ausgabe verantwortlich sind. Dies muss gelöst werden, indem der Status nur einmal oder zweimal eingestellt wird, jedoch mit aktualisierten Map-Werten.

+0

wie dumm von mir!, Danke für die darauf hingewiesen –

Verwandte Themen