Hi all,
Running into a snag in my program. I can't seem to figure out how to have an object of a class be able to look at all the other objects of its own class.
Reasoning being, I'm working on a game with multiple ships flying around in the same space. Each ship is a class.
Each ship has an x and a y, and needs to compare the angle and distance of other ships' x and y coordinates to see if they're visible on the same screen.
The problem I'm running into is I have no idea how to tell an object to look at objects of its own class.
Here's some code:
common.h
1 2 3 4 5 6 7
#ifndef COMMON_H_INCLUDED
#define COMMON_H_INCLUDED
int dist(int x1, int y1, int x2, int y2);
int get_info(int which);
#endif
#include "player.h"
#include "common.h"
#include "math.h"
int Num_Players = 10;
bool quit = false;
int main()
{
Player play[10];
for (int i = 0; i < Num_Players; i++)
{
play[i].which_player = i;
}
return 0;
while (quit == false)
{
for (int i = 0; i < Num_Players; i++)
{
play[i].update();
}
}
}
int dist(int x1, int x2, int y1, int y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int get_info(int which)
{
switch (which)
{
case 0: return Num_Players; break;
}
}
player.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
class Player
{
public:
int x;
int y;
int which_player;
int closest_enemy;
Player();
void get_closest();
void update();
};
#endif
#include "player.h"
#include "common.h"
Player::Player()
{
x = rand() * 1000;
y = rand() * 1000;
}
void Player::get_closest()
{
int temp_dist = 1000000;
int who_closest = -1;
int enemy_dist;
for (int i = 0; i < get_info(0); i++)
{
if (which_player != i)
{
enemy_dist = dist (x, y, play[i].x, play[i].y);
if (enemy_dist < temp_dist)
{
temp_dist = enemy_dist;
who_closest = i;
}
}
}
closest_enemy = who_closest;
}
void Player::update()
{
get_closest();
}
Basically, I just don't know how to properly write a function, call, or how to get the info I need, to the Player::get_closest() function so that it can see the other play objects.
Any insight into this would be much appreciated. Thanks!
I can think of two options:
1. make get_closets take an argument an array of players. Check if not calculating distance from a player to itself
2. use a static variable as a member of the class.
Thanks for the ideas.
However, can you elaborate on the second option of using a static variable as a member of the class? I'm not quite sure how I could implement that or what it would do.
#include<iostream>
#include<cstdlib>
usingnamespace std;
class Player
{
public:
int x;
int ID;
int closest_enemy;
static Player *playerlist; //static member - contains the pointer to the list of players
staticint num_players; //static member - number of players
Player();
~Player();
void get_closest();
};
Player::Player()
{
x=rand()%25;
++num_players;
ID=num_players;
if (num_players==1)
playerlist=this; //for the first player the playerlist point to "this"
}
Player::~Player()
{
--num_players;
if (num_players==0)
playerlist=NULL;
}
void Player::get_closest()
{
int diff=100;
for (int i=0;i<num_players;i++)
{
if((playerlist+i)->ID!=ID)
{
int x_other=(playerlist+i)->x;
if (abs(x_other-x)<diff)
{
closest_enemy=(playerlist+i)->ID;
diff=abs(x_other-x);
}
}
}
}
//Initialize static members
int Player::num_players=0;
Player *Player::playerlist=NULL;
int main()
{
srand(10);
Player play[10];
cout<<"Number of players"<<play[0].num_players<<endl;
for (int i=0;i<10;i++)
cout<<"player "<<play[i].ID<<" position "<<play[i].x<<endl;
play[0].get_closest();
cout<<"closest to player "<<play[0].ID<<" is player "<<play[0].closest_enemy<<endl;
}
Thank you for that. I didn't know you could do that.
I was able to implement that and get it working. Plus, that should come in handy in the future. :)
As ats15 said, the static variable is a bit of a hack; but it will get the job done.
However, it's not very nice from an OO point of view...
You said:
[you have] multiple ships flying around in the same space. Each ship is a class. Each ship has an x and a y, and needs to compare the angle and distance of other ships' x and y coordinates
(Do you mean that each ship is an instance of class "Spaceship"?)
I think you are missing part of the model: space.
1 2 3 4 5 6
class Space {
public:
Spaceship* findClosestSpaceshipTo(const COORD& coord);
void reportLocation(Spaceship* ship, coord COORD& coord);
// etc
};
Aftr all, Space is the "container" of all the ships!
I think it might help if you expand your statement of the problem a bit, so it's clear what class does what. e.g. Your spaceship "must be able to search though space to find the nearest of the other ships."
And, if you're interested in design pattern, you could maybe look at the observer pattern.
Thanks for the reply. I'll definitely check out the observer pattern. It sounds intriguing.
And yes, I meant an instance of class Spaceship. :)
In this case, though, there is no container for the ships. Each ship simply has its own X and Y coordinate and other than that, about all they share is the bullets flying around. It simulates space by, whenever a player moves, stars streak in the background to show which direction their moving. That way, each ship is 100% contained and the only way they communicate with each other is by sharing the same array of bullets and being able to use radar to see each other's X & Y coordinates.
That is an interesting idea though, with making a class "Space" that reports the locations to each other. I might see if I can implement something like that.
It's been a fun project since I have a fully programmed, finished version of the game in another language (QB64), but it's not object oriented and is hard coded as 2 player.