I have spent all day trying to solve what i thought was going to be an easy problem.
I am using MVS 2008.
So here is the skinny.
I created numerous classes each in their own file.
on 2 particular files BallManager.H and in PlayerManager.H
i have created a Vector containing objects of the type the managers are to manage.
like so
in BallManager.h
vector<Ball> AllBalls;
in PlayerManager.h
vector<Player> AllPlayers;
i am able to pass by reference Allplayers from PlayerManager to Player with no problem so it can be used.
example...
in playerManager.cpp
void PlayerManager::Update(int ScreenWidth, int ScreenHeight, vector<Ball> & AllBalls)
{
//calls update on all Players created
for(int i=0; i<PlayerCounter(); i++)
{
AllPlayers[i].Update(AllPlayers,FourNotTwo, ScreenWidth,ScreenHeight,AllBalls);
}
}
As AllPlayers is created in playerManager it has no trouble passing it via reference to the Player class so that a given player and do comparisons against all players.
HOWEVER, The input argument vector<Ball> &AllBalls gives me the undefined Identifer error.
how that came to be......
My main cpp file is called touchdemo. and it creates BOTH managers.
I then at some given point i determined i needed the AllBalls Data to compare against the AllPlayers Data. So i passed the AllBalls Data via reference to the Update() function in PlayerManger. which in turn passes the vector via reference to the Update() for player.
I thought the solution would be to include the Ball.h or BallManager.h in my PlayerManager.h file. so that it would know what ball was. however this only gives more errors and yet still keeps the old ones there saying its undefined identifier.
anyone have any suggestions?
im going to post below this one all the actual code so you can see.
//to give each player the same Red texture
HTEXTURE PaddleTexR;
//to give each player the same Green texture
HTEXTURE PaddleTexG;
//to give each player the same Blue texture
HTEXTURE PaddleTexB;
//to give each player the same Yellow texture
HTEXTURE PaddleTexY;
// a vector to hold all the players info
vector<Player> AllPlayers;
//Current Number of players
int CurrentPlayers;
//Current number of Teams
int CurrentTeams;
};
/*
** PlayerManager.cpp
*/
#include "PlayerManager.h"
//creates the Player manager to handle the Player
PlayerManager::PlayerManager(HGE *_hge)
{
//current Players in game
CurrentPlayers = 0;
//Current Teams in game
CurrentTeams = 0;
//team type designator
EveryMan = true;
//players type designator
FourNotTwo = false;
}
// because we cant load textures until HGE has been initialized...so we call this little gem later.
void PlayerManager::Initialize(HGE *_hge)
{
//to give the Players all the same texture.
PaddleTexR= _hge->Texture_Load("PaddleRed.png");
//to give the Players all the same texture.
PaddleTexG= _hge->Texture_Load("PaddleGreen.png");
//to give the Players all the same texture.
PaddleTexB= _hge->Texture_Load("PaddleBlue.png");
//to give the Players all the same texture.
PaddleTexY= _hge->Texture_Load("PaddleYellow.png");
}
void PlayerManager::Render()
{
//calls render on all Players created
for(int i=0; i<PlayerCounter(); i++)
{
AllPlayers[i].Render();
}
}
void PlayerManager::Update(int ScreenWidth, int ScreenHeight, vector<Ball> & AllBalls)
{
//calls update on all Players created
for(int i=0; i<PlayerCounter(); i++)
{
AllPlayers[i].Update(AllPlayers,FourNotTwo, ScreenWidth,ScreenHeight,AllBalls);
}
}
void PlayerManager::GetAllPlayerInput(HGE *_hge)
{
//calls update on all Players created
for(int i=0; i<PlayerCounter(); i++)
{
AllPlayers[i].GetInput(_hge);
}
}
int PlayerManager::PlayerCounter()
{
//return how many Player we have
return CurrentPlayers;
}
int PlayerManager::TeamCounter()
{
//return how many Player we have
return CurrentTeams;
}
void PlayerManager::UpdateTeams()
{
//can have 2 or 4 teams
//if everyman is true
if(EveryMan)
{
//every player is on his own team
CurrentTeams = CurrentPlayers;
}
else
{
//team is forced to 2. if 2 players thats 2 teams if 4 players its team based.
CurrentTeams = 2;
}
}
void PlayerManager::SetTeam(int PlayerNum, int DesiredTeam)
{
//tell player to change to DesiredTeam
AllPlayers[PlayerNum].SetTeam(DesiredTeam);
}
if(CurrentPlayers >0)
{
for(int i=CurrentPlayers-1; i>=0; i--)
{
//calls delete on the last enterd Player
AllPlayers[i].Delete();
//removes the last Player added to the vector
AllPlayers.pop_back();
}
}
//remove all Player from the counter
CurrentPlayers= 0;
int temp =999;
//4not2 true? then 4 players
if(FourNotTwo)
{
//set up 4 players
//how many teams?
//if 2
if(!EveryMan)
{
for(int i =0; i<4; i++)
{
//increase current Player counter; for player ID use
CurrentPlayers++;
//Set that player to a team based on his ID. (CurrentPlayers%2) so even players are team 1 and odd players are team 2
temp = CurrentPlayers%2;
//swap it so that players 1 and 3 are on team 1 and players 2 and 4 are on team 1
if(temp == 0)
temp = 1;
else
temp = 0;
temp +=1;
// set up colors for paddles based on team.
switch(temp)
{
case 1:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexR,ScreenWidth,ScreenHeight,FourNotTwo)); break;
case 2:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexB,ScreenWidth,ScreenHeight,FourNotTwo)); break;
}
AllPlayers[CurrentPlayers-1].SetTeam(temp); //so teams are 1 and 2
}
}
//4 teams every man for himself
else
{
for(int i =0; i<4; i++)
{
//increase current Player counter; for player ID use
CurrentPlayers++;
//Set that player to a team based on his ID. (CurrentPlayers%4)
temp = CurrentPlayers%4;
if(temp == 0)
temp =4; // this means player 1 = team1 2= 2 3=3 4=4(not zero)
// set up colors for paddles based on team.
switch(temp)
{
case 1:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexR,ScreenWidth,ScreenHeight,FourNotTwo)); break;
case 2:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexG,ScreenWidth,ScreenHeight,FourNotTwo)); break;
case 3:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexB,ScreenWidth,ScreenHeight,FourNotTwo)); break;
case 4:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexY,ScreenWidth,ScreenHeight,FourNotTwo)); break;
}
AllPlayers[CurrentPlayers-1].SetTeam(temp);
}
}
}
//else 2 players
else
{
//set up 2 players
for(int i =0; i<2; i++)
{
//increase current Player counter; for player ID use
CurrentPlayers++;
//Set that player to a team based on his ID.
//(CurrentPlayers%2) so even players are team 1 and odd players are team 2
temp = CurrentPlayers%2;
//swap it so players are on correct team
if(temp == 0)
temp = 1;
else
temp = 0;
temp+=1;
switch(temp)
{
case 1:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexR,ScreenWidth,ScreenHeight,FourNotTwo)); break;
case 2:
//create a player whom will get the ID of the Currentplayers-1
AllPlayers.push_back(Player(CurrentPlayers,PaddleTexB,ScreenWidth,ScreenHeight,FourNotTwo)); break;
}
//add one to team number to state teams are 1 and 2
AllPlayers[CurrentPlayers-1].SetTeam(temp);
}
}
}
void PlayerManager::DeleteAllPlayer(HGE *_hge)
{
for(int i=CurrentPlayers-1; i>=0; i--)
{
//calls delete on the last enterd Player
AllPlayers[i].Delete();
//removes the last Player added to the vector
AllPlayers.pop_back();
}
//remove all Player from the counter
CurrentPlayers= 0;
_hge->Texture_Free(PaddleTexR);
_hge->Texture_Free(PaddleTexG);
_hge->Texture_Free(PaddleTexB);
_hge->Texture_Free(PaddleTexY);
}
void PlayerManager::DeletePlayer()
{
//calls delete on the last enterd Player
AllPlayers[CurrentPlayers-1].Delete();
//removes the last Player added to the vector
AllPlayers.pop_back();
//remove a Player from the counter
CurrentPlayers--;
}
float PlayerManager::X(int ID)
{
//return a given Player X pos
return AllPlayers[ID].GetX();
}
float PlayerManager::Y(int ID)
{
//return a given ball Y pos
return AllPlayers[ID].GetY();
}
//where BallVec() returns a vector<Ball> from a BallManager called BallMgr
// there by sending the vector<Ball> AllBalls to PlayerMgr.Update() to be used...but its flagged as undefined identifier
so in BallManager.cpp I call Add() and adds function call will push_back.(Ball()); onto vector.
this gives me a vector<Ball> with up to 4 balls (a limit chosen else where)
as i said i then return this vector<Ball> AllBalls in BallsVec(). so that i can access it elsewhere.
Yeah, okay, but where are you declaring Ball? What you just said is a use of the class, not a declaration. The code needs to see the declaration in order to use the class.
maybe you can show me an example of what your asking so i can respond with exact details.
as im not sure what your looking for.
there is never a point where i say something like Ball aball = new ball(); the only case when i actually try to create a ball is when im adding it to the vector such as AllBalls.pushback(ball(x,x,x,x));
or are you asking me about the actual definition of the Ball class?
i can post you that file.....Ball.cpp and .h coming up.
//Balls current color (to change by last player touched)
DWORD BallCol;
bool DrawBall;
};
/*
** Ball.cpp
*/
#include "Ball.h"
// this will create a ball either in the center of the screen or at the desired location(usually another ball location)
Ball::Ball(int CurrentBalls,float x,float y, HTEXTURE _BallTex) // can get starting pos for ball
{
//assign the ball an idea based on the number of balls we have
BallID = CurrentBalls-1;
BallCol = 0XFFFFFFFF;
BallTex = _BallTex;
//set up ball sprite
BallSpr= new hgeSprite(BallTex,0,0,32,32);
BallSpr->SetColor(0XFFFFFFFF);
BallSpr->SetHotSpot(16,16);
DrawBall = true;
if( BallID > 0 ) // if not the first ball
{
//start at last created ball x position
xPos = x+16;
//start at last created ball y position
yPos = y+16;
}
else // if first ball
{
//start center of screen X
xPos = 640;
//start center of screen Y
yPos = 384;
}
//prepare random number
srand((unsigned)time(0) + BallID); //init seed
//random x and y speed
float RandX = (float)(((rand()%100))*0.1f);
float RandY = (float)(((rand()%100))*0.1f);
//random if they are negative or positive
int RandNeg = (rand()%2);
// if 1 then direction is negative
if (RandNeg >0)
RandX *= -1.0f;
RandNeg = (rand()%2);
//if new number is 1 then direction is negative
if (RandNeg >0)
RandY *= -1.0f;
//determine initial speed of the ball
xSpd = RandX; // set the x speed with the new random speed
ySpd = RandY; // set the y speed with the new random speed
}
// sets color based on player who hit ball.
BallSpr->SetColor(BallCol);
xSpd = xSpd * 0.98f;
xPos += xSpd;
ySpd = ySpd * 0.98f;
yPos += ySpd;
CollisionCheck(AllBalls);
}
void Ball::CollisionCheck(vector<Ball> & AllBalls)
{
//do collision detection on the walls
//
// if outside right wall
if(xPos>1200)
{
//check right wall above goal
if(yPos < 285)
{
//reflect
{xPos=1200-(xPos-1200);xSpd=-xSpd;}
}
//check right wall below goal
else if(yPos > 483)
{
//reflect
{xPos=1200-(xPos-1200);xSpd=-xSpd;}
}
//otherwise its in the goal...score
else
{
//last player to touch gets score
//dont draw the ball
DrawBall = false;
//remove the ball
}
}
// if outside left wall
if(xPos<80)
{
//check left wall above goal
if(yPos < 285)
{
//reflect
{xPos=80+(80-xPos);xSpd=-xSpd;}
}
//check left wall below goal
else if(yPos > 483)
{
//reflect
{xPos=80+(80-xPos);xSpd=-xSpd;}
}
//otherwise its in the goal...score
else
{
//last player to touch gets score
//dont draw the ball
DrawBall = false;
//remove the ball
}
}
// if outside bottom wall
if(yPos>688)
{
//check bottom wall left of goal
if(xPos < 541)
{
//reflect
{yPos=688-(yPos-688);ySpd=-ySpd;}
}
//check bottom wall right of goal
else if(xPos > 739)
{
//reflect
{yPos=688-(yPos-688);ySpd=-ySpd;}
}
//otherwise its in the goal...score
else
{
//last player to touch gets score
//dont draw the ball
DrawBall = false;
//remove the ball
}
}
// if outside top wall
if(yPos<80)
{
//check top wall left of goal
if(xPos < 541)
{
//reflect
{yPos=80+(80-yPos);ySpd=-ySpd;}
}
//check top wall right of goal
else if(xPos > 739)
{
//reflect
{yPos=80+(80-yPos);ySpd=-ySpd;}
}
//otherwise its in the goal...score
else
{
//last player to touch gets score
//dont draw the ball
DrawBall = false;
//remove the ball
}
}
//do collision detection with other balls
//create a few usfull vars
float X,X2,Xs,Y,Y2,Ys,Dist,Temp;
//for each ball
for(int i=0; i<(signed)(AllBalls.size()-1); i++)
{
//if not our current ball
if(BallID != AllBalls[i].ID())
{
//check for collision with this ball
// get the distance between the balls at their edges
// X's are equall to center of ball
X = xPos;
X2 = AllBalls[i].GetX();
// Y's are equall to center of ball
Y = yPos;
Y2 = AllBalls[i].GetY();
//x2-x1
Xs = (X2-X);
//sqred
Xs *= Xs;
//y2-y1
Ys = (Y2-Y);
//sqred
Ys *= Ys;
//add um up
Dist = Xs + Ys;
//square root
Dist = sqrt(Dist);
// is that distance less then the radius of both circles? (16+16 32 for both)
if( Dist < 32.0)
{
//then we have collision
//increase distance of each object by 8 from eachother totaling 16 in seperation(to account for lag in detection.)
if( xPos > AllBalls[i].GetX())
{
//increase the farther
xPos+=8;
//decrease the closer
AllBalls[i].SetX(-8);
}
else
{
//increase the farther
AllBalls[i].SetX(8);
//decrease the closer
xPos-=8;
}
//now for Y
//increase distance of each object by 8 from eachother totaling 16 in seperation(to account for lag in detection.)
if( yPos > AllBalls[i].GetY())
{
//increase the farther
yPos+=8;
//decrease the closer
AllBalls[i].SetY(-8);
}
else
{
//increase the farther
AllBalls[i].SetY(8);
//decrease the closer
yPos-=8;
}
// swap X and y speeds (transition the energy of faster to slower
Temp = xSpd;
xSpd = AllBalls[i].GetDX();
AllBalls[i].SetDX(Temp);
Temp = ySpd;
ySpd = AllBalls[i].GetDY();
AllBalls[i].SetDY(Temp);
}
//else no collision so do nothing and check next ball.
}
}
}
void Ball::Delete()
{
//delete this balls sprite (for mem management)
delete BallSpr;
}
void Ball::SetColor(DWORD _BallCol)
{
//changes the color of a given ball via input
BallCol = _BallCol;
}
float Ball::GetX()
{
//return this balls X position
return xPos;
}
void Ball::SetX(float value)
{
//set this balls X position
xPos += value;
}
float Ball::GetY()
{
//return this balls Y position
return yPos;
}
void Ball::SetY(float value)
{
//Set this balls Y position
yPos+=value;
}
float Ball::GetDX()
{
//return this balls X speed
return xSpd;
}
void Ball::SetDX(float value)
{
//set this balls X speed
xSpd = value;
}
float Ball::GetDY()
{
//return this balls Y position
return ySpd;
}
void Ball::SetDY(float value)
{
//set this balls Y speed
ySpd = value;
}
int Ball::ID()
{
//return this balls ID
return BallID;
}
i know your not. i made the mistake of thinking i already pasted up ball.H and Ball.Cpp which is why i was confused about your request.
it was my error in thinking so.
at anyrate
TouchDemo includes BallManager.h and PlayerManager.h
BallManager.h includes Ball.h
PlayerManager.h includes Player.h
if i try to include BallManager.h or Ball.h in my player.h or PlayerManager.h
i get like 50 errors saying im trying to redefine the Ball and player and playermanager and ballmanager classes