I'm trying to design a simple game ---Pong, Arkanoid--- using strictly "Proper OO", whatever that means.
So, by designing myself to death, I'm trying to get to a point where I'll know what to do or not do next time...
Who should handle, for example, colissions? And scorekeeping?
My first idea was giving a couple jobs to the ball, but that started expanding exponentially into a god object: The ball'd know where it is, who it crashed into, and report to the scorekeeping objects.
And that's too much for the poor ball.
rule of thumb:
if an object logically owns all of the state involved, then it owns the methods that use that state
if a method requires state from more than one object:
if a container object owns all of the objects used by the method, then it owns the method, too
otherwise you need a 'bridge' object to own the utility method
unless there is a strong argument for one object to be the 'controller' for the method (can't think of an example offhand though)
in your case, the 'gameboard' or 'game environment' would probably have a 'game physics' class (or group of methods) that owned the collision-detection (utility/bridge) methods
A good or bad design reveals itself by how well it accomodates unexpected requirements, so I would suggest keeping a stock of potential "game features" handy to inform your design reflexions. Since you're doing this as a learning project you can afford to go crazy.
Arkanoid is a very good choice for this, it offers so many options. Make different bricks score different amounts of points. Make some bricks change the score of other bricks when hit. Make some bricks require multiple hits. Give superpowers to the ball, paddle, or bricks. Vary these powers: one of them makes the ball keyboard-controllable, another makes it transparent, another reverses "gravity", and so on. Make bricks drop objects.
The goal is that when you make such a change, it impacts the minimum possible number of classes and methods. Get a feel for how your design must change to fit this criterion.
Use an IDE that has a Refactoring menu, in particular the move method refactoring. (If you haven't, read the book Refactoring.) Experiment with placing your various methods here and there. Notice what becomes hard to change when the method is placed "wrong", and what becomes easier when you place it elsewhere. Methods are placed right when objects take care of their own state; you can "tell" an object to do something, rather than "ask" it questions about its state and then make decisions based on its answers.
Let's assume that in your design each sprite is an object instance. (You could choose other strategies.) Generally, motion alters the state of a sprite, so the method that describes motion for a particular kind of sprite probably belongs on that sprite's class.
Collision detection is a sensitive part of the code, as it potentially involves checking all possible pairs of sprites. You'll want to distinguish checking for collisions and informing objects of collisions. Your ball object needs to alter its motion on colliding with the paddle, for instance. But the algorithm for detecting collisions in general won't belong on the ball class, since other pairs of objects may collide with consequences that matter to the game.
And so on...
Keep in mind that objects can also exist for logical elements of a given problem (not only real elements, like balls and boards).
So for collision detection, you could have a CollidingElement class that handles the position and shape states. This object can then be embedded by composition in any object that should collide in the game and delegate any needed method call to it.
It really depends on your implementation, but I imagine you'd have a "gameboard" object to manage score keeping, or maybe a goal object on each side. As far as collisions I think you might want to pass events between the objects. I think any object should know its location though.
in most games you have statics and actors . .. actors move around and each of them independently figures out when they collide with something since they are aware of their shape and extents
Related
I have been trying to get my head around this problem for the last week and can't seem to find a solution that doesn't either require a singleton or tight coupling.
I am developing a 3D space game, an early demo of which is here...
www.sugarspook.com/darkmatters/demo.html
... and I'm getting to the point of adding Missions which the player will be able to select from the heads up display (Hud class).
The structure of the game is:
The Game class contains the Hud and the ObjectsList class.
The ObjectsList class contains various game Objects, including the Player, the various kinds of ship, planets, and Orbitals (space stations).
Missions get instantiated when the Player gets to within a certain distance of an Orbital.
Missions are added to a MissionsList class, itself within the ObjectsList.
Missions can become unavailable and expire without warning (as if they are selected by another pilot) so the list displayed on the Hud is dynamic and updated regularly.
Previously I've had the Missions dispatching events up to Game which in turn informs Hud of the change. This seems a little clunky to me, as there are various deeper 'levels' to the Hud that the information needs to be passed down to. I end up with a lot of the same functions all the way down the chain.
The solution I was thinking of involved injecting a reference to the MissionsList class into the Hud, enabling it to listen for updates from the Missonslist. I've heard that it's bad practise to mix the state of something with its display, but I don't see how else to get the 'live' list of Missions to the Hud. In contrast, if the Hud contains only display details without reference to the Mission object that generated those details, when a player selects a Mission from the Hud how can I determine which Mission has been chosen?
Is tight coupling in this case OK? Or should I use a singleton to communicate to the Hud?
If there is something fundamentally wrong with anything I'm suggesting I welcome being told what that is and what is the best solution.
Thanks.
Well the simple answer is why not couple via an intermediate interface?
interface IMissionList
{
ObservableCollection<IMission> Missions{get;}
}
Then in your Dependency Injection bind that to something that can resolve to a instance, singleton or constant or etc...
then inject it into your Hud's constructor
Hud(IMissionList missionList){}
Now you are loosely coupled to a contract, the implementation of-which can be changed at any point, so long as the implementation adheres to the contract. Also, due to injection your Hud only has to concern it self with using IMissionList rather than also finding it.
[Edit] Sorry, this is C#, but hopefully the idea is of use. See for actionscript interfaces and Dependency Injection for Actionscript
What are the pros and cons of using a singleton class for sound management?
I am concerned that it's very anti-OOP in structure and don't want to potentially get caught up going down the wrong path, but what is a better alternative?
It's an awkward topic but I'd say that a sound manager style class is a good candidate for a class that should not be initialized.
Similarly, I would find it OK if a keyboard input manager style class was a completely static class.
Some notes for my reasoning:
You would not expect more than one instance that deals with all sounds.
It's easily accessible, which is a good thing in this case because sound seems more like an application-level utility rather than something that should only be accessed by certain objects. Making the Player class for a game static for example would be a very poor design choice, because almost no other classes in a game need reference directly to the Player.
In the context of a game for example, imagine the amount of classes that would need a reference to an instance of a sound manager; enemies, effects, items, the UI, the environment. What a nightmare - having a static sound manager class eliminates this requirement.
There aren't many cases that I can think of where it makes no sense at all to have access to sounds. A sound can be triggered relevantly by almost anything - the move of the mouse, an explosion effect, the loading of a dialogue, etc. Static classes are bad when they have almost no relevance or use to the majority of the other classes in your application - sound does.
Anyways; that's my point of view to offset the likely opposing answers that will appear here.
They are bad because of the same reasons why globals are bad, some useful reading :
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
A better alternative is to have it as a member of your application class and pass references of it to only modules that need to deal with sound.
"Managers" are usually classes that are very complex in nature, and thus likely violate the Single Responsibility Principle. To paraphrase Uncle Bob Martin: Any time you feel yourself tempted to call a class "Manager" of something - that's a code smell.
In your case, you are dealing with at least three different responsibilities:
Loading and storing the sounds.
Playing the sounds when needed.
Controlling output parameters, such as volume and panning.
Of these, two might be implemented as singletons, but you should always be very careful with this pattern, because in itself, it violates the SRP, and if used the wrong way, it causes your code to be tightly coupled (instead, you should use the Dependency Injection pattern, possibly by means of a framework, such as SwiftSuspenders, but not necessarily):
Loading and storing sounds is essentially a strictly data related task, and should thus be handled by the SoundModel, of which you only need one instance per application.
Controlling output parameters is something that you probably want to handle in a central place, to be able to change global volume settings, etc. This may be implemented as a singleton, but more likely is a tree-like structure, where a master SoundController handles global settings, and several child SoundControllers are responsible for more specific contexts, such as UI sound effects, game sounds, music, etc.
Playing the sound is something, which will occur in many places, and in many different ways: There may be loops (to which you need to keep references to be able to stop them later), or effect sounds (which are usually short and play only once), or music (where each song is usually played once, but needs subsequent songs to be started automatically, when the end is reached). For each of those variations (and whichever ones you come up with), you should create a different class, which implements a common SoundPlayer interface, e.g. LoopSoundPlayerImpl, SequentialSoundPlayerImpl, EFXSoundPlayerImpl, etc. The interface should be as simple as play(),pause(), rewind() - you can easily exchange those later, and will not have any problems with tightly coupled libraries.
Each SoundPlayer can hold a reference to both the master SoundController an its content-specific one, as well as - possibly - the SoundModel. These, then can be static references: Since they are all parts of your own sound plugin, they will usually be deployed as a package, and therefore tight coupling won't do much damage here - it is important, though, not to cross the boundary of the plugin: Instantiate everything within your Main partition, and pass on the instances to all classes, which need them; only have the SoundPlayer interface show up within your game logic, etc.
I'm looking to get some good books on design patterns and I'm wondering what particular pattern you'd recommend for a Realtime Strategy Game (like Starcraft), MVC?.
I'd like to make a basic RTS in Flash at some point and I want to start studying the best pattern for this.
Cheers!
The problem with this kind of question is the answer is it completely depends on your design. RTS games are complicated even simple ones. They have many systems that have to work together and each of those systems has to be designed differently with a common goal.
But to talk about it a little here goes.
The AI system in an rts usually has a few different levels to it. There is the unit level AI which can be as simple as a switch based state machine all the way up to a full scale behavior tree (composite/decorators).
You also generally need some type of high level planning system for the strategic level AI. (the commander level and the AI player)
There are usually a few levels in between those also and some side things like resource managers etc.
You can also go with event based systems which tie in nicely with flash's event based model as well.
For the main game engine itself a basic state machine (anything from switch based to function based to class based) can easily be implemented to tie everything together and tie in the menu system with that.
For the individual players a Model-View-Controller is a very natural pattern to aim for because you want your AI players to be exposed to everything the human player has access to. Thus the only change would be the controller (the brain) without the need for a view obviously.
As I said this isn't something that can just be answered like the normal stackoverflow question it is completely dependent on the design and how you decide to implement it. (like most things) There are tons of resources out there about RTS game design and taking it all in is the only advice I can really give. Even simple RTS's are complex systems.
Good luck to you and I hope this post gives you an idea of how to think about it. (remember balance is everything in an RTS)
To support lots of units, you might employ Flyweight and Object Pool. Flyweight object can be stored entirely in a few bytes in a large ByteArray. To get usable object, read corresponding bytes, take empty object and fill it with data from those bytes. Object pool can hold those usable objects to prevent constant allocation/garbage collection. This way, you can hold thousands of units in ByteArray and manage them via dozen of pooled object shells.
It should be noted that this is more suitable to store tile properties that units, however — tile are more-or-less static, while units are created and destroyed on regular basis.
It would be good to be familiar with a number of design patterns and apply them to the architecture of your game where appropriate.
For example, you may employ an MVC architecture for your overall application, factory pattern for creating enemies, decorator pattern for shop items, etc. Point being, design patterns are simply methodologies for structuring your objects. How you define those object and how you decide how they fit together is non prescriptive.
So my question isn't about the how-to of collision detection, but is more of a broad 'what code should own collision detection'. I've written some game in the past(relatively simple 2D Flash games) and it got me thinking of which code should own collision detection?
Let me clarify - say in a game I have a group of enemies and a group of projectiles the player has fired. So in the past I've had say an EnemyManager class, that every frame updates the positions of the enemies and likewise for the player projectiles had a PlayerProjectilesManager class that moved around the bullets. That's cool - everything is fine and dandy. But then, I decide I want the bullets to affect the enemies(crazy I know!). So that means somewhere in the code I need to:
Figure out which bullets and enemies are colliding(I don't care how for this question)Figure out the response to each collision
So basically what I've done in the past is just have the EnemyManager class take 'ownership' of the collisions, and during its update loop it finds the player bullets that collide with enemy bullets(i.e. Step 1) and also calls code for both objects to handle the collision (e.g. the enemy losses health, the bullet disappears) (i.e. Step 2). So I've given control of the collision detection and collision 'reaction' to the EnemyManager.
A couple comments about that:
It feels vary arbitrary to me that the EnemyManager is in 'control' instead of the PlayerProjectilesManager
Both collision detection and collision 'reaction' are handled by the same owner, this isn't a requirement from my point of view
What's forming in my mind is a 3rd party entity managing collision detection. For instance have a CollisionManager which has code that know's which other Managers need to have collisions detected. That leads to other questions like what interfaces do the 'Managers' need to expose for efficient collision detection without exposing too many innards to the CollisionManager. Then I suppose the CollisionManager what broadcast some sort of an event, containing which 2 objects collided etc... and perhaps the EnemyManager/PlayerProjectilesManager could separately listen for these events and react accordingly and separately. Starting to make sense in my mind. :)
Thoughts? Almost every game has collision detection, so I'm sure this has been discussed before. :)
this is a nice question. Personally, I would not complicate it so much by using "Managers". Let's say we have a GameEngine, which runs the game in its main loop. This main loop could consist of 3 steps: get the user input, update the state of all objects in the game (based on the user input) and finally draw everything again on the screen.
Everything about the collision detection is done in the second step - when updating the objects' state. Let's say all objects in the game are stored in a pool. This includes the player, the bullets, the enemies and even the world (if you'd like the world to be affected as well somehow). All the different objects could have some common properties - they could be Drawable, Movable, Collidable e.t.c. (think like implementing an interface or extending a base class to have these properties)
For each of these properties I would have a class that do something with all the objects in the pool. Like Mover.moveAll(objectsFromPool). This will move all objects, which are Movable.
The same for collision detection -> after we've relocated the objects with the Mover, then we check for collision with CollisionDetector.cehckAll(objectsFromPool). This checkAll() method will do the actual collision detection between the objects themselves, knowing their coordinates. If an object is Collidable, the CollisionDetector will invoke its method onCollide(withOtherObject) and then the object itself reacts properly, depending what other object hit it. Let's say, if the player is touched by the enemy body, they will both step back for example. If a bullet is hits by another bullet - they will both be marked for deletion. If the enemy is hit by a bullet, then some damage will happen and the bullet will be marked for deletion. All these reactions should be in the corresponding objects themselves.The collision detector applies its algorithms to detect collision between any two objects and then invokes their onCollide(withOtherObjct) method.
If an object is not Collidable, it will be simply ignored by the CollisionDetector (for examples rain particles or dust are not Collidable).
I hope I managed to express myself correct :)
Questions specific to game development are best suited to https://gamedev.stackexchange.com/ by the way.
So in the past I've had say an EnemyManager class
I consider any SomethingManager class to be a sign that your code isn't organised accurately yet. For the most part, objects should manage themselves. If they can't, that implies there is some external information about them, and that information probably has a representation more specific than 'manager'. 3 game-specific examples might be GameWorld, GameRegion, or GameLevel. Enemies exist within a world, or a region of the world, or a current game level, so have such an object maintain its list of enemies.
and likewise for the player projectiles had a PlayerProjectilesManager class
Projectiles too would live in some sort of game space, a world, region, or level.
By now, you can probably guess that one of the above objects can (and probably should) be responsible for owning all the above objects (perhaps indirectly, via a container class, but not via a heavyweight manager of any sort) and responsible for detecting collisions and resolving them.
I am a student with a mainly electronics background getting into programing. The more I get into it, the more I realize how bad I am at it.
I am trying to get better at OO design.
One thing I have been reading about is the use of Getters and Setters.
http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1
http://typicalprogrammer.com/?p=23
Now I can see the point they are making here but I am still unable to see away around some simple problems. And this brings me to my question (finally). I am setting up a simple tower defense game in AS3 as a learning exercise. I want enemies to follow way points so I was going to make an array of way points, and make that a property of a map object. And a way point was to be an object with an x and a y property (more like a struct). Now I can see that this is exactly the sort of bad practice that the articles are discouraging but I can't seem to think of a better way to do this. Any help from some of you guys with a bit more experience would be much appreciated.
Firstly generalise; whilst you are currently wanting enemies to follow waypoints it seems to me that what you have is a specific instance of the map determining where something moves.
Let's call enemies an instance of "GameEntity" (possibly MoveableGameEntity).
What you should be doing is to tell the map to manage the relevant GameEntities, and then the Map can keep a list of these objects and move them as needed.
Code fragments.
interface MoveableGameEntity
{
void positionNotify(Position new_postition);
};
public class Barbarian implements MoveableGameEntity
{
void positionNotify(Position new_postition)
{
// do something
}
};
// during initialisation.
map.Add(new Enemy("Barbarian 1"));
map.Add(new Enemy("Barbarian 2"));
//during map processing
Position new_position = new Position();
for (MoveableGameEntityList moveable : moveable_game_entity_items)
{
new_position = get_new_posistion(moveable);
item.moveTo(new_position);
moveable.positionNotify( new_position );
}
The map will need to have a method get_new_position(MoveableGameEntity ge) which will determine the new posisiton and the enemies will only be told their new posistion via the positionNotify method.
The MoveableGameEntityList is an object that will tie together a game entity and it's position. This way the game entity doesn't contain any position information and this is managed by another object.
Okay, heavy assumptions follow: I think you're thinking far too much about efficiency. OO coding isn't about efficiency. It's about elegant design. It's about minimizing side-effects from external factors and protecting internal state. This is why compilers "optimize." You should be thinking about maintainability and difficulty of coding primarily. The amount of lines you write might well be greater than non-OO code. That's not the point.
Try to think about your "objects" as tangible items that communicate with each-other. This communication is a protocol (includes method signatures). The language you "speak" to one another. Make it simple and unambiguous. Never assume that any object has the power to manipulate another beyond its ability to communicate a suggestion or request (encapsulation).
Don't just add getters and setters to everything without purpose. You'll miss the entire point and might as well be coding in another style. Protect internal state. Getters & setters on everything simply means, that you'll have a universally inefficient implementation. Setters & getters are gatekeepers. Nothing more. Eliminate them if they don't make sense. Use them where they do. Never allow something else to screw with your internal state. It'll create chaos.
When writing games, these practices fall down, but they're not to be abandoned. Optimize your critical loops & choke points. Keep your original code for reference & as a mirror-image model of your optimized code. Take the shortcuts you need and nothing more. Optimization must always come last... even in the face of an obviously inefficient, yet thoughtful, design.
Many ex-Java coders I've worked with put setters & getters on attributes unnecessarily (every attribute). This is simply what they're accustomed to. No benefit in 9 of 10 of cases, but they were insistent on this pattern. The impact was always negligible (50k users per minute... of course, not using Java... but still). The total impact of getters & setters is minimal in a high-level design. Lower level, as in video CODECs or OpenGL, it's huge.
You can choose to adopt them without thinking, or implement them with applicability in mind. You will find many professors telling you that you're "wrong" because you omitted them. Keep your coursework expectations in mind. :)
I prefer not to see this as bad habits vs good habits, but rather a shift in paradigm. Unfortunately, it's not as simple as just flipping a switch. It's something that happens gradually as you get more and more experienced with a different way of looking at things.
The best advice I can give you is to just start coding. A lot.
A bit unrelated, but if you want to get into OO design I have 2 v. good books for you, easy to understand & grasp.
Head First: OOAD
Head First: Design Patterns