2017-06-26 4 views
0

私はRPGゲームを作成しようとしています。しかし、私はderはたくさんの最適化をすべきだと思います。最大の問題の1つは、パフォーマンスです。新しいブロックを設定するためにforループを使って配列を更新しますが、時間がかかりすぎます。私はまた、より良いパフォーマンスのためにOOPを使うべきだと思いますが、どうすればいいでしょうか?配列の更新とパフォーマンスのJavaScriptを最適化

は、あなたが私を助け、私の英語のため申し訳ありませんことを願って:)

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

OOPが良く保証するものではありませんスペース]ボタンをクリックするため

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

修正するだけ年代にidを追加パフォーマンス。 – evolutionxbox

+2

主な問題は、毎回グリッド全体を更新するため、htmlパーサーがビジー状態になることです。それはなぜ反応がとても有名になったのですか?だから、あなたはちょうど変更を聞くかもしれません... –

+0

はい、私はクリックして、文書の開始時に発砲するためにtryied。しかし、私はそれがまだパフォーマンスを消費することがわかります。どのように私はsteStageメソッドを最適化する必要がありますか? T.T – Rakowu

答えて

0

プレーヤーDIVのコンテンツ全体を解析するのではなく、選択したブロックのみを置き換えるのはなぜですか。 divの上

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>"; 

クリック:

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/

+0

ああ、それは巨大な違いです:Dほぼ完璧です。唯一の問題は、奇妙な方法でグリッド要素がクローンをスペースでクリックすることです。 (スペースは "草"を切るために使われます)。 – Rakowu

+0

そのようにすると、 'data-type =" white-space "のようなデータ属性を置き、' replaceWith'関数の前にその値をチェックし、必要な処理を行うことができます。ちょうど私がIDの –

+0

を追加したちょうど唯一の問題は、クリックでコールバックがあることですが、私はそれらを交換する必要があることを彼らに理解させる必要があります^^しかし、今私はそれをさらに取るための良い基盤を持っています: D – Rakowu

関連する問題