我正在尝试实施一个像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"));
答案 0 :(得分:1)
您正在levelRender中设置状态,并使用之前的状态覆盖相同的状态。
在第452行,正在调用this.leverRender
,这实际上设置了新游戏状态(所需)。之后,在485行,状态被变量映射覆盖,变量映射具有旧值,这是造成不希望的输出的原因。这必须通过仅设置一次状态,或者设置两次但使用更新的map值来解决。