So to describe more about my collision.
Units and tiles are size of 32 pixels in height and width.
Units each (500+rand()%500) get to pick action. If their last action is not finished they will continue doing current action.
When action is done a bool(isActionDone = true) marking for next unit loop that unit can take new action.
When unit acts it does following
moveDirY = rand()%4;//0 = noDir, 1 = up, 2 = down, 3 = noDir
moveDirX = rand()%4+2;//2 = noDir, 3 = left, 4 = right, 5 = noDir
if(moveDirY == up)
moveAmountY = -(rand()%96 + 32);
else if(moveDirY == down)
moveAmountY = (rand()%96 + 32);
Same occures for X movement and in case of noDir moveDir is set to 0 at begining of the loop.
Then units "move();" function is issues
allTypes toPositive(allTypes num)
{
if(num < 0)
num *= -1;
return num;
}
bool Map::CheckTileWalkable(float posX, float posY);//returns true if tile is walkable
//I will explain about this later
moveAmount = unitMoveRate * deltaTime;
if(toPositive(moveAmountY) > 0)
{
if(objMap.CheckTileWalkable(unitPosX, unitPosY + moveAmount) == true)
unitPosY += moveAmount;
}
//Same occurs for X except for X values
Now for the map collision detection witch i think is the problem in my case.
There are four cases i need to check before execute.
1:
if(int(unitPosX)%TILE_SIZE/*32*/ == 0) //Checking if units X is directly only one tile if so check only 1 tile vertically, if false check 2 tiles vertically.
2: same as case 1 except checking for y
3:There is a bool(bool isWalkable = true) and from above code we can see witch tiles to check so the cases for tile check is
x=1 y=1, or x=2 y=1, or x=1 y=2, or x=2 y=2.
So i have 1D array of tiles that is stored in vector
for(int y = 0; y <= tilesToCheckY; y++)
{
for(int x = 0; x < tilesToCheckX; x++)
{
if(mapVec[(unitPosX%TILE_SIZE)+x + (((unitPosY%TILE_SIZE)+y)*mapSizeX).isWalkable == false)
isWalkable = false;
}
}
return isWalkable;
IMO i am looking for a better way to provide illusion of units just wandering around map from time to time, and from the posts i read there was one great idea.
Check collision only once and store a path, then move unit along that path. This will be my next step i will attempt.
NOTE:: Not actual code, i do not have my project on this harddrive atm, i will update if i get huge desire to do so.
Somehow i don't like the performance i am getting and i am looking for some kind of nourishment because i am procrastinating this and it is really holding me back.
how many units, and whats your fps?
Do note i am not ignoring, but my hard drive is out of my reach at the moment i will post as soon as i have it.
EDIT:: Posting the code in case someone will need it
The following code is for unit getting random movement direction on X and Y and moving according to data stored in class.]
Pixel perfect collision included, if you are struggling.. ^^ feel free to use it.
//.h
class AI
{
public:
AI(int & dt, Map & objMap);
protected:
void LoopAI(BaseUnitForMap & objUnit);
void MoveDecidePosition();
void MoveExecute();
void MovePixelPerfectX();
void MovePixelPerfectY();
private:
int & dt;
BaseUnitForMap * objUnitptr;
Map * objMap;
int toPositive(int num);
int moveAmountX, moveAmountY;
bool isSprinting;
bool movePixelPerfectX, movePixelPerfectY;
int tempI;
};
//.cpp
void AI::MoveDecidePosition()
{
int directionY = rand()%4;//Decide 0 nowhere, 1 up, 2 down, 3 nowhere
//int directionY = 2;//Decide 0 nowhere, 1 up, 2 down, 3 nowhere
int directionX = rand()%4+2;//Decide 2 = nowhere, 3 left, 4 right, 5 nowhere
//int directionX = 0;//Decide 2 = nowhere, 3 left, 4 right, 5 nowhere
if(directionY == en::Dirrection::up)
{
objUnitptr->moveAmountAIY = rand()%64+16;
objUnitptr->moveDirY = en::Dirrection::up;
}
else if(directionY == en::Dirrection::down)
{
objUnitptr->moveAmountAIY = rand()%64+16;
objUnitptr->moveDirY = en::Dirrection::down;
}
if(directionX == en::Dirrection::left)
{
objUnitptr->moveAmountAIX = rand()%64+16;
objUnitptr->moveDirX = en::Dirrection::left;
}
else if(directionX == en::Dirrection::right)
{
objUnitptr->moveAmountAIX = rand()%64+16;
objUnitptr->moveDirX = en::Dirrection::right;
}
//if(directionX > 0 && directionY > 2)
objUnitptr->acting = true;
}
void AI::MoveExecute()
{
//Horizontal
if(objUnitptr->moveDirX == en::Dirrection::left)
moveAmountX = -objUnitptr->movementRate * dt;
else if(objUnitptr->moveDirX == en::Dirrection::right)
moveAmountX = objUnitptr->movementRate * dt;
else
moveAmountX = 0;
//Vertical
if(objUnitptr->moveDirY == en::Dirrection::up)
moveAmountY = -objUnitptr->movementRate * dt;
else if(objUnitptr->moveDirY == en::Dirrection::down)
moveAmountY = objUnitptr->movementRate * dt;
else
moveAmountY = 0;
//Move X
if(moveAmountX != 0)
{
if(objMap->CHECKOutOfBounds(objUnitptr->posX + moveAmountX, objUnitptr->posY) == false)
{
//std::cout<<"pass1"<<std::endl;
if(objMap->CHECKWalkable(objUnitptr->posX + moveAmountX, objUnitptr->posY) == true)
{
//std::cout<<"pass2"<<std::endl;
objUnitptr->posX += moveAmountX;
movePixelPerfectX = true;
}
else if(movePixelPerfectX == true)
MovePixelPerfectX();
//else
//std::cout<<"Coll1"<<std::endl;
}
else if(movePixelPerfectX == true)
MovePixelPerfectX();
//else
//std::cout<<"OOB1"<<std::endl;
}
//Move Y
if(moveAmountY != 0)
{
if(objMap->CHECKOutOfBounds(objUnitptr->posX, objUnitptr->posY + moveAmountY) == false)
{
if(objMap->CHECKWalkable(objUnitptr->posX, objUnitptr->posY + moveAmountY) == true)
{
objUnitptr->posY += moveAmountY;
movePixelPerfectY = true;
}
else if(movePixelPerfectY == true)
MovePixelPerfectY();
//else
//std::cout<<"Coll2"<<std::endl;
}
else if(movePixelPerfectY == true)
MovePixelPerfectY();
//else
//std::cout<<"OOB2"<<std::endl;
}
//std::cout<<"MAX:"<<moveAmountX<<" MAY:"<<moveAmountY<<std::endl;
if(objUnitptr->moveAmountAIX - toPositive(moveAmountX) < 1 &&
objUnitptr->moveAmountAIY - toPositive(moveAmountY) < 1)
{
//std::cout<<"1"<<std::endl;
objUnitptr->acting = false;
}
else
{
//std::cout<<"2"<<std::endl;
objUnitptr->moveAmountAIX -= toPositive(moveAmountX);
objUnitptr->moveAmountAIY -= toPositive(moveAmountY);
}
}
void AI::MovePixelPerfectX()
{
//Moving PP X
//std::cout<<"PP1 posX"<<objUnitptr->posX<<std::endl;
movePixelPerfectX = false;
if(objUnitptr->moveDirX == en::Dirrection::left)
{
objUnitptr->posX -= (objUnitptr->posX % TILE_SIZE);
//else do nothing
}
else if(objUnitptr->moveDirX == en::Dirrection::right)
{
tempI = objUnitptr->posX % TILE_SIZE;
if(tempI != 0)
objUnitptr->posX += TILE_SIZE - (objUnitptr->posX % TILE_SIZE);
}
//std::cout<<"PP1 end posX"<<objUnitptr->posX<<std::endl;
}
void AI::MovePixelPerfectY()
{
//Moving PP Y
//std::cout<<"PP1 posY"<<objUnitptr->posY<<std::endl;
movePixelPerfectY = false;
if(objUnitptr->moveDirY == en::Dirrection::up)
{
objUnitptr->posY -= (objUnitptr->posY % TILE_SIZE);
}
else if(objUnitptr->moveDirY == en::Dirrection::down)
{
tempI = objUnitptr->posY % TILE_SIZE;
if(tempI != 0)
objUnitptr->posY += TILE_SIZE - (objUnitptr->posY % TILE_SIZE);
}
//std::cout<<"PP1 end posY"<<objUnitptr->posY<<std::endl;
}
int AI::toPositive(int num)
{
if(num < 0)
return num *= -1;
return num;
}