I have a question about a XNA game I'm making, but it is also a generic question for future games. I'm making a Pong game and I don't know exactly what to update where, so I'll explain better what I mean. I have a class Game, Paddle and Ball and, for example, I want to verify the collisions between the ball with the screen limits or the paddles, but I come across 2 approaches to do this:
Higher Level Approach - Make paddle and ball properties public and on the Game.Update check for collisions?
Lower Level Approach- I supply every info I need (the screen limits and paddles info) to the ball class (by parameter, or in a Common public static class) and on the Ball.Update I check for collisions?
I guess my question in a more generic way is:
Does an object need to know how to update and draw itself, even having dependencies from higher levels that somehow are supplied to them?
or
Is better to process it at higher levels in Game.Update or Game.Draw or using Managers to simplify code?
I think this is a game logic model question that applies to every game. I don't know if I made my question clear, if not, feel free to ask.
The difficult part of answering your question is that you're asking both: "what should I do now, for Pong" and "what should I do later, on some generic game".
To make Pong you don't even need Ball and Paddle classes, because they're basically just positions. Just stick something like this in your Game class:
Then just update and draw them in whatever order suits you in your Game's
Update
andDraw
functions. Easy!But, say you want to create multiple balls, and balls have many properties (position, velocity, rotation, colour, etc): You might want to make a
Ball
class or struct that you can instance (same goes for the paddles). You could even move some functions into that class where they are self-contained (aDraw
function is a good example).But keep the design concept the same - all of the object-to-object interaction handling (ie: the gameplay) happens in your
Game
class.This is all just fine if you have two or three different gameplay elements (or classes).
However let's postulate a more complicated game. Let's take the basic pong game, add some pinball elements like mutli-ball and player-controlled flippers. Let's add some elements from Snake, say we have an AI-controlled "snake" as well as some pickup objects that either the balls or the snake can hit. And for good measure let's say the paddles can also shoot lasers like in Space Invaders and the laser bolts do different things depending on what they hit.
Golly that is a huge mess of interaction! How are we going to cope with it? We can't put it all in Game!
Simple! We make an interface (or an abstract class or a virtual class) that each "thing" (or "actor") in our game world will derive from. Here is an example:
(This is only an example. There is not "one true actor interface" that will work for every game, you will need to design your own. This is why I don't like
DrawableGameComponent
.)Having a common interface allows Game to just talk about Actors - instead of needing to know about every single type in your game. It is just left to do the things common to every type - collision detection, drawing, updating, loading, unloading, etc.
Once you're in the actor, you can start worrying about specific types of actor. For example, this might be a method in
Paddle
:Now, I like to make the Ball bounced by the Paddle, but it is really a matter of taste. You could do it the other way around.
In the end you should be able to stick all your actors in a big list that you can simply iterate through in Game.
In practice you might end up having multiple lists of actors of different types for performance or code simplicity reasons. This is ok - but in general try to stick to the principle of Game only knowing about generic actors.
Actors also may want to query what other actors exist for various reasons. So give each actor a reference to Game, and make the list of actors public on Game (there's no need to be super-strict about public/private when you're writing gameplay code and it's your own internal code.)
Now, you could even go a step further and have multiple interfaces. For example: one for rendering, one for scripting and AI, one for physics, etc. Then have multiple implementations that can be composed into objects.
This is described in detail in this article. And I've got a simple example in this answer. This is an appropriate next step if you start finding that your single actor interface is starting to turn into more of a "tree" of abstract classes.
I agree with what Andrew said. I am just learning XNA as well and in my classes, for example your ball class. I'd have an Update(gametime) method and a Draw() method in it at the least. Usually an Initialize(), Load() as well. Then from the main game class I will call those methods from their respective cousins. This was before I learned about GameComponent. Here is a good article about if you should use that. http://www.nuclex.org/blog/gamedev/100-to-gamecomponent-or-not-to-gamecomponent
You could see your ball and paddle as a component of your game, and XNA gives you the base class
GameComponent
that has anUpdate(GameTime gameTime)
method you may override to do the logic. Additionally, there is also theDrawableGameComponent
class, which comes with its ownDraw
method to override. EveryGameComponent
class has also aGame
property which holds the game object that created them. There you may add some Services that your component can use to obtain information by itself.Which approach you want to make, either have a "master" object that handles every interaction, or provide the information to the components and have them react themselves, is entirely up to you. The latter method is preferred in larger project. Also, that would be the object-oriented way to handle things, to give every entity its own Update and Draw methods.
You could also opt to start thinking about how different components of the game need to talk to each other.
Ball and Paddle, both are objects in the game and in this case, Renderable, Movable objects. The Paddle has the following criteria
It can only move up and down
The ball has the following criteria
It cannot leave the boundaries of the screen
Identifying the common criteria you can extract an interface
You also have some GamePhysics
Then there is some game logic
This is not all the logic, but it should give you an idea of what to look for, because you are building a set of Libraries and functions that you can use to determine what is going to happen and what can happen and how you need to act when those things happen.
Also, looking at this you can refine and refactor this so that it's a better design.
Know your domain and write your ideas down. Failing to plan is planning to fail