The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Help, collision check alive objects
macrofeet


Joined: 29 Apr 2012
Posts: 20
Simple 2d Bounding Box collision detection I'm using on the following game

http://gamejolt.com/games/arcade/asteroids-flackroid-hd/52501/

bool GameObject::CollChk(GameObject B, int AReductionX,int AReductionY,int BReductionX,int BReductionY )
{ //The sides of the rectangles
int LeftA, LeftB;
int RightA, RightB;
int TopA, TopB;
int BottomA, BottomB;

///CheckCol = 1; //switch to show hit points

//square Object1
LeftA = XPos+AReductionX;
RightA = XPos+LImageLength-AReductionX;
TopA= YPos+AReductionY;
BottomA = YPos+LImageHeight-AReductionY;

//Square Object2
LeftB = B.XPos+BReductionX;
RightB = B.XPos+ B.LImageLength-BReductionX;
TopB = B.YPos+BReductionY;
BottomB = B.YPos+ B.LImageHeight-BReductionY;


if( (BottomA <= TopB) || (TopA >= BottomB) || (RightA <= LeftB) || (LeftA >= RightB) )
return false; else return true;
}


In the following I check collision and move various objects against each other


void MoveObjects()
{
for (int Q = 0; Q <= PtCals; Q++) if (PartS[Q].IsAlive) {PartS[Q].Move(); if (PBullet.EventTimer(PBullet.ALiveDuration)) PBullet.IsAlive=false;} //move particals
LevelImage.apply_surfacing();
LevlNumb.apply_surfacing();
if (PBullet.IsAlive) { PBullet.Move(); if (PBullet.EventTimer(PBullet.ALiveDuration)) PBullet.IsAlive=false;}// check if ship is firing update bullet location
if (LevelBreak.IsAlive)
{
if (Mix_Playing(2)==false) Mix_PlayChannel( 2, LevelUp, 0 );
LevelBreak.apply_surfacing();
if (LevelBreak.EventTimer(1000))
{
LevelBreak.IsAlive=false;
Shipshield.IsAlive=false;
}
}
if (Enterprise.IsAlive)
{
ShipHealth.SetLocation(Enterprise.XPos-35,Enterprise.YPos+20);
if (Enterprise.Movement()=='T') Thurst();
if (Shipshield.IsAlive) Shipshield.SetLocation(Enterprise.XPos,Enterprise.YPos);
Enterprise.Move();
Enterprise.LoopObjectOnScreen(); // loop player ship around screen
}
EndLev=1; //Get ready for end of level if no Large asteroids are alive that is check to see...
for (int i = 0; i < lvlnum; i++) if (Ast[i].IsAlive) // check from 1 to amount of created (Large Asteroids Check) if the large Asteroid [i] is alive
{
Ast[i].LoopObjectOnScreen(); // if off edge of screen loop round
Ast[i].loopspritesheet(); // move on spritesheet and if at end reset/loop to start
Ast[i].Move(); // set the Asteroid type fire ice rock change to the correct texture
EndLev=0; // it is not the end of the level at least 1 asteroid is left alive dont end level
if(Ast[i].CollChk(Enterprise,15,20,20,20)) //if a roid hit player or player hit roid blow up
{
Enterprise.IsAlive=false; // player ship dead
Ast[i].IsAlive=false; // asteroid dead
Explode[1].SetLocation(Ast[i].XPos,Ast[i].YPos); //set explode location
Explode[1].SetAlive();
Mix_PlayChannel( -1, LargeExp , 0 );
Explode[0].SetLocation(Enterprise.XPos,Enterprise.YPos); //set explode location
Explode[0].SetAlive();
}
if (Shipshield.IsAlive) // if shield active
{
if(Ast[i].CollChk(Shipshield,0,0,0,0)) //if a roid hit player shield or player hit roid blow up
{
Shipshield.IsAlive=false; // player ship dead
Ast[i].IsAlive=false; // asteroid dead
Explode[1].SetLocation(Ast[i].XPos,Ast[i].YPos); //set explode location
Explode[1].SetAlive();
Mix_PlayChannel( -1, LargeExp , 0 );
SaveAstNum=i; //record the roid number the one that blew up
SpawnObjects(2);
SpawnObjects(3);
}
}
if (PBullet.IsAlive) //if bullet is active/fired
{
if (Ast[i].CollChk(PBullet,10,12,0,0)) // check if bullet hit the large Asteroid if so..
{
if (Ast[i].Hit_Points > 0) Ast[i].Hit_Points--; //asteroid has been hit
Mix_PlayChannel( -1, SmallExp, 0 ); //play hit sound
PBullet.IsAlive=false; // kill bullet
if (Ast[i].Hit_Points == 0)// if asteroid has no health left kill
{
Ast[i].IsAlive = false; // kill roid
Explode[1].SetLocation(Ast[i].XPos, Ast[i].YPos); //Set blowup location
Explode[1].IsAlive = true; // begin explode
SaveAstNum = i; //record the roid number the one that blew up
SpawnObjects(2);
SpawnObjects(3);
Mix_PlayChannel( -1, LargeExp , 0 );
}
}
}
}
for (int Q = 0; Q <= AstSmNum; Q++) // Small Asteroids Check
{
if (AstS[Q].IsAlive)
{
AstS[Q].LoopObjectOnScreen(); // loop small asteroid on playfield if reach edge
AstS[Q].Move(); // move the sprite
AstS[Q].apply_surfacing();
if(AstS[Q].CollChk(Enterprise,0,0,30,30)) //if a Small asteroid hit player or player hit asteroid blow up
{
Enterprise.Hit_Points--; // reduce health counter
ShipHealth.loopspritesheet(); // Animate Decrease health counter
if (Enterprise.Hit_Points == 0) {
Enterprise.IsAlive=false; // player ship dead
Mix_PlayChannel( -1, LargeExp , 0 );
}
AstS[Q].IsAlive=false; // asteroid dead
Explode[0].SetLocation(AstS[Q].XPos,AstS[Q].YPos); //set explode location
Explode[0].IsAlive=true; //explode alive
Mix_PlayChannel( -1, SmallExp, 0 ); // play small explode sound
}
if (Shipshield.IsAlive)
{
if(AstS[Q].CollChk(Enterprise,0,0,0,0)) //if shield active & Small asteroid hit player or player hit asteroid blow up
{
Shipshield.IsAlive=false; // take shield down
AstS[Q].IsAlive=false; // asteroid kill
Explode[1].SetLocation(AstS[Q].XPos,AstS[Q].YPos); //set explode location
Explode[1].SetAlive();
Mix_PlayChannel( -1, SmallExp, 0 ); //play small explode sound
}
}
if (PBullet.IsAlive) //if bullet is active/fired
{
PBullet.LoopObjectOnScreen(); //loop bullet if ship is alive and bullet is alive
if (AstS[Q].CollChk(PBullet, 0, 0, 0, 0)) // check if bullet hit the small asteroid if so..
{
PBullet.IsAlive = false; // kill bullet as it hit Asteroid [Q]
AstS[Q].IsAlive = false; // kill Small Asteroid Number [Q] it was hit by bullet
Explode[0].SetLocation(AstS[Q].XPos,AstS[Q].YPos); //set explode location
Explode[0].IsAlive=true;
Mix_PlayChannel( -1, SmallExp, 0 ); //play hit sound
}
}
}
}

}

