Jump to content
  • Advertisement
Sign in to follow this  
ThePointingMan

Serious slowdown!

This topic is 2753 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently working on my first game in c++(Other then Pong :P) and have got almost everything running smoothly... However, I just ran into the problem of making the bullets hit the enemies. I made a system that stores all bullets in one list, and all enemies in another, and created a hit test function, but when testing for every bullet and every enemy (currently only 3 enemies and 3 bullets on screen) brings terrible lag, So I was wandering what methods are used for testing collisions between large groups of things without producing a massive amount of slowdown.Also here is what mine is.
while(e != enemies->end())
{
i = bullets->begin();
while(i != bullets->end())
{
if(HitBox(e->x, e->y, i->x, i->y, e->w, e->h, i->w, i->h))
{
e->erase=true;
i->erase=true;
}
i++;
}
e++;
}

as well as
bool HitBox(float x1, float y1, float x2, float y2, float w1, float h1, float w2, float h2)
{
bool collision;
if(x1 >= x2 && (x2 + w2) >= (x1 + w1) && y1 >= y2 && (y2 + h2) >= (y1 + h1))
{
collision = true;
}
else
{
collision = false;
}
return collision;
}

Share this post


Link to post
Share on other sites
Advertisement
While your approach isn't the most efficient it shouldn't be a problem doing all of 3*3=9 HitBox tests per frame. If you're experiencing slowdown with so few enemies and bullets your problem is elsewhere. Once you solve that problem and would like to be able to handle larger numbers of interactions you may want to look into some kind of spatial hierarchy, even something as simple as a grid.

Share this post


Link to post
Share on other sites
As wild_pointer said, the problem is not likely to be your hit-check code as posted. It isn't ridiculously efficient, but unless you're running on an 8088 CPU from decades ago, it should perform just fine. Post more code if you can, or throw a profiler at it and see where your time is really going.

Share this post


Link to post
Share on other sites
Good to know It most likely isn't in what I posted, I'll just post my entire Logic file I guess. A lot of the stuff is really crude, but it's a start. I'm hoping to finish this before I graduate to apply for a scholarship for post secondary education.

P.S. The game is a side scrolling shoot 'em 'up.


Everything above the line
//are things touching... THIS IS A SHOOTEM UP! anything touching should EXPLODE!!!
should be unrelated to the problem I'm thinkin.
#include "Global.h"
OBJECT bult;
OBJECT enem;
OBJECT screen;
int ftime=0;
int scroll=0;
int sch=1;
void InitGame(OBJECT* ship)
{
screen.x=-500;
screen.y=-500;
screen.w=1024+500+500;
screen.h=1268+500;
// Initialize Player 1
ship->x = 150.0f;
ship->y = 350.0f;
ship->xspeed=.6f;
ship->yspeed=-.6;//I prefer down to be negative
ship->xmomentum = 0.0f;
ship->ftype=3;
ship->direction=0;
ship->type=6*2;
ship->w = 100;
ship->h = 67;
ship->antimer=0;

return;

}

void Logic(OBJECT* ship, list<OBJECT> *bullets, list<OBJECT> *enemies, INPUTDATA* InputData)
{
scroll++;
ftime--;
ship->antimer-=0.1f;
static int time, start_time = GetTickCount();
time = GetTickCount() - start_time;
start_time = GetTickCount();

for(int ms = 0; ms < time; ms++) // once per millisecond...
{
// Take the input and calculate Player 1's change in momentum
if(InputData->MoveLeft)
{
ship->xmomentum=-ship->xspeed;
ship->direction=1;
}
if(InputData->MoveRight)
{
ship->xmomentum=ship->xspeed;
ship->direction=1;
}
if(InputData->MoveUp)
{
ship->ymomentum=ship->yspeed;
ship->direction=5;
}
if(InputData->MoveDown)
{
ship->ymomentum=-ship->yspeed;
ship->direction=3;
}
if(!InputData->MoveLeft&&!InputData->MoveRight || InputData->MoveLeft&&InputData->MoveRight )
{
ship->xmomentum=0.0f;
}
if(!InputData->MoveUp&&!InputData->MoveDown || InputData->MoveUp&&InputData->MoveDown)
{
ship->ymomentum=0.0f;
ship->direction=1;
}
// Move the player based on his new momentum
ship->x += ship->xmomentum;
ship->y += ship->ymomentum;
// create enemies
ec(enemies, scroll);
//take input/ change shoot type/ shoot
bult.x=ship->x+ship->w;
bult.y=ship->y;
if(InputData->Spread)
{
ship->ftype=3;
if(ftime<-1)
{

ftime=8;
bult.type=3;
bult.xspeed=1.5f;
bult.w=100;
bult.h=67;
bult.ftype=3;
bult.yspeed=0;
bullets->push_back(bult);
bult.yspeed=0.2f;
bullets->push_back(bult);
bult.yspeed=-0.2f;
bullets->push_back(bult);
}

}
if(InputData->Laser)
{
ship->ftype=2;
if(ftime<0)
{
ftime=2;
bult.ftype=2;
bult.xspeed=2.0f;
bult.w=100;
bult.h=67;
bult.ftype=2;
bult.yspeed=0;
bullets->push_back(bult);
}
}
if(InputData->Explode)
{
ship->ftype=1;
if(ftime<0)
{
ftime=20;
bult.ftype=1;
bult.xspeed=1.0f;
bult.w=100;
bult.h=67;
bult.ftype=1;
bult.yspeed=0;
bullets->push_back(bult);
}
}
list<OBJECT>::iterator i = bullets->begin();
list<OBJECT>::iterator e = enemies->begin();
//are things touching... THIS IS A SHOOTEM UP! anything touching should EXPLODE!!!
while(e != enemies->end())
{
i = bullets->begin();
while(i != bullets->end())
{
if(HitBox(e->x, e->y, i->x, i->y, e->w, e->h, i->w, i->h))
{
e->erase=true;
i->erase=true;
}
i++;
}
e++;
}
// Move enemies, delete if necessary
e = enemies->begin();
while(e != enemies->end())
{
//check all things that might delete it
if((!HitBox(e->x, e->y, screen.x, screen.y, e->w, e->h, screen.w, screen.h)))
{
e->erase=true;
}
if(e->erase==true)
{
enemies->erase(e++);
}
else
{
e->x += e->xspeed;
e->y += e->yspeed;
e++;
}


}
// Move the bullets and Check if bullets are off the screen and delete them if they are/if collide with enemies delete
i = bullets->begin();
while(i != bullets->end())
{
e = enemies->begin();
if((!HitBox(i->x, i->y, screen.x, screen.y, i->w, i->h, screen.w, screen.h)))
{
i->erase=true;
}
if(i->erase==true)
{
bullets->erase(i++);
}
else
{

i->x += i->xspeed;
i->y += i->yspeed;
if(i->ftype==2)
{
i->y=ship->y;
}
i++;

}

}



//animate the enemies
// animate the ship
if(ship->antimer<0.0f)
{
if(ship->antimer<-0.5f)
{
ship->antimer=-ship->antimer;
ship->direction++;
}
}
// animate the eye's
// change sprite
ship->type=6*(ship->ftype-1)+(ship->direction-1);
// Detect player collision with the walls, and change the player momentum
if(ship->x < 0)
{
ship->x = ship->xmomentum;

}
if(ship->x + ship->w > 1024)
{
ship->x = 1024 - ship->w;
}
if(ship->y < 0)
{
ship->y = ship->ymomentum;

}
if(ship->y + ship->h > 768)
{
ship->y = 768 - ship->h;
}
}

return;
}
bool HitBox(float x1, float y1, float x2, float y2, float w1, float h1, float w2, float h2)
{
bool collision;
if(x1 >= x2 && (x2 + w2) >= (x1 + w1) && y1 >= y2 && (y2 + h2) >= (y1 + h1))
{
collision = true;
}
else
{
collision = false;
}
return collision;
}


// enemy ID
// 0:nothing
// 1:red eye
// 2:blue eye
// 3:green eye
void ec( list<OBJECT> *enemies, int x)
{
if(scroll==300)
{

enem.x=1025.0f;
enem.y=300.0f;
enem.xspeed=-.5f;
enem.w=100;
enem.h=67;
enem.ftype=1;
enem.direction=1;
enem.type=2*(enem.ftype-1)+(enem.direction-1);
enemies->push_back(enem);
}
if(scroll==320)
{
enem.direction=1;
enem.x=1025.0f;
enem.y=300.0f;
enem.xspeed=-.5f;
enem.w=100;
enem.h=67;
enem.ftype=2;
enem.type=2*(enem.ftype-1)+(enem.direction-1);
enemies->push_back(enem);
}
if(scroll==340)
{
enem.direction=1;
enem.x=1025.0f;
enem.y=300.0f;
enem.xspeed=-.5f;
enem.w=100;
enem.h=67;
enem.ftype=3;
enem.type=2*(enem.ftype-1)+(enem.direction-1);
enemies->push_back(enem);
}

}



Just in case I'll post the render file, but I really don't think there is an issue with it.
#include "global.h"

SPRITE graphics;
SPRITE spread;
SPRITE eyes;

void LoadGraphics()
{
LoadSprite(&graphics, TEXT("Derpderpderp.bmp"), 100, 67, 6, 3);
LoadSprite(&spread, TEXT("SpreadSpriteSheet.bmp"), 50,50,8,1);
LoadSprite(&eyes, TEXT("EyeSpriteSheet.bmp"), 50,50,2,3);

return;
}

void Render(OBJECT* ship, list<OBJECT> *bullets, list<OBJECT> *enemies)
{
StartRender();
DrawSprite(&graphics, ship->type, ship->x, ship->y, 0);
list<OBJECT>::iterator index;
for(index=enemies->begin();index != enemies->end(); index++)
{
DrawSprite(&eyes, index->type, index->x, index->y, 0);
}
for(index=bullets->begin();index != bullets->end(); index++)
{
DrawSprite(&spread, index->type, index->x, index->y, 0);
}
EndRender();

return;
}

Share this post


Link to post
Share on other sites
Your problem is almost certainly this outer loop in your Logic function:



void Logic(OBJECT* ship, list<OBJECT> *bullets, list<OBJECT> *enemies, INPUTDATA* InputData)
{
static int time, start_time = GetTickCount();
time = GetTickCount() - start_time;
start_time = GetTickCount();

for(int ms = 0; ms < time; ms++) // once per millisecond...
{
// ...
}

return;
}
}


This is certainly not doing what you intended. It's almost as if you expect this to be running in another thread but I'll assume for the moment it is not.

What does your game loop look like? How are you calling Logic? Assuming something like 30fps that's 33 ms a frame and that means your input handling and collision is going to run 33 times every time you call logic. And it's not going to run every ms, it will happen much more quickly. Think about it: you don't expect your other for loops to take 1ms per iteration so why would this one? In fact, once your framerate starts to drop you'll get crazy pathological behavior where your logic function starts running through that loop even more often due to the larger time delta.

Share this post


Link to post
Share on other sites
Here's what my loop looks like.
#include "global.h"

OBJECT ship;
INPUTDATA InputData;
list<OBJECT> bullets;
list<OBJECT> enemies;
// The Main Loop
void MainLoop()
{
InitGame(&ship);

while(HandleMessages())
{
Input(&InputData);
Logic(&ship, &bullets, &enemies, &InputData);
Render(&ship, &bullets, &enemies);
}
}

Also >_> Yeah, what I wrote doesn't make sense, I'm going to have to do a recode of that.

edit:
I've made some changes and it seems to work pretty good! Thanks for the help.
ftime--;
ms++;
ship->antimer-=0.1f;
static int time, start_time = GetTickCount();
time = GetTickCount() - start_time;
start_time = GetTickCount();

if( ms < time) // once per millisecond...
{
ms=0;

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!