There are two ways to solve this.
If your game will only ever be single-player, then you will only ever have one Player. At that point, you can create a static, public field of Player called something like "Instance", and assign to that in the Player constructor:
public class Player
{
public static Player Instance;
public Player() {
Instance = this;
/* stuff */
}
}
At this point, you can always get to the current player by going through "Player.Instance"
If your game may be multi-player, or your enemies need to react to "things in the world" (whether they be player or not), then it's probably better to create a World object. Each object in the World registers itself (typically by implementing IWorldObject). An entity can then query the World for "things close enough to me to care about," and make whatever decision they want.
For example:
enum Alignment {
PlayerFriendly,
PlayerHostile
}
public interface IWorldObject {
Alignment Alignment { get; }
Vector3 Position { get; }
}
public class World {
public static World Instance = new World();
World() {}
List<IWorldObject> objects = new List<IWorldObject>();
public void AddObject(IWorldObject wo) ...
public void RemoveObject(IWorldObject wo) ...
public List<IWorldObject> GetObjectsNear(Vector3 pos, float radius) ...
}
The Player would then implement IWorldObject, set Alignment to PlayerFriendly, and add itself to the world.
The enemies would implement IWorldObject, set Alignment to PlayerHostile, and add themselves to the world.
When the enemies need to "react" to something in the world, they call World.Instance.GetObjectsNear(Position, radius), and iterate through those objects to see if there's any objects that are PlayerFriendly; if so, they know they are enemies thereof.
Jon Watte, Direct3D MVP
Tweets, occasionallykW X-port 3ds Max .X exporter
kW Animation source code