I'm trying to find a better way to collision check all alive objects ?
macrofeet


Joined: 29 Apr 2012
Posts: 20
Quote:
I'm trying to find a better way to collision check all alive objects?


I'm happy with Bounding Box collision detection,

but I'm thinking the repetitive way in which objects are checked against each other is far from great
macrofeet


Joined: 29 Apr 2012
Posts: 20
Code:

void UpdateAsts(void)
{
   int Ctype =0; // type of collsion 
   int Lcount =-1; // Alive large asteroid counter
   int Scount=-1; // alive small asteroid counter
   int SAN,LAN =0; //large Asteroid Number from array
 
   for (int i = 0; i < lvlnum; i++) if (Ast[i].IsAlive) //Record Large alive Asteroids
   {
     Lcount++; // inc counter
     LAlive[Lcount]= i; // store large alive asteroid
   }

   for (int Q = 0; Q <= MaxAstS; Q++) if (AstS[Q].IsAlive) //Record small alive Asteroids
   {
     Scount++; // inc counter
     SAlive[Scount]= Q; // store small alive asteroid
   }

   if (Lcount==-1) EndLev=1; // end level true
   else EndLev=0; // large asteroids left end level false
   
   for (; Lcount>-1; Lcount--) // for all the alive ones if any
   {
    LAN=LAlive[Lcount]; // copy array to integer faster than multiple reading array 
    Ast[LAN].LoopObjectOnScreen(); // if off edge of screen loop round
    Ast[LAN].loopspritesheet(); // move on spritesheet and if at end reset/loop to start
    Ast[LAN].Move(); // Move Asteroid
   
    if (Ast[LAN].CollChk(Enterprise,15,20,20,20)) Ctype=1; //if a roid hit player or player hit roid blow up
    else if ((Shipshield.IsAlive) && (Shipshield.CollChk(Ast[LAN],0,0,0,0))) Ctype=2; //if a roid hit player shield or player hit roid blow up
    else if ((PBullet.IsAlive) && (PBullet.CollChk(Ast[LAN],10,12,0,0))) Ctype=3; //if single bullet is active/fired
    else Ctype=0; // nothing happend

    if (Ctype!=0) // if something happend
    {
      if ( Ctype==1)  // player ship dead
      {
        Enterprise.IsAlive=false;
        Explode[1].SetLocation(Ast[LAN].XPos,Ast[LAN].YPos); //set explode location
        Explode[1].IsAlive = true; // begin explode
        Mix_PlayChannel( -1, LargeExp , 0 );
        Explode[0].SetLocation(Enterprise.XPos,Enterprise.YPos); //set explode location
        Explode[0].SetAlive();
      }
      else if( Ctype==2)  // asteroid dead, shield dead
      {
        Ast[LAN].IsAlive=false;
        Explode[1].SetLocation(Ast[LAN].XPos,Ast[LAN].YPos); //set explode location
        Explode[1].IsAlive = true; // begin explode
        Mix_PlayChannel( -1, LargeExp , 0 );
        SaveAstNum=LAN; //record the roid number the one that blew up
        SpawnObjects(2);
        SpawnObjects(3);
      }
      else if (Ctype==3) //asteroid has been hit by bullet
      {
        if (Ast[LAN].Hit_Points > 0) Ast[LAN].Hit_Points--;
        Mix_PlayChannel( -1, SmallExp, 0 ); //play hit sound
        if (Ast[LAN].Hit_Points == 0)// if asteroid has no health left kill
        {
          Ast[LAN].IsAlive = false; // kill roid
          Explode[1].SetLocation(Ast[LAN].XPos, Ast[LAN].YPos); //Set blowup location
          Explode[1].IsAlive = true; // begin explode
          SaveAstNum = LAN; //record the roid number the one that blew up
          SpawnObjects(2);
          SpawnObjects(3);
          Mix_PlayChannel( -1, LargeExp , 0 );
        }
      }
    }
   }
  Ctype=0;

  if (Scount!=-1) // not no small asteroids
  for (; Scount>-1; Scount--) // for all the alive ones if any  // Small Asteroids Check
  {
    SAN=SAlive[Scount]; // copy array to integer faster than multiple reading array
    AstS[SAN].LoopObjectOnScreen(); // loop small asteroid on playfield if reach edge
    AstS[SAN].Move(); // move the sprite

    if(AstS[SAN].CollChk(Enterprise,0,0,30,30)) Ctype=4;
    else if ((Shipshield.IsAlive) && (Shipshield.CollChk(Ast[SAN],0,0,0,0))) Ctype=5;
    else if ((PBullet.IsAlive) && (PBullet.CollChk(AstS[SAN], 0, 0, 0, 0))) Ctype=6;
    else Ctype=0; // nothing happend]
   
    if (Ctype!=0) // if somthing happend
    {
      if ( Ctype==4)  // player ship dead
      {
        Enterprise.Hit_Points--; // reduce health counter
        ShipHealth.loopspritesheet(); // Animate Decrease health counter
        if (Enterprise.Hit_Points == 0)   
        {
          Enterprise.IsAlive=false;  // player ship dead
          Mix_PlayChannel( -1, LargeExp , 0 );
        }
        Explode[0].SetLocation(AstS[SAN].XPos,AstS[SAN].YPos); //set explode location
        Explode[0].IsAlive=true; //explode alive
        Mix_PlayChannel( -1, SmallExp, 0 ); // play small explode sound
      }
      else if ( Ctype==5)  //if shield active & Small asteroid hit player or player hit asteroid blow up
      {
        Shipshield.IsAlive=false; // take shield down
        Explode[1].SetLocation(AstS[SAN].XPos,AstS[SAN].YPos);  //set explode location
        Explode[1].IsAlive = true; // begin explode
        Mix_PlayChannel( -1, SmallExp, 0 ); //play small explode sound
      }
      else if ( Ctype==6)
      {
        AstS[SAN].IsAlive = false; // kill Small Asteroid Number [Q] it was hit by bullet
        Explode[0].SetLocation(AstS[SAN].XPos,AstS[SAN].YPos);  //set explode location
        Explode[0].IsAlive=true;
        Mix_PlayChannel( -1, SmallExp, 0 ); //play hit sound
      }
    }
  }
}


Here is what I came up with any help would be great