views:

228

answers:

3

Hi, I'm starting to program a javascript tower defense; so far i have the movement of the minions over a trajectory. But I have a very big trouble, the game suddenly freezes for a couple of seconds. I'm guessing that is the garbage collector doing its job, any ideas on how i can solve this will be very good since i plan on adding a lot more of elements to the game and i don't want to keep coding till i get this flowing perfectly!

The code so far is pretty simple; you can check it out here

Here's the code:

<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>
A: 

Its not the garbage collector doing the job but in your code when you try to set the top and left positions, at a particuar time the value that you try to set in not a number. So the code breaks....

I think this occurs when the moving div crosses the top of the container with red background.

rahul
It hapens before they exit the background.I was thinking more of the decimal points in the left and right declaration; let me check it out
DFectuoso
The game is very nice....
rahul
Also check this in IE7. It generates a script error.
rahul
Thanks!!! I tried ceiling the result to a interget; didnt fix it =/
DFectuoso
Is the monster allowed to move beyond the container margins???
rahul
I think at a particuar point mostro.point_to_reach attains the value 11 and when it tries to look into the array for 11 th position the code breaks.[since arrays length is 10]
rahul
+1  A: 

Yes, thats right: the delay is because when there are too many monsters, there are too many position updates that need to be done. This causes the "redraw" delay..

I see that there is a DOM element for each monster(as should be the case). But, you are updating their positions one by one.

Tips to reduce this lag:

Firstly, it would be a better stategy to update their positions en masse:

<div id='monster-container'>
   <div id='monstser-1'></div>
   <div id='monstser-2'></div>
   <div id='monstser-3'></div>
</div>

So update the position of '#monster-container' when the monsters move. This way redraw time will definitely be minimized. What I say is from a primitive understanding of your game. You may need to modify this approach depending upon the path of the monsters. My approach will work directly only if the monsters only move in a straight line.

  • Secondly, if you are using img's for the monsters, consider using div's, and set the images as backgrounds of the div. This has given faster redraw performance in many of my pet games.

  • Thirdly, if you are using individual images for the monsters, consider using a composite image and CSS spriting.

Wish you luck with your game! Cheers!!

jrh

Here Be Wolves
Yea; but i need to move them one by one to make the game the way i need it to be. Thanks for the other tips tho!
DFectuoso
that is easily done: move them with respect to their container div! I've actually faced these before... And if you really want to build an intensive game, use <canvas>. Really, moving divs and imgs about will only get you so for.
Here Be Wolves
Thats a good idea... hummm hummm
DFectuoso
If you're going to use <canvas>, check out Processing.js.
cdmckay
Regarding tower defence, take a look at http://ptdef.com/ you may find it interesting. Regarding <canvas>, know that IE does not support it yet (like that's gonna change).
Here Be Wolves
+1  A: 

Yes, that's definitely a garbage collector. I am developing a JavaScript game myself, and I spent last few days trying to get rid of this problem. So far I can say that it's impossible.

However, I would like to note that different browsers have different garbage collectors, and for example, in Safari 4, your example runs perfectly smooth.

And here is interesting link on this topic: Reducing freezing with Object Pooling

Honestly, I think, that technique described in that article is not very helpful, because even in your example, that doesn't have any variables needed to be cleared, freezing is really noticeable.

Also I've rewritten your example, to test if global variables ruined performance. You can see the difference yourself

valums
Not selecting your answer as correct because it doesn't solve the problem, but you rock! man!, great answer, good content, understanding of the problem and definitely useful!!!
DFectuoso