我开始编写一个javascript塔防;到目前为止,我的仆从在轨道上运动。但是我遇到了很大的麻烦,游戏突然冻结了几秒钟。我猜这是垃圾收集器正在做的工作,任何关于如何解决这个问题的想法都会非常好,因为我计划在游戏中添加更多元素,我不想继续编码直到我得到这完美流淌!
到目前为止,代码非常简单;你可以查看here
以下是代码:
<html>
<head>
<style>
#game{
background:red;
width:500px;
height:500px;
position:relative;
}
.mostro {
background:black;
width:15px;
height:15px;
position:absolute;
}
</style>
</head>
<body>
<div id="game">
<script type="text/javascript">
waypoint_x = [40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420];
waypoint_y = [140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20];
delay = 25;
new_monster = 0;
monsters_placed = 0;
monsters = [];
var d = new Date();
dist_x = 0;
dist_y = 0;
angle = 0;
mostro="";
total_monsters = 5;
function runGame() {
if (monsters_placed<total_monsters) {
new_monster++;
}
if (new_monster == delay) {
new_monster = 0;
document.getElementById("game").innerHTML = document.getElementById("game").innerHTML + '<div class="mostro" id="mostro-'+monsters_placed+'"></div>';
monsters_placed++;
}
for (i=0;i<monsters_placed;i=i+1) {
mostro = monsters[i];
dist_x = waypoint_x[mostro.point_to_reach] - mostro._x;
dist_y = waypoint_y[mostro.point_to_reach] - mostro._y;
if ((Math.abs(dist_x) + Math.abs(dist_y)) < 1) {
monsters[i].point_to_reach++;
}
angle = Math.atan2(dist_y, dist_x);
mostro._x = mostro._x + mostro.speed * Math.cos(angle);
mostro._y = mostro._y + mostro.speed * Math.sin(angle);
monsters[i]._rotation = angle/Math.PI*180-90
document.getElementById("mostro-"+i).style.left = Math.ceil(mostro._x) + "px";
document.getElementById("mostro-"+i).style.top = Math.ceil(mostro._y) + "px";
}
}
function setUpGame(){
for(i=0;i<=total_monsters;i++){
monsters[i] = new Object();
monsters[i].point_to_reach = 0;
monsters[i].speed = 1;
monsters[i]._x = 0;
monsters[i]._y = 0;
}
}
setUpGame();
setInterval(runGame,10);
</script>
</body>
</html>
答案 0 :(得分:2)
当您尝试设置顶部和左侧位置时,它不是垃圾收集器,而是在您的代码中,在特定时间,您尝试设置的值不是数字。所以代码中断......
我认为当移动的div穿过红色背景的容器顶部时会发生这种情况。
答案 1 :(得分:2)
是的,没错:延迟是因为当怪物太多时,需要完成太多的位置更新。这导致“重绘”延迟..
我看到每个怪物都有一个DOM元素(应该是这样)。但是,你正逐一更新他们的位置。
减少这种滞后的提示:
首先,整体更新他们的立场是一个更好的策略:
<div id='monster-container'>
<div id='monstser-1'></div>
<div id='monstser-2'></div>
<div id='monstser-3'></div>
</div>
当怪物移动时,更新'#monster-container'的位置。这样重绘时间肯定会最小化。我所说的是对游戏的原始理解。您可能需要根据怪物的路径修改此方法。只有当怪物只是直线移动时,我的方法才会直接起作用。
其次,如果您使用img's作为怪物,请考虑使用div,并将图像设置为div的背景。这在我的许多宠物游戏中提供了更快的重绘性能。
第三,如果您为怪物使用单独的图像,请考虑使用合成图像和CSS精灵。
祝你的游戏运气好!干杯!!
JRH
答案 2 :(得分:1)
是的,那肯定是垃圾收集器。我自己开发了一个JavaScript游戏,我花了几天时间试图摆脱这个问题。到目前为止,我可以说这是不可能的。
但是,我想注意不同的浏览器有不同的垃圾收集器,例如,在Safari 4中,您的示例运行非常流畅。
以下是关于此主题的有趣链接:Reducing freezing with Object Pooling
老实说,我认为,那篇文章中描述的技术并不是很有用,因为即使在你的例子中,没有任何变量需要被清除,冻结也是显而易见的。
此外,我已经重写了您的示例,以测试全局变量是否会破坏性能。 You can see the difference yourself