I'll be as direct as I can concerning this problem, because there must be something I'm totally missing coming from a structured programming background.
Say I have a Player class. This Player class does things like changing its position in a game world. I call this method warp() which takes a Position class instance as a parameter to modify the internal position of the Player. This makes total sense to me in OO terms because I'm asking the player "to do" something.
The issue comes when I need to do other things in addition to just modifying the players position. For example, say I need to send that warp event to other players in an online game. Should that code also be within Player's warp() method? If not, then I would imagine declaring some kind of secondary method within say the Server class like warpPlayer(player, position). Doing this seems to reduce everything a player does to itself as a series of getters and setters, or am I just wrong here? Is this something that's totally normal? I've read countless times that a class that exposes everything as a series of getters/setters indicates a pretty poor abstraction (being used as a data structure instead of a class).
The same problem comes when you need to persist data, saving it to a file. Since "saving" a player to a file is at a different level of abstraction than the Player class, does it make sense to have a save() method within the player class? If not, declaring it externally like savePlayer(player) means that the savePlayer method would need a way to get every piece of data it needs out of the Player class, which ends up exposing the entire private implementation of the class.
Because OOP is the design methodology most used today (I assume?), there's got to be something I'm missing concerning these issues. I've discussed it with my peers who also do light development, and they too have also had these exact same issues with OOP. Maybe it's just that structured programming background that keeps us from understanding the full benefits of OOP as something more than providing methods to set and get private data so that it's changed and retrieved from one place.
Thanks in advance, and hopefully I don't sound too much like an idiot. For those who really need to know the languages involved with this design, it's Java on the server side and ActionScript 3 on the client side.
I advise you not to fear the fact, that player will be a class of getters and setters. What is object anyway? It's compilation of attributes and behaviours. In fact the more simple your classes are, the more benefits of an OOP you'll get in the development process.
I would breakdown your tasks/features into classes like that:
Player:
has hitpoints attribute
has position attribute
can walkTo(position), firing "walk" events
can healUp(hitpoints)
can takeDamage(hitpoints), firing "isHurt" event
can be checked for still living, like isAlive() method
Fighter extends Player (you should be able to cast Player to Fighter, when it's needed) :
has strength and other fighting params to calculate damage
can attack() firing "attack" event
World keeps track of all players:
listens to "walk" events (and prevents illegal movements)
listents to "isHurt" events (and checks if they are still alive)
Battle handles battles between two fighters:
constructor with two fighters as parameters (you only want to construct battle between players that are really fighting with each other)
listens to "attack" events from both players, calculates damage, and executes takeDamage method of the defending player
PlayerPersister extends AbstractPersister:
saves player's state in database
restores player's state from database
Of course, you game's breakdown will be much more complicated, but i hope this helps you to start thinking of problems in "more OOP" way :)
Don't worry too much about the Player class being a bunch of setters and getters. The Player class is a model class, and model classes tend to be like that. It's important that your model classes are small and clean, because they will be reused all over the program.
I think you should use the warpPlayer(player, position) approach you suggested. It keeps the Player class clean. If you don't want to pass the player into a function, maybe you could have a PlayerController class that contains a Player object and a warp(Position p) method. That way you can add event posting to the controller, and keep it out of the model.
As for saving the player, I'd do it by making Player implement some sort of serialisation interface. The player class is responsible for serializing and unserializing itself, and some other class would be responsible for writing the serialised data to/from a file.
I would probably consider having a Game object that keeps track of the player object. So you can do something like game.WarpPlayerTo(WarpLocations.Forest); If there are multiple players, maybe pass a player object or guid with it. I feel you can still keep it OO, and a game object would solve most of your issues I think.
The problems you are describing don't belong just to game design, but to software architecture in general. The common approach is to have a Dependency Injection (DI) and Inversion of Control (IoC) mechanisms. In short what you are trying to achieve is to be able to access a local Service of sorts from your objects, in order for example to propagate some event (e.g warp), log, etc.
Inversion of control means in short that instead of creating your objects directly, you tell some service to create them for you, that service in turn uses dependency injection to inform the objects about the services that they depend on.
If you are sharing data between different PCs for multiplayer, then a core function of the program is holding and synchronising that piece of state between the PCs. If you keep these values scattered about in many different classes, it will be difficult to synchronise.
In that case, I would advise that you design the data that needs to be synchronised between all the clients, and store that in a single class (e.g. GameState). This object will handle all the synchronisation between different PCs as well as allowing your local code to request changes to the data. It will then "drive" the game objects (Player, EnemyTank, etc) from its own state. [edit: the reason for this is that keeping this state as small as possible and transferring it efficiently between the clients will be a key part of your design. By keeping it all in one place it makes it much easier to do this, and encourages you to only put the absolute essentials in that class so that your comms don't become bloated with unnecessary data]
If you're not doing multiplayer, and you find that changing the player's position needs to update multiple objects (e.g. you want the camera to know that the player has moved so that it can follow him), then a good approach is to make the player responsible for its own position, but raise events/messages that other objects can subscribe/listen to in order to know when the player's position changes. So you move the player, and the camera gets a callback telling it that the player's position has been updated.
Another approach for this would be that the camera simply reads the player's position every frame in order to updaet itself - but this isn't as loosely coupled and flexible as using events.
Sometimes the trick to OOP is understanding what is an object, and what is functionality of an object. I think its often pretty easy for us to conceptually latch onto objects like Player, Monster, Item, etc as the "objects" in the system and then we need to create objects like Environment, Transporter, etc to link those objects together and it can get out-of-control depending on how the concepts work together, and what we need to accomplish.
The really good engineers I have worked with in the past have had a way of seeing systems as collections of objects. Sometimes in one system they would be business objects (like item, invoice, etc) and sometimes they would be objects that encapsulated processing logic (DyeInjectionProcessor, PersistanceManager) which cut across several operations and "objects" in the system. In both cases the metaphors worked for that particular system and made the overall process easier to implement, describe, and maintain.
The real power of OOP is in making things easier to express and manage in large complex systems. These are the OOP principles to target, and not worry as much whether it fits a rigid object hierarchy.
I havent worked in game design, so perhaps this advice will not work as well, in the systems I do work on and develop it has been a very beneficial change to think of OOP in terms of simplification and encapsulation rather than 1 real world object to 1 OOP class.
I'd like to expand on GrayWizardx's last paragraph to say that not all objects need to have the same level of complexity. It may very well fit your design to have objects that are simple collections of get/set properties. On the other hand, it is important to remember that objects can represent tasks or collections of tasks rather than real-world entities.
For example, a player object might not be responsible for moving the player, but instead representing its position and current state. A PlayerMovement object might contain logic for changing a player's position on screen or within the game world.
Before I start simply repeating what's already been said, I'll point towards the SOLID principles of OOP design (Aviad P. already mentioned two of them). They might provide some high-level guidelines for creating a good object model for a game.
Related
Consider a Chess application that has a Board containing an array of chess Pieces. Which of the following is the best object-oriented way of designing the Piece object, taking into account the advantages/disadvantages of each choice:
One class for all pieces, with a piece_type attribute that enumerates the types of chess pieces,
A Piece interface that all pieces inherit from, which would have the overhead of creating 6 other classes each corresponding to a unique chess piece.
The first option has the advantage of being lightweight and uses the fact that there is a lot of similar code involved with each chess piece, but is less "OOP". The second option defines an object for each chess piece, but would probably have to contain a lot of copied code and additional source files.
Considering the above, which method would be the most "OOP" design for a chess Piece?
Definitely the second one. The reason is that different chess pieces aren't just different types, they have completely different behavior.
So breaking it down into different classes allows you to specify correct movement (no two units move alike) and attack (e.g. pawn attacks diagonally) behavior for each piece nicely with polymorphism without having giant switch/case clauses in single class.
As for copied code, that is definitely bad; if you find yourself in the need to copy code, it is best to move that particular code to separate class, however I'm not sure what would be needed to copy here - each piece is different.
And as for additional source files, that is something you should almost never worry about. If you are getting lost in all the files it is best to organize it differently, e.g. putting all chess piece classes in their own folder.
Update (from comment):
The game should decide that the piece moves, but the piece decides how. So for example if you wanted to be provide feedback for the user, the user would click on a unit, and the game would ask the unit where it can move (because only the unit knows where it can move), and once the user would confirm the target, the game would tell the unit to move to the (valid!) target. So the game provides interaction between the pieces and user, but the pieces provide behavior particular to each piece.
Indeed great answer, however, I would omit any "Definitely" from an answer, especially to OO related subjects...I assume that each time you address such a problem you'll reach a different design concept.
IMO, there are several options, and any mix and match may work and be reasonably implemented. For instance, defining class "Movement" to stereotype the different moves a Piece can make. Different pieces can actually utilize same movement in certain game play.
Interface vs. Base class definition, again, depending on whether you see any attributes to the classes or not. I see several (Type, assigned movement, Active/Inactive etc.) - and that actually shouts "Base Class"...
For the actual game play, is there a "Player" class that actually instantiate "Moves"? just something to think about.
I've been working on a small project using C++ (although this question might be considered language-agnostic) and I'm trying to write my program so that it is as efficient and encapsulated as possible. I'm a self-taught and inexperienced programmer but I'm trying to teach myself good habits when it comes to using interfaces and OOP practices. I'm mainly interested in the typical 'best' practices when it comes to accessing the methods of an object that is acting as a subsystem for another class.
First, let me explain what I mean:
An instance of ClassGame wants to render out a 2d sprite image using the private ClassRenderer subsystem of ClassEngine. ClassGame only has access to the interface of ClassEngine, and ClassRenderer is supposed to be a subsystem of ClassEngine (behind a layer of abstraction).
My question is based on the way that the ClassGame object can indirectly make use of ClassRenderer's functionality while still remaining fast and behind a layer of abstraction. From what I've seen in lessons and other people's code examples, there seems to be two basic ways of doing this:
The first method that I learned via a series of online lectures on OOP design was to have one class delegate tasks to it's private member objects internally. [ In this example, ClassGame would call a method that belongs to ClassEngine, and ClassEngine would 'secretly' pass that request on to it's ClassRenderer subsystem by calling one of its methods. ] Kind of a 'daisy chain' of function calls. This makes sense to me, but it seems like it may be slower than some alternative options.
Another way that I've seen in other people's code is have an accessor method that returns a reference or pointer to the location of a particular subsystem. [ So, ClassGame would call a simple method in ClassEngine that would return a reference/pointer to the object that makes up its ClassRenderer subsystem ]. This route seems convenient to me, but it also seems to eliminate the point of having a private member act as a sub-component of a bigger class. Of course, this also means writing much fewer 'mindless' functions that simply pass a particular task on, due to the fact that you can simply write one getter function for each independent subsystem.
Considering the various important aspects of OO design (abstraction, encapsulation, modularity, usability, extensibility, etc.) while also considering speed and performance, is it better to use the first or the second type of method for delegating tasks to a sub-component?
The book Design Patterns Explained discusses a very similar problem in its chapter about the Bridge Pattern. Apparently this chapter is freely available online.
I would recommend you to read it :)
I think your type-1 approach resembles the OOP bridge pattern the most.
Type-2, returning handles to internal data is something that should generally be avoided.
There are many ways to do what you want, and it really depends on the context (for example, how big the project is, how much you expect to reuse from it in other projects etc.)
You have three classes: Game, Engine and Renderer. Both of your solutions make the Game commit to the Engine's interface. The second solution also makes the Game commit to the Renderer's interface. Clearly, the more interfaces you use, the more you have to change if the interfaces change.
How about a third option: The Game knows what it needs in terms of rendering, so you can create an abstract class that describes those requirements. That would be the only interface that the Game commits to. Let's call this interface AbstractGameRenderer.
To tie this into the rest of the system, again there are many ways. One option would be:
1. Implement this abstract interface using your existing Renderer class. So we have a class GameRenderer that uses Renderer and implements the AbstractGameRenderer interface.
2. The Engine creates both the Game object and the GameRenderer object.
3. The Engine passes the GameRenderer object to the Game object (using a pointer to AbstractGameRenderer).
The result: The Game can use a renderer that does what it wants. It doesn't know where it comes from, how it renders, who owns it - nothing. The GameRenderer is a specific implementation, but other implementations (using other renderers) could be written later. The Engine "knows everything" (but that may be acceptable).
Later, you want to take your Game's logic and use it as a mini-game in another game. All you need to do is create the appropriate GameRenderer (implementing AbstractGameRenderer) and pass it to the Game object. The Game object does not care that it's a different game, a different Engine and a different Renderer - it doesn't even know.
The point is that there are many solutions to design problems. This suggestion may not be appropriate or acceptable, or maybe it's exactly what you need. The principles I try to follow are:
1. Try not to commit to interfaces you can't control (you'll have to change if they change)
2. Try to prevent now the pain that will come later
In my example, the assumption is that it's less painful to change GameRenderer if Renderer changes, than it is to change a large component such as Game. But it's better to stick to principles (and minimise pain) rather than follow patterns blindly.
I have a quick question about the organization of a particular OOP problem.
Say I have a Terrain class, full of Tiles. There are multiple derivatives of class Tile, namely Door. The Door class has a method called open() which opens the door, and close() which closes the door. This makes perfect sense until both of these methods need to check for something in the way before opening and/or closing. How do I make a Door check for an object in the way without it knowing about its parent?
A simple solution would be to check for something in the way before calling open(), but if there was a different kind of door that needed to be check in a different shape, it creates clutter on the higher level.
It seems like this would have a simple answer, but it also seems like I run into this problem more often than not.
One answer is that Doors should know how to open and close themselves and know if they are blocked. If Door is a class, then both the state (is_open, is_blocked) and the behavior (open_the_door, close_the_door) should reside in the Door class. Encapsulation is a fundamental principle of the object-oriented paradigm.
But the real-world answer is usually more subtle. Can you provide some background on the application and what it needs to accomplish? There are clean, simple solutions that will work well for toy applications, but bigger apps are going to need something more sophisticated.
How to handle door is_blocked presents some design issues. There is no one right design, but there are good design and bad designs. Separating the good ideas from the bad ideas depends on more than just design principles-- it depends on the context of the problem.
If I had to take a guess, I'd guess that your application is a game. Maybe the tiles represent the area of the game board or map. You have identified that many different objects might have to interact and that it would be mess if they all referenced each other directly.
Games often have a master object called "Game" or "Board" or "Map". Let the master object hold the collection of things in the Tile hierarchy (tiles, doors, etc).
Let the master object also hold the collection of things that can block doors or otherwise interact with tiles and doors.
Now create a method named update() on the Tile class that accepts an object as a parameter.
And create a boolean attribute for the Door class called "blocked".
The update method for the Door might do something like this:
Door::update(BlockingObject object) {
if(object.location == this.location)
blocked = true
}
The method on the superclass of door might do nothing. Like this:Tile::update(BlockingObject obj) {
//tiles cannot be blocked
}
Now, inside the game loop, include a step where all the doors are set to blocked = false.
The create some loops ask all of the tiles to check if they are blocked. It might look something like this in pseudo code:
For each tile {
For each blocking object {
tile.update(object)
}
}
This is a naive, but straight forward design that holds true to the OO paradigm.
The design gives tiles/doors and objects a chance to interact once per turn, without forcing them to hold references to one another.
The design will work fine for a few hundred tiles and objects, but it would become very slow for thousands of tiles.
Is it a good design?
The answer depends on the needs of the application.
For a 2D game I'm making (for Android) I'm using a component-based system where a GameObject holds several GameComponent objects. GameComponents can be things such as input components, rendering components, bullet emitting components, and so on. Currently, GameComponents have a reference to the object that owns them and can modify it, but the GameObject itself just has a list of components and it doesn't care what the components are as long as they can be updated when the object is updated.
Sometimes a component has some information which the GameObject needs to know. For example, for collision detection a GameObject registers itself with the collision detection subsystem to be notified when it collides with another object. The collision detection subsystem needs to know the object's bounding box. I store x and y in the object directly (because it is used by several components), but width and height are only known to the rendering component which holds the object's bitmap. I would like to have a method getBoundingBox or getWidth in the GameObject that gets that information. Or in general, I want to send some information from a component to the object. However, in my current design the GameObject doesn't know what specific components it has in the list.
I can think of several ways to solve this problem:
Instead of having a completely generic list of components, I can let the GameObject have specific field for some of the important components. For example, it can have a member variable called renderingComponent; whenever I need to get the width of the object I just use renderingComponent.getWidth(). This solution still allows for generic list of components but it treats some of them differently, and I'm afraid I'll end up having several exceptional fields as more components need to be queried. Some objects don't even have rendering components.
Have the required information as members of the GameObject but allow the components to update it. So an object has a width and a height which are 0 or -1 by default, but a rendering component can set them to the correct values in its update loop. This feels like a hack and I might end up pushing many things to the GameObject class for convenience even if not all objects need them.
Have components implement an interface that indicates what type of information they can be queried for. For example, a rendering component would implement the HasSize interface which includes methods such as getWidth and getHeight. When the GameObject needs the width, it loops over its components checking if they implement the HasSize interface (using the instanceof keyword in Java, or is in C#). This seems like a more generic solution, one disadvantage is that searching for the component might take some time (but then, most objects have 3 or 4 components only).
This question isn't about a specific problem. It comes up often in my design and I was wondering what's the best way to handle it. Performance is somewhat important since this is a game, but the number of components per object is generally small (the maximum is 8).
The short version
In a component based system for a game, what is the best way to pass information from the components to the object while keeping the design generic?
We get variations on this question three or four times a week on GameDev.net (where the gameobject is typically called an 'entity') and so far there's no consensus on the best approach. Several different approaches have been shown to be workable however so I wouldn't worry about it too much.
However, usually the problems regard communicating between components. Rarely do people worry about getting information from a component to the entity - if an entity knows what information it needs, then presumably it knows exactly what type of component it needs to access and which property or method it needs to call on that component to get the data. if you need to be reactive rather than active, then register callbacks or have an observer pattern set up with the components to let the entity know when something in the component has changed, and read the value at that point.
Completely generic components are largely useless: they need to provide some sort of known interface otherwise there's little point them existing. Otherwise you may as well just have a large associative array of untyped values and be done with it. In Java, Python, C#, and other slightly-higher-level languages than C++ you can use reflection to give you a more generic way of using specific subclasses without having to encode type and interface information into the components themselves.
As for communication:
Some people are making assumptions that an entity will always contain a known set of component types (where each instance is one of several possible subclasses) and therefore can just grab a direct reference to the other component and read/write via its public interface.
Some people are using publish/subscribe, signals/slots, etc., to create arbitrary connections between components. This seems a bit more flexible but ultimately you still need something with knowledge of these implicit dependencies. (And if this is known at compile time, why not just use the previous approach?)
Or, you can put all shared data in the entity itself and use that as a shared communication area (tenuously related to the blackboard system in AI) that each of the components can read and write to. This usually requires some robustness in the face of certain properties not existing when you expected them to. It also doesn't lend itself to parallelism, although I doubt that's a massive concern on a small embedded system...?
Finally, some people have systems where the entity doesn't exist at all. The components live within their subsystems and the only notion of an entity is an ID value in certain components - if a Rendering component (within the Rendering system) and a Player component (within the Players system) have the same ID, then you can assume the former handles the drawing of the latter. But there isn't any single object that aggregates either of those components.
Like others have said, there's no always right answer here. Different games will lend themselves towards different solutions. If you're building a big complex game with lots of different kinds of entities, a more decoupled generic architecture with some kind of abstract messaging between components may be worth the effort for the maintainability you get. For a simpler game with similar entities, it may make the most sense to just push all of that state up into GameObject.
For your specific scenario where you need to store the bounding box somewhere and only the collision component cares about it, I would:
Store it in the collision component itself.
Make the collision detection code work with the components directly.
So, instead of having the collision engine iterate through a collection of GameObjects to resolve the interaction, have it iterate directly through a collection of CollisionComponents. Once a collision has occurred, it will be up to the component to push that up to its parent GameObject.
This gives you a couple of benefits:
Leaves collision-specific state out of GameObject.
Spares you from iterating over GameObjects that don't have collision components. (If you have a lot of non-interactive objects like visual effects and decoration, this can save a decent number of cycles.)
Spares you from burning cycles walking between the object and its component. If you iterate through the objects then do getCollisionComponent() on each one, that pointer-following can cause a cache miss. Doing that for every frame for every object can burn a lot of CPU.
If you're interested I have more on this pattern here, although it looks like you already understand most of what's in that chapter.
Use an "event bus". (note that you probably can't use the code as is but it should give you the basic idea).
Basically, create a central resource where every object can register itself as a listener and say "If X happens, I want to know". When something happens in the game, the responsible object can simply send an event X to the event bus and all interesting parties will notice.
[EDIT] For a more detailed discussion, see message passing (thanks to snk_kid for pointing this out).
One approach is to initialize a container of components. Each component can provide a service and may also require services from other components. Depending on your programming language and environment you have to come up with a method for providing this information.
In its simplest form you have one-to-one connections between components, but you will also need one-to-many connections. E.g. the CollectionDetector will have a list of components implementing IBoundingBox.
During initialization the container will wire up connections between components, and during run-time there will be no additional cost.
This is close to you solution 3), expect the connections between components are wired only once and are not checked at every iteration of the game loop.
The Managed Extensibility Framework for .NET is a nice solution to this problem. I realize that you intend to develop on Android, but you may still get some inspiration from this framework.
I try to realize a little game project to dive deeper into OO programming (winforms c++/cli).
I already started coding but now I´d like to make a re-design.
For the beginning the game should consist of four parts like game-engine, user interface, highscore and playground. Heres a little (non-UML-conform) class diagramm to visualize my purposes
Would this be the right way?
In my eyes the game engine is responsible to control the game sequences (state machine?) and exchanges information betweens all other classes.
I appreciate any help!
EDIT:
so it´s a really simple game, no big deal! here´s a link of what I made by now:
http://www.file-upload.net/download-2595287/conways_project.exe.html
(no virus :) but I guess you need .NET framwork to get it work)
Unfortunately, your current design sucks :)
I won't say what I will suggest is actually the best solution available, because in game design there is generally "no best" solution, but still I think it would make you think appropriately.
Larger UML here.
alt text http://yuml.me/1924128b
Let's say you have your basic class Game. It's something abstract class, that wraps all your game logics and works as a sort of Swiss knife.
You should create two another classes - UI and State (which, obviously, encapsulate game UI operations and store current game state). Let your Game class hold UI and State instances.
Now, your Game class should have basic methods to control your game. They could be plain render(...) and update(...) methods and this part is actually a bit tricky. If your game is real-time, you would have to update your state every Y milliseconds, so your update(...) should be called in a loop.
If your game isn't actually real-time, your updates should happen only when user does something or you actually know that you need to change something. You could implement a message queue here and update(...) call would simply flush all those messages.
Now, the render(...) method. Create some class and call it Backend - let this class encapsulate all your drawing possibilities. There is one really cool thing here - you could let your Backend be an abstract superclass and create some concrete backends, which derive from Backend. And that would actually give you an opportunity to switch your Backends with simple code manipulations.
After that, you should pass your Backend instance to your render(...) method, which would do appropriate drawing and it's logic could be written the following way:
foreach (const Object& object, game_state) {
object->render(backend); // Or something like that
}
The last thing to mention, your game state. You could have a plain structure to hold all your current objects, score, etc, etc. Let every object access that GameState structure and everything will be fine.
Actually, there are many things to think about, if you wish to, I could write more about this game design approach and share some tricks :)
Your 'Game Engine' would probably be considered more of a 'Math Library.' You might want to insert another object in between 'Game' and the other Server Classes that 'Delegates' the requirements of 'Game' to the Server Classes and call that 'Game Engine'.
Also maybe 'High Score' and 'Playground' could be combined into a Class which represents 'Game State' and port that directly to 'Game.' 'Playground' could be a Server Class which encapsulates any code to do the actual presenting of said background where this would usually represent a 'Rendering Class.'
IMHO