Hi; this might seem a silly thing to ask, but I'm wondering what's the best way to solve this issue:
Currently, I have four classes: Actor, Monster, Player, and Projectile. The latter three all inherit from Actor, because it makes intuitive sense that a Monster 'is an' Actor, etc. Inside the main program, I have a List of Actor*. What I'd like to do is run through the List some number of times per second, calling update() and draw() on each Actor (where update() is virtual, of course). This will update all of the actors, then redraw all of the updated actors.
However, the update() function for a Player is different from that of a Monster and Projectile; Player's update() is passed in an additional 2-dimensional vector (not the data structure) telling it where it wants to go (calculated from the input to the keyboard/mouse, which is handed by the main program), while Monster's and Projectile's update() lack this argument, because it doesn't seem to make sense that any input on my end should directly influence them. But if the argument lists are different, wouldn't that make them two different functions - in which case, it's not quite as simple as just doing actor.update() for each actor?
It seems like one way I could fix it is by making the vector be a default argument in the base class and completely disregarding it in all non-Player classes. But I'm not sure if this is a standard approach to the problem. I could also completely dispose of the virtual method, and write non-virtual update() functions for each class. Or I could break the parent/child link between Actor and Player and make Player its own separate class. Or I could, before updating, update a vector in Player that tells it where I want to go, so that it doesn't need the extra argument (this would probably require me to keep pointers to all the Player(s) in the game). Given that I've never used polymorphism before, and that I could have possibly gotten this entire situation wrong, I'd like to ask: Firstly, is this a valid problem? If so, what's the most acceptable way to go about solving this problem?
As described, Actor is someone who can be told to update() itself, and Player is not someone who can be told to update() itself, therefore Player is not an Actor, public inheritance would be an error.
How is that vector produced? If it's something only Players should receive, why isn't it sent to Players only? If it's something that is derived from input, why is it distributed to the objects on screen refresh and not on input?
The vector is produced in the main program through examination of the current keyboard state; the y-component of the vector is 1 when the 'down' key is down and the 'up' key is up, for example. Although it's not sent to Players only in the current form of the code, one possible fix could make it so. I'm just not sure if that fix, or another fix, would be better; from your post, I suppose the best way would be to simply make Player its own class. The main loop (so far) runs as follows:
1 2 3 4
while(game isn't closed){
update();//calls all the update() functions of each Actor
draw();//calls all the draw() functions of each Actor
}
So all the updating (with the input) happens first, then the drawing occurs.
What does Actor::update() do? I am guessing it updates the coordinates and other state of the Actor based on the current time and its previous state (velocity, angular momentum, etc)?. If so, Players can do that just as well, so they are Actors.
What I am suggesting is decoupling keyboard input from scene refresh, those are different kinds of information. Players can receive the keyboard state updates on their own, either it's sent to them (e.g. they register themselves in Player::Player() as receivers of keyboard input, and if there are many Actors that do that, they can all be KeyboardListeners), or they can ask for it from within Player::update(), if they are told, at construction time, what object to poll.
That should be pretty much all that it does, exactly as you described it.
Hmm, that sounds like a good idea. I hadn't thought of keeping the keyboard seperate from the manager class that did all the grunt work. Doing as you say definitely sounds like it'll fix my problem, since I won't need to pass in that vector anymore.