Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Arboris on Tue 03/11/2009 20:51:04

Title: A simple AGS Shoot 'em up
Post by: Arboris on Tue 03/11/2009 20:51:04
Hey, I've been busy with a simple shooter concept as of late and have a question about the maximum number of objects one can use on a single screen. Well, I've run into this problem fairly quickly since every bullet I use on screen has to be it's own object. This including with the enemies I top the maximum objects very, very quickly.

Now, I could reuse the old objects and just designate a certain number row of objects to enemies, bullets and so on (e.g. object 10 to 19 for enemies, 20 to 29 for projectiles) and change their given appearance. But this is allot more fiddly and less readable then designate objects to a fixed object number.

So, is it possible to up the maximum? Or am I going to have it do the hard way  :'(

Title: Re: Maximum number of objects
Post by: Shane 'ProgZmax' Stevens on Tue 03/11/2009 21:49:40
You really shouldn't use objects for anything as numerous as bullets, Arboris.  The ideal solution, really, is to use the rawdraw functions and make your own bullet structure so you can create as many bullets as needed.  Another approach, and one I take in games that don't require 'a lot' of moving things, is to use characters instead of objects since you can have an infinite number of them and they're room independent.  Ultimately though, for a shooter where you typically have dozens of onscreen bullets at any given time you'll want to create and render and recycle the sprites yourself.
Title: Re: Maximum number of objects
Post by: Arboris on Wed 04/11/2009 11:53:28
I was using objects because of the wonderful pixel perfect collision detection plugin (which also works with characters, I know. but that was before I knew of the max of 40 objects per screen). I'll try using the 'DrawImage' function instead then, and handle the amount of projectiles myself. That'll make a good exercise to keep me occupied for a while.
Title: Re: Maximum number of objects
Post by: suicidal pencil on Fri 13/11/2009 01:23:52
You basically described the problems I ran into (and worked around) when I made this (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=39156.0).

I solved the problem by limiting the bullet to using one object only, and making sure that the object is not in use when the player is not firing again.


//Assume that Object 39 is reserved as a bullet
function shoot_bullet()
{
  if(object[39].Graphic == 0)
  {
    object[39].Graphic == 1; //sprite no.1 is the bullet (1x1 transparency)
  }
  else
  {
    //do nothing
  }
}


You can use objects to do what you need, just make sure that the script will ever hit the limit
Title: Re: Maximum number of objects
Post by: Ryan Timothy B on Fri 13/11/2009 04:47:55
Quote from: ProgZmax on Tue 03/11/2009 21:49:40
[..]use characters instead of objects since you can have an infinite number of them and they're room independent.[..]
There is also a 40 character limit per room.

But to get more than that, you'd have to use drawingsurfaces.  And for an arcade game, you're best off with using drawingsurfaces anyway.  That way you can go from room to room if you keep your scripts in globalscripts, without need of creating objects for each room or changing all the characters rooms.

Edit:  I've actually drawn 400 'characters' at once, and with each one animating, using drawing functions.  It barely shows any sign of lag (just don't animate every game loop (obviously), since a game loop is very quick, you'd have to have an int used as an animating timer for each 'character').
Title: Re: Maximum number of objects
Post by: Arboris on Fri 13/11/2009 11:54:13
Ah, sorry, but I've tackled this one a little while back.  I did tell and thank ProgZmax for mentioning you can simply draw sprites on the background, but never here. Still, thanks for the input.

As I said: I'm drawing the bullets on the background now, and keep their respective x, y, and angle in an array and have one dedicated function which checks the array if something falls between the 320x240 dimensions and then draws it on the background.  And it also checks if you're pressing the left mouse button. This will put 'new' projectile coordinates in the array where ever the y coordinate has exceeded the 0 limit (top of the screen) and then 'breaks'out of this while loop, because it successfully registered in the array. With this I can create a ridiculous amount of bullets on screen without AGS slowing down it seems.

