Archived

This topic is now archived and is closed to further replies.

jon723

Timing the spawning of weapons??

Recommended Posts

Hello, I''m trying to time when a new weapon is spawned in my game but the method I''m using isn''t displaying the weapon after the certain amount of seconds has passed. For testing purposes I''m using a time limit of 3, here is the source code:
  
void World::Render()
{
	Weapon *tempWeapon = new Weapon();
	Weapon *newWeapon;
	float time = 0.0;


	if((time = worldTime.GetElapsedTime(1)) == 3.0)
	{
		int randWeapon = 1 + (rand()%5);	// generate a weapon


		switch(randWeapon)
		{
		case 1:	tempWeapon->setWeapon(MEGA_BURST);
				tempWeapon->setDamage(3);
				tempWeapon->setShots(AMMO_MEGA_BURST);
	
			break;
		case 2: tempWeapon->setWeapon(LASER);
				tempWeapon->setDamage(8);
				tempWeapon->setShots(AMMO_LASER);

			break;
		case 3: tempWeapon->setWeapon(GRENADE);
				tempWeapon->setDamage(12);
				tempWeapon->setShots(AMMO_GRENADE);

			break;
		case 4: tempWeapon->setWeapon(ICE_SHOT);
				tempWeapon->setDamage(15);
				tempWeapon->setShots(AMMO_ICE_SHOT);

			break;
		case 5: tempWeapon->setWeapon(NUKE);
				tempWeapon->setDamage(20);
				tempWeapon->setShots(AMMO_NUKE);

			break;
		default: tempWeapon->setWeapon(BULLET);
				 tempWeapon->setDamage(2);
				 tempWeapon->setShots(AMMO_BULLET);

			break;
		}

		newWeapon = new Weapon(tempWeapon->position, tempWeapon->getWeapon(), tempWeapon->getDamage(), tempWeapon->getShots());
		this->numWeapons += 1;
		delete tempWeapon;
	
		glTranslatef(newWeapon->position.xpos, newWeapon->position.ypos, newWeapon->position.zpos);	
		newWeapon->Draw();
	}
}
  
I''m using real time to time the events here is the code to get the elapsed time.
  
float GetElapsedTime(unsigned long elapsedSec = 1)
	{
		static LARGE_INTEGER prevTime = starttime;
		LARGE_INTEGER currtime;

		QueryPerformanceCounter(&currtime);

		float seconds = ((float)currtime.QuadPart -(float)prevTime.QuadPart / 
						(float)ticksecond.QuadPart);

		prevTime = currtime;

		return seconds;
	}
  
How do I get to display a weapon every 3 seconds?? Jon

Share this post


Link to post
Share on other sites
I'd guess that as time is a float it might be returning 3.1 or 3.11 or whatever and never actually 3.

You could try a range, say 2.8 to 3.2.


Paul Cunningham

