All the objects in my game have inherit my Sprite class. Here's the hierarchy I'm using:
Sprite > StaticObject > MovingObject > Character > Player
I have written a function in my main game class that searches through all objects in the game and finds any "Player" objects. If a Player object is found, it prints to the screen the value of the object's speed (the v2Speed vector).
foreach (var gameObject in GameInfo.gameInfo.gameObjects)
{
if (gameObject.GetType() == typeof (Player))
{
string sPlayerPosition = string.Format("Player position: ({0:0.00},{1:0.00})", gameObject.v2Position.X, gameObject.v2Position.Y);
DrawWithShadow(sPlayerPosition, new Vector2(10, 60));
string sPlayerSpeed = string.Format("Player speed: ({0:0.00},{1:0.00})", gameObject.v2Speed.X, gameObject.v2Speed.Y);
DrawWithShadow(sPlayerSpeed, new Vector2(10, 80));
}
}
However, this only works if I put v2Speed in the base Sprite class. I assume that this is because the compiler wants to find the variable in every object that the game is searching through. I'm not sure why this is a problem because the code accessing v2Speed is only ever applied to a Player object, which will always have that vector defined. I really don't want to have v2Speed in any class higher than the MovingObject class, because the Sprite and StaticObject objects will never move once the game starts.
My question is how do I rewrite the code above to access v2Speed if it is stored in the MovingObject class instead of the Sprite class?
The compiler only knows that gameObject
is of type Sprite
(I assume; it's hard to tell for sure). Your if
condition doesn't change that.
Instead, you can use:
if (gameObject is Player player)
{
// Now use player instead of gameObject
}
Note that this requires C# 7. If you're only using C# 6 or earlier, you'd use:
Player player = gameObject as Player;
if (player != null)
{
// ...
}
Note that this behaves slightly differently to your original code - if you had an object which was an instance of a subclass of Player
, it wouldn't be picked up in your original code, but would be in this code... which is probably what you want.
(The OfType<Player>
approach as per Codor's answer is a great alternative - although I'd then call the loop variable player
instead of gameObject
, given that you'd know it was a player...)
See more on this question at Stackoverflow