function MachineGunLaser(){//drawing it on the background instead of using objects now. int laserPosition[200]; is a global array.
 int x=0;
 if(Mouse.IsButtonDown(eMouseLeft)==1){
   PlaySound(1); //pewpew sound
   while(x<=199){//the array has I'm checking has 200 places. it was a random number without thought tbh.
     if(laserPosition[x+1]<0){//checking if the Y position of any other projectile is out of bounds
       laserPosition[x]=mouse.x+8+Random(18);//to get the gatling effect I put in a bit of random X position
       laserPosition[x+1]=185;//his Y start position
       laserPosition[x+2]=Random(2)-1;//random angle at which the bullet will fly
       x=199; //breakfunction
     }
     x=x+3;//every bullet takes up 3 places in the array. X, Y and Angle.
   }
 }
  x=0;
 background=Room.GetDrawingSurfaceForBackground(); //drawing all the bullets that are stored in the array and do not fall out of bounds
 while(x<=199){//again, checking the entire array
   if(laserPosition[x+1]>=0){//only draw the bullets that are on screen
     background.DrawImage(laserPosition[x], laserPosition[x+1], 64);
     laserPosition[x+1] = laserPosition[x+1]-5;//speed it flies upwards
     laserPosition[x] = laserPosition[x]+laserPosition[x+2]; //angle
   }
   x=x+3;
 }
 background.Release();
}


Here's the result. (http://arboris.hell-on-earth.net/stuff/Coell%20Decka%20DAKKADAKKADAKKA.rar) This is an old version btw, and hasn't implemented the angled shots (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=39293.0) yet.
Title: Re: Maximum number of objects
Post by: Ryan Timothy B on Fri 13/11/2009 18:13:22
I quickly scanned through your code and saw this comment:
x=x+3;//every bullet takes up 3 places in the array. X, Y and Angle.

To make things easier on yourself also with less chances of programming errors, would be to use a struct and array.
Like this:

struct sBullets {
  int x;
  int y;
  int a;  //angle
};
sBullets bullet[100];


Then you can call the variables like so:

bullet[i].x = mouse.x+8+Random(18);
bullet[i].y = 185;
bullet[i].a = Random(2)-1;

