Reputation: 107
I'am trying to implement a rogue like dungeon crawler game in react,I render the map before component mounts once and i later re-render the level using levelRender() function,but my state is returning back to its orginal value which is set by componentWillMount() function.Debugging shows that state is being chaged by levelRender() function but at end it returns to original state,which i think shouldn't be happening.I know my code is bit long but i guess problem lies with way i call componentWillMount() and levelRender() function.
In the game,brown box is the portal which should trigger the levelRender,when it is run over by player which is red box.
here is link to my codepen,use arrow keys to move around :)
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"));
Upvotes: 0
Views: 178
Reputation: 164
You are setting the state in levelRender and overwriting the same with the previous state.
On line 452, this.leverRender
is being invoked, which actually sets the new game state (desired). Later, on line 485, state is being overwritten with the variable map which has got the old values, which is responsible for the undesired output. This has to be resolved by setting the state only once, or setting it twice but with updated values of map.
Upvotes: 1