We are building a interactive tile-based (32x32 px) (game) map where the user can move around. However we experience lag (some sort of a delay on the movement) and we need to work around this problem. The "hack/lag" also happen on a local server so it's not because of the traffic yet. Any suggestions how we can make the rendering of the map and performance of the map faster?
DISCLAIMER: The code is fast-written, we are beware of the security issues, please do not point them out
map.php
<?php
session_start();
$_SESSION['angle'] = 'up';
$conn = mysql_connect('localhost', 'root', '') or die(mysql_error());
mysql_select_db('hol', $conn) or die(mysql_error());
$query = mysql_query("SELECT x, y FROM hero WHERE id = 1");
$result = mysql_fetch_assoc($query);
$startX = $result['x'];
$startY = $result['y'];
$fieldHeight = 10;
$fieldWidth = 10;
//x = 0 = 4
//y = 0 = 4
$sql = "SELECT id, x, y, terrain FROM map WHERE x BETWEEN ".($startX-$fieldWidth)." AND ".($startX+$fieldWidth). " AND y BETWEEN ".($startY-$fieldWidth)." AND ".($startY+$fieldHeight);
$result = mysql_query($sql);
$map = array();
while($row = mysql_fetch_assoc($result)) {
$map[$row['x']][$row['y']] = array('terrain' => $row['terrain']);
}
ob_start();
echo '<table border=\'0\' cellpadding=\'0\' cellspacing=\'0\'>';
for ($y=$startY-$fieldHeight;$y<$startY+$fieldHeight;$y++) {
echo '<tr>';
for ($x=$startX-$fieldWidth;$x<$startX+$fieldWidth;$x++) {
if ($x == $startX && $y == $startY) {
echo '<td style="width:32px; height:32px; background-image:url(\'tiles/' . (isset($map[$x][$y]['terrain']) ? $map[$x][$y]['terrain'] : 'water') . '\');"><img src="char/medic_' . $_SESSION['angle'] . '.png" alt="" /></td>';
} else {
//echo '(' . $x . ',' . $y . ')';
echo '<td style="width:32px; height:32px; background-image:url(\'tiles/' . (isset($map[$x][$y]['terrain']) ? $map[$x][$y]['terrain'] : 'water') . '\');"></td>';
}
}
echo '</tr>';
}
echo '</table>';
$content = ob_get_contents();
ob_end_clean();
?>
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<meta charset="utf-8">
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(document).keyup(function(e){
if (e.keyCode == 37) {
move("West");
return false;
}
if (e.keyCode == 38) {
move("North");
return false;
}
if (e.keyCode == 39) {
move("East");
return false;
}
if (e.keyCode == 40) {
move("South");
return false;
}
});
$(".direction").click(function() {
move($(this).text());
});
function move(newDirection)
{
var direction = newDirection;
$.ajax({
type: "POST",
url: "ajax/map.php",
data: { direction: direction },
success: function(data) {
$('#content').html(data);
}
});
}
/*
$("#content").click(function() {
var x = 3;
var y = 3;
$.ajax({
type: "POST",
url: "ajax.php",
data: { x: x, y: y },
success: function(data) {
$('#content').html(data);
}
});
});
*/
});
</script>
<style type="text/css">
td {margin: 0; border: none; padding: 0;}
img{
display:block;
margin:0;
}
.
</style>
</head>
<body>
<div id="content"><?php echo $content; ?></div>
<div class="result"></div>
<button class="direction">South</button>
<button class="direction">North</button>
<button class="direction">West</button>
<button class="direction">East</button>
</body>
</html>
ajax/map.php
<?php
session_start();
$conn = mysql_connect('localhost', 'root', '') or die(mysql_error());
mysql_select_db('hol', $conn) or die(mysql_error());
//Get Player's current position
$query = mysql_query("SELECT x, y FROM hero WHERE id = 1");
$result = mysql_fetch_array($query);
$current_x = $result['x'];
$current_y = $result['y'];
switch ($_POST['direction']) {
case 'North':
if ($current_y - 1 < 0) {
echo 'Invalid path';
}
//Next tile
$x = $current_x;
$y = $current_y - 1;
$_SESSION['angle'] = 'up';
break;
case 'South':
if ($current_y + 1 > 500) {
echo 'Invalid path';
}
$x = $current_x;
$y = $current_y + 1;
$_SESSION['angle'] = 'down';
break;
case 'West':
$x = $current_x - 1;
$y = $current_y;
$_SESSION['angle'] = 'left';
break;
case 'East':
$x = $current_x + 1;
$y = $current_y;
$_SESSION['angle'] = 'right';
break;
}
$result = mysql_query("SELECT walkable FROM map WHERE x = $x AND y = $y");
$row = mysql_fetch_array($result);
//Is the next tile walkable?
if ($row['walkable'] == 1) {
//Update Player's position
mysql_query("UPDATE hero SET x=$x, y=$y WHERE id = 1");
$startX = $x;
$startY = $y;
} else {
$startX = $current_x;
$startY = $current_y;
}
$fieldHeight = 10;
$fieldWidth = 10;
//x = 0 = 4
//y = 0 = 4
$sql = "SELECT id, x, y, terrain FROM map WHERE x BETWEEN ".($startX-$fieldWidth)." AND ".($startX+$fieldWidth). " AND y BETWEEN ".($startY-$fieldWidth)." AND ".($startY+$fieldHeight);
$result = mysql_query($sql);
$map = array();
while($row = mysql_fetch_assoc($result)) {
$map[$row['x']][$row['y']] = array('terrain' => $row['terrain']);
}
ob_start();
echo '<table border=\'0\' cellpadding=\'0\' cellspacing=\'0\'>';
for ($y=$startY-$fieldHeight;$y<$startY+$fieldHeight;$y++) {
echo '<tr>';
for ($x=$startX-$fieldWidth;$x<$startX+$fieldWidth;$x++) {
if ($x == $startX && $y == $startY) {
echo '<td style="width:32px; height:32px; background-image:url(\'tiles/' . (isset($map[$x][$y]['terrain']) ? $map[$x][$y]['terrain'] : 'water') . '\');"><img src="char/medic_' . $_SESSION['angle'] . '.png" alt="" /></td>';
} else {
//echo '(' . $x . ',' . $y . ')';
echo '<td style="width:32px; height:32px; background-image:url(\'tiles/' . (isset($map[$x][$y]['terrain']) ? $map[$x][$y]['terrain'] : 'water') . '\');"></td>';
}
}
echo '</tr>';
}
echo '</table>';
$content = ob_get_contents();
ob_end_clean();
echo $content;
ob_start()
. I don't use it myself, mostly because I do not like the way it lets you have HTML in your PHP. But just the way it works makes me think it adds a lot of overhead. – mseancole Jun 13 '12 at 17:01