Then when you run a while statement you don't have to add 3, or whatever amount, each time.  Just one.
Title: Re: Maximum number of objects
Post by: Scarab on Fri 13/11/2009 18:31:19
Does your game shoot bullets only or can you shoot a lazer like in your sig and in RaidenX (http://www.freeworldgroup.com/onlinegames/gameindex/raiden.htm)?

I tried to download your demo/game, but my screen resolution could not handle the resolution  :-[

peace
scar
Title: Re: Maximum number of objects
Post by: Arboris on Fri 13/11/2009 18:43:54
The concept demo link in my signature has upgradable weapons, and that laser is your temporary powerup weapon. Try running it in window, you can select it from the setup that comes with it.
Title: Re: Maximum number of objects
Post by: Shane 'ProgZmax' Stevens on Sat 14/11/2009 01:41:13
It reminds me very much of an old snes shooter!  Are you going to add enemies or is it just going to be like it is now, with an every increasing number of asteroids coming at you?  Some enemies might spice it up a bit, as well as the ability to move vertically (like up to about half the screen would be good for avoiding projectiles). 
Title: Re: Maximum number of objects
Post by: Arboris on Sat 14/11/2009 11:15:15
I was planning on making it with enemy waves. At the moment I can send enemies forward in sequence rather then the randomness of the asteroids demo. The only problem I have with it is that the function that will handle these events will become a giant 'else if' statement.

function eventHandler(){//this is where every enemy encounter will come
  if(gameTimer==50){
    Zigzag(100, 40.0, 60.0, 2, 26, 1, -1, 10);
  }else if(gameTimer==250){
    Zigzag(40, 50.0, 25.0, 2, 26, 3, -1, 80);
    Zigzag(100, 8.0, 15.0, 2, 26, 2, -1, 50);
    Zigzag(200, 5.0, 5.0, 2, 26, 1, -1, 70);
  }else if(gameTimer==400){
    Zigzag(0, 200.0, 140.0, 1, 26, 1, -1, 10);
  }else if(gameTimer==450){
    Zigzag(220, 0.1, 0.1, 2, 2000, 1, -1, 80);
    Zigzag(80, 0.1, 0.1, 2, 2000, 1, -1, 80);
  }else if(gameTimer==460){
    Zigzag(210, 0.1, 0.1, 2, 2000, 1, -1, 80);
    Zigzag(90, 0.1, 0.1, 2, 2000, 1, -1, 80);
  }else if(gameTimer==470){
    Zigzag(200, 0.1, 0.1, 2, 2000, 1, -1, 80);
    Zigzag(100, 0.1, 0.1, 2, 2000, 1, -1, 80);
  }else if(gameTimer==480){
    Zigzag(190, 0.1, 0.1, 2, 2000, 1, -1, 80);
    Zigzag(110, 0.1, 0.1, 2, 2000, 1, -1, 80);
  }else if(gameTimer==650){
    gameTimer=0;
  }
  gameTimer++;
}


and this is just for a few encounters. So as you can see, with a medium sized level this thing would become ginormous
Title: Re: Maximum number of objects
Post by: Helme on Sat 14/11/2009 11:18:24
Just some feedback for your demo: I would prefer to use the arrow-keys instead of the mouse.
Title: Re: Maximum number of objects
Post by: Arboris on Sat 14/11/2009 11:36:37
I'll be changing that soon. It was never intended to do all this, and I kinda got carried away with it (Dodging the asteroids was the main idea, without even the ability to fire). And since what I'm working on now requires you to move up and down as well, I'll just implement a keyboard control scheme.  But I'll be working on a redo of the spaceship sprite first.
Title: Re: Maximum number of objects
Post by: Victor6 on Sat 14/11/2009 20:09:17
Quote from: Arboris on Sat 14/11/2009 11:15:15
I was planning on making it with enemy waves. At the moment I can send enemies forward in sequence rather then the randomness of the asteroids demo. The only problem I have with it is that the function that will handle these events will become a giant 'else if' statement.

I wrote a flash shooter once and encountered a similar coding issue. I got around it by keeping track of the current 'wave' of enemies, and storing the spawn data in a 2d array.

That way you only need to check the timer against the timer value for the next wave each time.

I believe AGS doesn't support 2d arrays, but you probably can use multiple arrays to simulate the same effect.
Title: Re: Maximum number of objects
Post by: suicidal pencil on Sat 14/11/2009 23:12:48
Quote from: Victor6 on Sat 14/11/2009 20:09:17
I believe AGS doesn't support 2d arrays, but you probably can use multiple arrays to simulate the same effect.

you can cheat using struct
Quote from: Khris on Sat 24/10/2009 10:40:04
// header

struct str_x {
  int y[100];
};

// script

str_x x[100];

// now one can do:
  x[40].y[20] = 3;

Title: Re: Maximum number of objects
Post by: Arboris on Mon 16/11/2009 19:40:36
Well, I've been working on it a bit more, and I was afraid this would happen. It's pretty easy to get the game to crawling slowdown now. Of course at the moment you can spawn more then 40 bullets in one go, but even with half of that you'll notice a serious slowdown.

this is mainly because unlike enemy fire which only has to check hits vs your ship, every bullet you shoot has to be checked vs every visable object on screen. And I've done this with a loop within a loop approach.

test version 1.02 (http://arboris.hell-on-earth.net/stuff/Coell%20Decka%20Test%201.02.rar)

*EDIT*
Luckily the slowdown was caused by a simple oversight I made on when to calculate the hitboxes.
Test version 1.03 (http://arboris.hell-on-earth.net/stuff/Coell%20Decka%20Test%201.03.rar)
Title: Re: A simple AGS Shoot 'em up
Post by: Ryan Timothy B on Tue 17/11/2009 01:01:56
I noticed your enemy ships just Appear right on the top of the screen.  Why not make them appear above the edge of the screen and move down.  You can use drawimage even if the rectangle boundaries of that image is off the drawing surface (eg: y==-10).  
I've done it plenty of times without AGS giving any errors.  It must be calculated in the drawimage function within AGS.




Also one thing you're doing that seems a little backwards is how you determine which number the new bullet should spawn as.  Your code here:
while(x<=199){//the array has I'm checking has 200 places. it was a random number without thought tbh.

What I do to prevent having to run this while statement, is I have an integer of How many bullets are on the screen.  Whenever you want to add a bullet you just do this instead:


 if (Mouse.IsButtonDown(eMouseLeft)==1)
 {
   if (BulletCount<200) //checks to see if you aren't at max
   {
     PlaySound(1); //pewpew sound
     bullet[BulletCount].x = mouse.x+8+Random(18);  //to get the gatling effect I put in a bit of random X position
     bullet[BulletCount].y = 185;  //his Y start position
     bullet[BulletCount].a = Random(2)-1;  //random angle at which the bullet will fly
     BulletCount++;  //you add the number After you assign it to the Array. That way 1 will be 0 on the array.
   }
 }


Then to see if a Bullet needs to be removed you'd have to run a while loop in the rep_ex (also in this while loop you should also cross check if the bullet in question is touching an enemy ship, that way you aren't wasting a while loop):


int i;
while [i<BulletCount]
{
 if (bullet[i].y<0) //remove the bullet  OR  if this bullet has touched an enemy ship.
 {
   bullet[i].x=bullet[BulletCount].x;  //this replaces the current bullet with the Last bullet in the array.
   bullet[i].y=bullet[BulletCount].y;
   bullet[i].a=bullet[BulletCount].a;
   BulletCount--;
   i--; //so this number gets ran again
 }
 i++;
}


I wrote this all in here, so I hope there aren't any issues.
This is how I do it, just to prevent any unnecessary while loops, and to maximize cpu efficiency.
Title: Re: A simple AGS Shoot 'em up
Post by: Khris on Tue 17/11/2009 09:29:18
Great stuff!

Small suggestion: set mouse bounds & add esc = quit. I understand the game is in early alpha, but it makes testing a lot more convenient.
Title: Re: A simple AGS Shoot 'em up
Post by: Arboris on Tue 17/11/2009 12:05:10
Quote(also in this while loop you should also cross check if the bullet in question is touching an enemy ship, that way you aren't wasting a while loop)

Good idea. I'll move the hitdetection the moment it also actually draws. It'll safe some while loops. Altho it'll be less readable then one my current single hitdetection function. But I'm the only one looking at it anyway ;)

QuoteI noticed your enemy ships just Appear right on the top of the screen.

This is because of the 'odd' difference between object and DrawImage. for an object the Y coordinate is the bottom left corner, and for DrawImage it's the upper left corner. It's a minor tweak i still need to do ;)
Title: Re: A simple AGS Shoot 'em up
Post by: Radiant on Wed 18/11/2009 15:11:00
Quote from: Arboris on Tue 03/11/2009 20:51:04
Hey, I've been busy with a simple shooter concept as of late and have a question about the maximum number of objects one can use on a single screen. Well, I've run into this problem fairly quickly since every bullet I use on screen has to be it's own object.

I recommend rawdraws (http://crystalshard.net/index.php?g=14).
Title: Re: A simple AGS Shoot 'em up
Post by: abstauber on Fri 27/11/2009 09:19:38
Have you already switched over to raw drawing?

I'm using *cough* GUI buttons. But they work perfectly and I have the feeling, that moving buttons around is much faster than overlays.

Anyhow, I use one GUI for the Enemies + Player, one  GUI for enemy bullets and one  GUI for player bullets. Since you can have 30 elements per GUI and as much GUIs as you like, I think that's fair enough :)

Also you don't have to worry about z-order and animations.
Title: Re: A simple AGS Shoot 'em up
Post by: Arboris on Sat 28/11/2009 16:45:55
I've been using rawdraw (or DrawImage as it's known now) for a while now. As you can see in the test versions (not the demo linked in my sig) I've got the basics down now, and 'just' need to create a decent game with it now. Which means creating sprites, attack patterns etc.

the only thing i haven't tried yet is some sort of boss composed out of multiple objects. you can't have a shooter without some sort of boss fight ;)
Title: Re: A simple AGS Shoot 'em up
Post by: abstauber on Mon 30/11/2009 08:38:42
Quoteyou can't have a shooter without some sort of boss fight
Exactly :)
Bosses are just chunks of enemies so it should take you long to implement them. Speaking for myself, attack-patterns are a real pain...
Title: Re: A simple AGS Shoot 'em up
Post by: Arboris on Thu 03/12/2009 00:30:29
Did a bit of work again this night, trying to get some sort of boss fight. The boss wasn't really thought about, and I just made it on the fly.It was a 'right that works, now what should it do next?' process. You no longer use the mouse to move your ship, and you'll have to use the keyboard. Directional keys for the movement of your ship and Space to shoot.

Download Test version 1.04 (http://arboris.hell-on-earth.net/stuff/Coell%20Decka%20Test%201.04.rar)

A little disclaimer:
The sprites that compose the various boss parts are not mine (http://www.pixeljoint.com/pixelart/28896.htm). Neither is the music (that one comes from Streets of Rage)

Title: Re: A simple AGS Shoot 'em up
Post by: Ryan Timothy B on Thu 03/12/2009 02:47:00
Don't forget to add a WASD and a 8456 (keypad) control too.  Some keyboards (like my laptop, for example) can't use arrow keys in a certain combination with the space bar. (Like down+left and space. The arrow keys will be ignored and the ship will stop dead)

I played around 10 or so times and still can't beat the boss guy. :P  I either suck, or it's hard.
Title: Re: A simple AGS Shoot 'em up
Post by: abstauber on Thu 03/12/2009 07:40:02
Nice work. Although the boss is really tough, I had fun blasting him away :D

@Ryan:
Attack early and stay close, then it's quite easy.
Title: Re: A simple AGS Shoot 'em up
Post by: Arboris on Thu 03/12/2009 12:05:21
And here I was thinking it might be a bit too simple. You still have the unfair advantage of using the test gun, which spits out an enormous amount of bullets every cycle ;).

The keypad should work already, wasd is easily enough implemented.
Title: Re: A simple AGS Shoot 'em up
Post by: DoorKnobHandle on Thu 03/12/2009 12:52:23
I had no trouble beating the boss actually! :D Nice work!
Title: Re: A simple AGS Shoot 'em up
Post by: Ryan Timothy B on Thu 03/12/2009 17:40:19
See!  I just suck. :P

I actually beat him after a few more tries, but I definitely wouldn't say it's easy.  Perhaps it's mostly because my bullets are so freakin huge that they distract me from enemy fire.
Title: Re: A simple AGS Shoot 'em up
Post by: DoorKnobHandle on Thu 03/12/2009 17:49:57
You have to destroy the center guns first as they are dangerous. If you start shooting before the boss even appears, the first one can be broken before it fires one shot. Then get the second and after that it's a piece of cake. :D
Title: Re: A simple AGS Shoot 'em up
Post by: Arboris on Thu 03/12/2009 20:26:41
Your bullets aren't THAT huge, you just fire an ungodly amount of them. Which makes it look like a sea of blue  :=
Title: Re: A simple AGS Shoot 'em up
Post by: Kweepa on Tue 15/12/2009 03:46:45
This is pretty cool!
This and the shooter section of abstauber's latest game make me want to get back to the AGS conversion of Imagine's Arcadia I abandoned...