Note that there are some explanatory texts on larger screens.

plurals
  1. POhtml / jquery 2d tile based map: javascript too slow, alternatives?
    text
    copied!<p>I am working on a browser-based web game with a very large 2d, tile-based map. Unlike games like Tribal Wars, the terrain is not generated randomly from a seed or one large image file.</p> <p>What I currently do is have a hidden canvas element that contains a bmp map where each pixel represents a tile. A green pixel represents land, a blue pixel represents water, and a black pixel represents a region outside of the map.</p> <p>Currently my algorithm will take a certain rectangular segment of the bitmap in the canvas and then create a bunch of uniformly sized tiles that fit into a much larger div. Tiles are painted left to right, relying on relative positioning and float: left to arrange themselves properly. Each tile is 30px by 30px, which adds up to quite a few tiles on a 1080p monitor.</p> <p>In order to move the map around, the user presses an arrow key that moves the rectangular selection in the canvas, then painting it all back.</p> <p>Here is the straight code: </p> <pre><code>&lt;script&gt; $("#WorldMapCanvas").hide(); var canvas = document.getElementById('WorldMapCanvas'); var context = canvas.getContext('2d'); var imageObj = new Image(); imageObj.src = '../Images/MapTest3.bmp'; var tileSize = 30; var maxTilesOnX = $("#WorldMap").width() / tileSize; var maxTilesOnY = $("#WorldMap").height() / tileSize; var offsetX = 0; var offsetY = 0; function draw() { $("#WorldMap").html(""); // clear map div context.drawImage(imageObj, 0, 0); for (var y = 0 + offsetY; y &lt; maxTilesOnY + offsetY; y++) { for (var x = 0 + offsetX; x &lt; maxTilesOnX + offsetX; x++) { var pixel = context.getImageData(x, y, 1, 1); // alert("x: " + x + " y: " + y + " " + pixel.data[0] + "," + pixel.data[1] + "," + pixel.data[2]); if ((pixel.data[0] == 0) &amp;&amp; (pixel.data[1] == 255) &amp;&amp; (pixel.data[2] == 0)) { $("#WorldMap").append("&lt;div class = 'grass'&gt;&lt;/div&gt;"); } else if ((pixel.data[0] == 0) &amp;&amp; (pixel.data[1] == 0) &amp;&amp; (pixel.data[2] == 255)) { $("#WorldMap").append("&lt;div class = 'ocean'&gt;&lt;/div&gt;"); } else if ((pixel.data[0] == 0) &amp;&amp; (pixel.data[1] == 0) &amp;&amp; (pixel.data[2] == 0)) { $("#WorldMap").append("&lt;div class = 'null'&gt;&lt;/div&gt;"); } } } $(".grass").mouseenter(function () { $("#WorldMapMessage").html("grass"); }); $(".ocean").mouseenter(function () { $("#WorldMapMessage").html("ocean"); }); $(".null").mouseenter(function () { $("#WorldMapMessage").html("empty"); }); } imageObj.onload = draw(); // allows player to draw new portions of the map by using arrow keys clickhandler = document.addEventListener('keydown', function (event) { if (event.keyCode == 37) { offsetX -= 5; draw();} else if (event.keyCode == 38) { offsetY += 5; draw(); } // up else if (event.keyCode == 39) { offsetX += 5; draw(); } else if (event.keyCode == 40) { offsetY -= 5; draw(); } }); </code></pre> <p></p> <p>However, a single key press takes the browser about 2.5 seconds to process and paint all that data, and I have a fairly powerful processor which means it'll likely be painfully slow for the average user.</p> <p>How might I improve algorithm speed? Ideally I'd like scrolling to be realtime so the player can drag the map around, google maps style. I have a few ideas:</p> <ol> <li>Define left and top positions for each tile via jquery rather than loading them all in and relying on relative positioning to cause them to align.</li> <li>Merge the tiles together into a single image in a canvas. However, I do need to maintain the cursor-hover information so the player can query terrain info (and later on armies/cities that will be drawn on top after pulling that data from the server.)</li> <li>Preload the entire map. Not ideal since maps will be about 1 million square tiles...</li> <li>Look into using a Flash plugin, also not ideal since I'd like to minimize outside performance requirements.</li> </ol> <p>Do any of you have suggestions on how I might go about improving my algorithm or have suggestions on entire new ideas to consider?</p> <p>Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload