# Serious slowdown!

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

## Recommended Posts

I'm currently working on my first game in c++(Other then Pong ) 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 on other sites
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 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 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 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 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;

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
5. 5
A4L
11

• 12
• 16
• 26
• 10
• 44
• ### Forum Statistics

• Total Topics
633767
• Total Posts
3013739
×