(PS - I'm assuming that your code works and without the time check a weapon does get created)



[edited by - PaulCunningham on May 28, 2003 2:47:06 PM]

Share this post


Link to post
Share on other sites
This line is almost certainly your problem:

if((time = worldTime.GetElapsedTime(1)) == 3.0)

Never do an == comparison on floats, for instead of 3.0 you''ll have 2.9999999999999999994 or 3.00000000000000001 and the compare will evaluate to false. You need to use >=, or round both values to the nearest int and them compare, or compare to a range (2.95 to 3.05), or similar.

Also, the elapsedSec parameter on your GetElapsedTime function doesn''t seemed to be used at all in the function. What is it supposed to do?

Share this post


Link to post
Share on other sites
Just a small point, that your code is leaking, if the if expression is false, then tempweapon is never deleted, so you should move the delete tempweapon to outside the if statement.

Share this post


Link to post
Share on other sites
Good point (didn''t see that). About the timer, I changed it test it the time is greater then the specified time. The whole purpose of this is to restrict the render of a new weapon during a certain time interval (you probably figured this out). Another leak I see is that after the time is checked its going to fail after the first time. How can I get this to work??

Share this post


Link to post
Share on other sites
I moved the time checking stuff outside of the function because it would be better (and makes more sense) to call the function after a certain time interval. But now I''m faced with the problem of checking if a certime has passed. Does anyone know how to do this with the High res timer??

Share this post


Link to post
Share on other sites
quote:
Original post by jamessharpe
Just a small point, that your code is leaking, if the if expression is false, then tempweapon is never deleted, so you should move the delete tempweapon to outside the if statement.


i wouldnt even call new without knowing if you actually need it. so i'd rather place that inside the if instead of creating and deleting the weapon a hundred times and only use it once.

but then.. i wouldnt even initialize it. drop the tmpweapon and call the newweapon constructor in each case, instead of assigning all but one value to a tmp weapon. or drop the newweapon and return the tmpweapon (which is in fact pretty much the same).
all this seems kind of redundant and not necessary.

about the time: whereever you check for the elapsed time, place a static float TimeUntilSpawn (inside it representing the time since a weapon spawned (or whatever event triggers those 3 seconds). as youre most likely testing that every frame it should like this:

static float TimeUnitlSpawn=0; //spawn at first time
if (TimeUntilSpawn -= ElapsedTime <= 0)
{
SpawnWeapon();
TimeUntilSpawn=WEAPON_SPAWN_DELAY;
}

ElapsedTime would be the time since your last frame, that i would calculate once at the beginning of the game loop and pass it to all functions that are time dependent (physics, ai, whatever).

while im at it:


void SpawnWeapon() {
int randWeapon = 1 + (rand()%5);
switch(randWeapon) {
case 1:
VecWeapons.push_back(new Weapon(BURST, 3, AMMO_BURST));
break;
case 2:
VecWeapons.push_back(new Weapon(LASER, 8, AMMO_LASER));
break;
...
}
}



VecWeapons is considered a vector/array/list or whatever you use to store your weapons in (or a more general container for gameobjects). instead of numWeapons you have VecWeapons.size().

also youre (in your code) obviously drawing the weapon only once when it is created, dont store its pointer anywhere and therefore have another leak (and dont be surprised if your weapon doesnt appear anywhere). your render function shouldnt contain anything but rendering, in this case (i'll use the vector array like instead of stl like):

      
void Render() {
int numWeaps=VecWeapons.size(); //dont know how clever your compiler is, but to be sure it wont call the function every iteration i store it here.


for (int i=0; i<numWeaps; ++i) {
Weapon* w=VecWeapon[i]; //just me being lazy

glTranslatef(w->position.xpos, w->position.ypos, w->position.zpos);
VecWeapon[i].Draw();
}
}


another thing. consider using a factory. its job would be creating and deleting weapons. why would this be a good idea:

all created weapons are stored within the factory (or call it manager). you want get memory leaks because you were overwriting a pointer and you wont have two pointers to the same object (well, you will, but you wont try to delete them because thats the job of the manager). this could even create weapons of a derived type. im not keen on singletons so im doing something that might look pretty ugly... lots of statics. ill try to do a general factory/manager, not just for guns, but game objects in general.

   
class ObjectFactory {
private:
ObjectFactory(); //no instance possible

static list<Object*> Objects;
public:
static Weapon* CreateWeapon(int Type);
static Vehicle* CreateVehicle(int Type);
static void Destroy(Object* obj);

static void CleanUp();
};
list<Object*> ObjectFactory::Objects;

Weapon* ObjectFactory::CreateWeapon(int Type) {
Weapon* result=0;
switch (Type) {
case WEAP_TYPE_LASER:
result=new Weapon(bla, bla, bla);
//set whatever

break;
default:
cout << "Unknown Weapon Type requested" << endl;
}
return result;
}

void ObjectFactory::Destroy(Object* obj) {
Objects.remove(obj);
delete obj;
}

void ObjectsFactory::CleanUp() {
while (Objects.size()) {
delete Objects.front();
Objects.pop_front();
}
}


looks like a lot of pointless work, but it never hurts to have everything at one place and not flying around everywhere.

to get a weapon you would do this:
Weapon* weapon=ObjectFactory::CreateWeapon(WEAP_TYPE_LASER);

if you dont need it anymore:
ObjectFactory::Destroy(weapon);

and after a level :
ObjectFactory::CleanUp();

the factory might be extra work, but the rest of the code will be a lot cleaner.

[edited by - Trienco on May 31, 2003 11:51:01 AM]

[edited by - Trienco on May 31, 2003 11:52:30 AM]

Share this post


Link to post
Share on other sites
Trienco, it seems that your method for determining the time to render a weapon after a certain ammount of time is not working for my purposes. In my main render function (which I use to draw everything) I get the elapsed amount of time and pass it to the weapon rendering function which determines if the weapon draw function should be called.

this is in the main render function: double ElapsedTime = gameWorld->worldTime.GetElapsedTime(1);

this is the weapon render function which gets passed the ElapsedTime variable.

void World::RenderWeapon(double w_time)
{
Weapon *tempWeapon = new Weapon();
static float TimeUntilSpawn=0; //spawn at first time

int randWeapon;

if (TimeUntilSpawn -= w_time <= 0) // if we have run out of time render a new weapon

{
if(this->numWeapons)
{
randWeapon = 1 + (rand()%5); // generate a weapon


switch(randWeapon)
{
case 1: tempWeapon->setWeapon(MEGA_BURST);
tempWeapon->setDamage(3);
tempWeapon->setShots(AMMO_MEGA_BURST);
break;
case 2: tempWeapon->setWeapon(LASER);
tempWeapon->setDamage(8);
tempWeapon->setShots(AMMO_LASER);
break;
case 3: tempWeapon->setWeapon(GRENADE);
tempWeapon->setDamage(12);
tempWeapon->setShots(AMMO_GRENADE);
break;
case 4: tempWeapon->setWeapon(ICE_SHOT);
tempWeapon->setDamage(15);
tempWeapon->setShots(AMMO_ICE_SHOT);
break;
case 5: tempWeapon->setWeapon(NUKE);
tempWeapon->setDamage(20);
tempWeapon->setShots(AMMO_NUKE);
break;
default: tempWeapon->setWeapon(BULLET);
tempWeapon->setDamage(2);
tempWeapon->setShots(AMMO_BULLET);
break;
}
}
this->numWeapons += 1;

glTranslatef(tempWeapon->position.xpos, tempWeapon->position.ypos, tempWeapon->position.zpos);

tempWeapon->Draw();

TimeUntilSpawn = 30;
}
}


Even though the ElapsedTime variable is getting updated each frame my counter isn''t operating at the time interval I set (almost at the verge of a mental meltdown).

Share this post


Link to post
Share on other sites
what is your draw function doing? or the weapon constructor? if draw does nothing but drawing the weapon then your problem isnt any timing, but that you draw it for one single frame and then never again.

also it seems that you will always draw a weapon, but when no new weapon is created its a weapon either not initiliazed or with the values of your constructor..

Share this post


Link to post
Share on other sites