Moving multiple overlays at once [SOLVED with drawing onto the room background]

Started by .M.M., Sat 21/04/2012 10:43:29

Previous topic - Next topic

.M.M.

Hi, I've just finished my game (it's a top-down action RPG) and now, I'm trying to improve some things for the next game. One of the main issues is that it was possible to shoot only one bullet at a time, because the bullet was represented by a character. I tried to replace it by overlays. This is what I have:
Code: ags

function Shoot(this Character*, int targetx, int targety, float speed) { // speed is between 20.0 and 30.0
 if (bullet_count == 20) return; //maximum count of overlays
 while (bullet[i] != null && bullet[i].Valid && i < 20) i++;
 originx[i] = IntToFloat(this.x);
 originy[i] = IntToFloat(this.y);
 destinationx[i] = IntToFloat(targetx-this.x);
 destinationy[i] = IntToFloat(targety-this.y);
 float l = Maths.Sqrt(destinationx[i]*destinationx[i] + destinationy[i]*destinationy[i]);
 destinationx[i] = speed*destinationx[i]/l;
 destinationy[i] = speed*destinationy[i]/l;
 bullet[i] = Overlay.CreateGraphical(this.x, this.y, 0, true);
 bullet_count ++;
}

and for moving the bullets (in repeatedly_execute):
Code: ags

 if (bullet_count > 0) {
 if (i < 20) i++;
 else i = 0;
 if (bullet[i] == null) return;
  if (bullet[i].Valid) {
   originx[i] += destinationx[i];
   originy[i] += destinationy[i];
   bullet[i].X = FloatToInt(originx[i]);
   bullet[i].Y = FloatToInt(originy[i]);
   float r_width = IntToFloat(Room.Width);
   float r_height = IntToFloat(Room.Height); 
   if (originx[i] < 0.0 || originx[i] > r_width || originy[i] < 0.0 || originy[i] > r_height) {
    bullet[i].Remove();
    bullet_count --;
   }
  } 
 }

It's just a slightly changed code originally created by Khris (thank you one more time! :-) ) - I added mainly the indexes. There are these problems:
1) Every bullet is moved only once for a 20 frames, because of the indexes.  But I can't limit it to the bullet count - there might be only three bullets on the screen, but with indexes e.g. 1,5 and 14. The only workaround I have discovered is to set the game speed to a number around 800-850.
2) Even though it raises the maximal count of bullets from 5 in my first game to 20 (and I think that this number will drop down because of functions like Display, that use overlays, too), it's still limited. Is there a better way? Actually, I'm sure there is, but I just can't think of anything...

Khris

What you usually do is iterate through all bullets, check if they're "active" and if they are, move them. That way, their handling is independent and it doesn't matter how many bullets there are on the screen at any given time.

Not sure what you're doing at the start of your rep_ex part, but having to set the game speed to 800 definitely means your code is flawed.

I wouldn't use overlays but a transparent, non clickable, screen-sized GUI. Each frame, the bullets are drawn to a screen-sized DynamicSprite, which is then set as the GUI's BackgroundGraphic.

.M.M.

Yes, this sounds like the best way and now it works without problems. Just in case that any one will have the same problem and will read this: to make it work with scrolling rooms, save one dynamic sprite as player enters a room and then, override the actual background graphic with this sprite (it will make all the previous changes dissapear) and then draw all the bullets over it.

Khris

Why would you need to save or replace the background? Just .Clear() the DynamicSprite's DrawingSurface before drawing the bullets to it.

.M.M.

Because of scrolling rooms, where it's not possible to use the GUI. Command Clear() is good for the transparent GUI, but not for drawing onto the background.

Khris

Why is it not possible? Just subtract GetViewportX/Y() from the bullet's coordinates before drawing them.

.M.M.

It's not impossible, I thought it more like that it's easier to use (at least for me) because I don't have to worry about the viewports.

SMF spam blocked by CleanTalk