优化阵列更新和性能javascript

时间:2017-06-26 11:38:02

标签: javascript performance oop

我试图制作一款RPG游戏。但我认为应该进行大量的优化。性能最大的问题之一。我使用for循环更新数组以设置新块,但它需要太长时间。我认为我也应该使用OOP来获得更好的性能,但它应该如何呢?

希望你能帮助我,对不起我的英语:)

使用Javascript:

var keyCode = {};
var player = document.getElementsByClassName("player")[0];
var div = document.getElementsByTagName("div")[0];
var iGrass = document.querySelectorAll(".interface > .grass")[0];
var iWater = document.querySelectorAll(".interface > .water")[0];
var iWall = document.querySelectorAll(".interface > .wall")[0];
var setEle = iWall;
var xPos = player.offsetWidth;
var yPos = player.offsetWidth;
var speed = 20;
var currentxPos;
var currentyPos;
var field = [];
field[0] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
field[1] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[2] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[3] = [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[4] = [1, 0, 0, 0, 0, "g", "g", 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[5] = [1, 0, 0, 0, "g", "g", "g", "g", 0, 0, 0, 0, 0, 0, 0, 1];
field[6] = [1, 0, 0, 0, "g", "g", "g", "g", 0, 0, 0, 0, 0, 0, 0, 1];
field[7] = [1, 0, 0, 0, 0, "g", "g", 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[8] = [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1];
field[9] = [1, 0, 0, 0, 0, 0, 0, 0, "w", "w", "w", 1, 0, 0, 0, 1];
field[10] = [1, 0, 0, 0, 0, 0, 0, 0, "w", "w", "w", 1, 0, 0, 0, 1];
field[11] = [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1];
field[12] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[13] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[14] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[15] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
field[16] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

function setStage() {
  for (y = 0; y < field.length; y++) {
    for (x = 0; x < field[y].length; x++) {
      if (field[y][x] == 1) {
        div.innerHTML = div.innerHTML + "<span class='wall'></span>";
      } else if (field[y][x] == "w") {
        div.innerHTML = div.innerHTML + "<span class='water'></span>";
      } else if (field[y][x] == "g") {
        div.innerHTML = div.innerHTML + "<span class='grass'></span>";
      } else {
        div.innerHTML = div.innerHTML + "<span></span>";
      }
    }
  }

  for (var i = 0; i < document.querySelectorAll('span').length; i++) {
    document.querySelectorAll("span")[i].style.width = player.offsetWidth + "px";
    document.querySelectorAll("span")[i].style.height = player.offsetWidth + "px";
  }
}
setStage();
div.style.width = field[0].length * player.offsetWidth + "px";

document.addEventListener("keydown", function(e) {
  keyCode[e.which || e.keyCode] = true;
  e.preventDefault();
});
document.addEventListener("keyup", function(e) {
  keyCode[e.which || e.keyCode] = false;
});

function playerMovement() {
  currentxPos = parseInt(xPos / player.offsetWidth);
  currentyPos = parseInt(yPos / player.offsetWidth);
  if (field[currentyPos][currentxPos] == "w") {
    speed = 1;
    player.style.transition = "0.4s all";
  } else {
    speed = 5;
    player.style.transition = "0.2s all";
  }
  /*Left*/
  if (keyCode[65] && xPos > 0) {
    if (field[currentyPos][currentxPos - 1] != 1) {
      xPos -= speed;
    } else {
      xPos = currentxPos * player.offsetWidth;
    }
  }
  /*Right*/
  if (keyCode[68] && xPos < div.offsetWidth - player.offsetWidth) {
    if (field[currentyPos][currentxPos + 1] != 1) {
      xPos += speed;
    } else {
      xPos = currentxPos * player.offsetWidth;
    }
  }
  /*Bottom*/
  if (keyCode[83]) {
    if (field[currentyPos + 1][currentxPos] != 1) {
      yPos += speed;
    } else {
      yPos = currentyPos * player.offsetWidth;
    }
  }
  /*Top*/
  if (keyCode[87] && yPos > 1) {
    if (field[currentyPos - 1][currentxPos] != 1) {
      yPos -= speed;
    } else {
      yPos = currentyPos * player.offsetWidth;
    }
  }
  /*Space*/
  if (keyCode[32]) {
    player.style.background = "#f00";
    if (field[currentyPos][currentxPos] == "g") {
      field[currentyPos][currentxPos] = 0;
      div.innerHTML = "";
      setStage();
    }
  } else {
    player.style.background = "#66f";
  }
  player.style.left = (currentxPos * player.offsetWidth) + "px";
  player.style.top = (currentyPos * player.offsetWidth) + "px";
}
iWall.addEventListener("click", function() {
  setEle = iWall;
});
iGrass.addEventListener("click", function() {
  setEle = iGrass;
});
iWater.addEventListener("click", function() {
  setEle = iWater;
});
div.addEventListener("click", function(e) {

  var setXpos = parseInt(e.x / player.offsetWidth);
  var setYpos = parseInt(e.y / player.offsetWidth);
  if (setEle == iWall) {
    field[setYpos][setXpos] = 1;
  } else if (setEle == iGrass) {
    field[setYpos][setXpos] = "g";
  } else if (setEle == iWater) {
    field[setYpos][setXpos] = "w";
  } else {
    field[setYpos][setXpos] = 0;
  }
  div.innerHTML = "";
  setStage();
});
setInterval(function() {
  playerMovement();
}, 10);

HTML:

<div class="stage"></div>
<div class="player"></div>
<div class="interface">
  <span class="grass"></span>
  <span class="water"></span>
  <span class="wall"></span>
</div>

CSS:

* {box-sizing: border-box;}
body {margin: 0;}

.player {
  border: 1px solid #66f;
  width: 20px;
  height: 20px;
  background: #66f;
  position: absolute;
  transition: 0.1s all linear;
  transform-origin: 50%;}
span {
  border: 1px solid #ddd;
  display: block;
  float: left;}
.wall {background: #e86;}
.water {background: #6af;}
.grass {background: #aea;}
.interface {
  overflow: hidden;
  padding: 10px;
  border: 1px solid #ddd;}

* DEMO: https://jsfiddle.net/Rakowu/nskzga7f/

1 个答案:

答案 0 :(得分:0)

为什么不尝试仅替换所选块而不是解析播放器DIV的全部内容。只需将ID添加到

中即可:

div.innerHTML = div.innerHTML + "<span class='wall' id='cell-"+y+"-"+x+"'></span>";
      } else if (field[y][x] == "w") {
        div.innerHTML = div.innerHTML + "<span class='water' id='cell-"+y+"-"+x+"'></span>";
      } else if (field[y][x] == "g") {
        div.innerHTML = div.innerHTML + "<span class='grass' id='cell-"+y+"-"+x+"'></span>";
      } else {
        div.innerHTML = div.innerHTML + "<span id='cell-"+y+"-"+x+"'></span>";

点击div:

div.addEventListener("click", function(e) {

   .....
   // div.innerHTML = "";
   // setStage();       
    document.getElementById(e.target.getAttribute('id')).replaceWith(setEle.cloneNode())
});

修复单击空格按钮

 if (keyCode[32]) {
    player.style.background = "#f00";
    if (field[currentyPos][currentxPos] == "g") {
      field[currentyPos][currentxPos] = 0;
      var selectedEl = document.getElementById('cell-'+currentyPos+'-'+currentxPos);
      var whiteSpace = document.createElement('span');
      whiteSpace.setAttribute('id', 'cell-' +currentyPos+'-'+currentxPos);
      whiteSpace.style.width = '20px';
      whiteSpace.style.height = '20px';
      selectedEl.replaceWith(whiteSpace);
    }

示例https://jsfiddle.net/nskzga7f/9/