So I am developing a web text-based game and whatever business requirement shows up it adds a new method to the Player class. If you have developed a game in OOP way you possible know what I am talking about.
On my daily job I am developing a game server project and again, it has a HUGE Player class. The way they made that class to not be even bigger is making something like "managers": PlayerAttributeManager, PlayerFoodManager and those are just examples. So you would not call Player.getFood, Player.getTastyFood and so on, but those would be in PlayerFoodManager for example.
A friend was making a game for android and again most if his logic was in the Player class. However a huge Player class does not break the design patterns I think, because in those games a Player can do so much things and everything is related to the player.
Please give me any advice on how to have a smaller class when creating a game.
A way to keep your Player class small(er) is to take the OOP pattern further. Let's assume that your player does, at the moment, know about food, knows how to eat, etc. Why not factor out those things and take a different point of view: Your player has, for want of a better word, a digestion - or, in OOP, an attribute of type "Digestion", which is in itself a class covering hunger, eating, etc.
A similar principle can be applied to other aspects of your player.
At the end, your player would have fields of type Digestion, Health, Armory, ..., and these aspects would be self-contained classes, keeping the player class small.
Of course, health would have some interaction with digestion presumably - this can be managed by using interfaces.
Related
I'm currently in a project of making a video game, to be specific, a turn-based strategy in OCAML. It's a coursework about functional programming, so the more functional programming the better, but if I can't do it with functional programming, I can use OOP if REALLY needed.
Here's the model of my game at the basic level :
In the following, when I say type, I actually mean instance/type/module, i.e. I don't know how I should implement it, but I know that they should be at least packaged into different sections.
There will be a Main type. It's role is to switch between menus, settings, and the actual game.
The Game type will run the game. In context, it will iterate over each Faction of the game, and iterate, within the Faction, each Unit that the faction has. Each Unit will have a specific behaviour attached to it.
Every game object ( that can be rendered in a 2D screen ) will have the GameObject type. Ideally, I can attach a bunch of video/audio/etc. renderer and I will be able to know their position on the map.
Grid will be an array of array composed of Tile. Grid has a global view over the game, from Grid, I can, for example, know the location of every GameObject in the Game
Tile is a tile on the grid. Eventually, I would like them to have special features, for example, a terrain type.
Unit ( not to be confused with unit type from OCAML ) is an entity controlled by a Faction. It has many attributes, such as health, mana, strength etc... and can do certain actions depending on who they are.
Faction represents either the player or one of the opponents. Some bonus apply depending on the faction. e.g. a faction could have greater health, but lower strength and vice-versa.
Action is a type that represents an action. It has a source and a destination attributes. It can represent, any type of action, from self healing to an AOE spell. It has access to Game so that it can be free to do whatever it pleases within the Game.
My goal is to make a game model that I can improve on progressively. For instance, I would like to make subclasses of unit, those who can attack from afar, and those who can only attack in melee etc.
If this was a OOP project, it would be pretty straightforward, albeit inefficient if I understood the previous comments. As you can see, my way of thinking is biased towards OOP because I haven't done any project of this scale without OOP. My goal here is to make it in Functional Programming.
I require your advice on how to implement what I described, or part of it so I can figure out the rest on my own.
Thank you.
EDIT: Edited the whole question
EDIT2: Some spelling and backticks
Your question is filled with imperative and OOP idioms: iterate, array, object, subclasses, ... So your mind set seems to be already made up.
Not surprising as GUIs and games are the most obvious examples for OOP. They have state and mutate over time and thrive on inheritance. And while you can do all those things functionally, with functors or with with first class modules I don't think it is worth it.
Luckily ocaml lends itself well to this. Records and classes can have mutable fields and ocamls classes can model your objects and inheritance nicely. And you still can use all the functional concepts of ocaml alongside the classes. It mixes well.
I am new to XNA and this is a philosophical question. In most examples I have seen, game assets are defined as private class variables, loaded in the LoadContent method, and then drawn with the Draw method. If I have a large game with a lot of screens, there could be quite a bit of declarations at the top of this class.
With that said, here are my questions
Should I use the content pipeline over Texture2D.FromFile().
What are the advantages other than faster loading.
Should I call Content.Load(Of T)([some asset name]) outside the LoadContent() sub.
How are you handling loading assets for different screens? Are you declaring all assets at the top?
Thanks in advanced,
Eric
Using the Content Pipeline allows you to compile your textures with your binary, which saves space, load time, and protects your assets from editing/unauthorized use if you care about that. On the flipside, if you wanted an asset to be editable (like texture packs), FromFile() is effective. The file must exist in the expected directory with normal use of course.
It is good practice but ultimately your decision on where you choose to load content. Remember that content loading requires reading from disk, which is not something you want to be doing every frame for sure, and not really something we like doing during the game. You will want to set up your Game State Management so that content can be loaded completely during loading screens or game startup and not during the game itself. Of course, this is precisely what level loading screens are for! If you're very clever you can sneak loading in during pauses in gameplay, a la Metroid Prime's 'door loading'. Depending on the scope and assets of your game, though, you shouldn't really need to load dynamically like that.
Finally, about dumping assets: the answer is the great trope of OO programming: abstraction. If you have trouble organizing members then move them into an inherited class or a subclass as necessary (and only when sensible). In my game design I rarely have more than 2 Texture2Ds, 1 SoundBank, and perhaps a VertexBuffer/IndexBuffer per class. If I have designed things well, these are stored in a base class like "Sprite" from which any visual objects inherit. In my latest set of tools, I've gone one level deeper, so now it looks like "Player.base(which is Sprite).Animation.Texture" if you want to access the actual texture... but you don't need to because all animation/drawing is handled completely by the Animation class and updated by Sprite along with Position, Rotation, Scale, Bounding, etc.
So, break down your game into objects. If you are storing a Texture2D PlayerTex and Vector2 PlayerPos in your Game class and in Draw you are drawing PlayerTex at PlayerPos, you are not taking advantage of OO programming. Store PlayerTex and PlayerPos in a Player class which also defines every other aspect and behavior (methods) of the player. Now all you need in Game is Player myPlayer, and in Draw you call myPlayer.Draw(SpriteBatch .. etc). You can take it even further! Here are some classes pretty much every game will have: Entity (base class of all dynamic objects), Level (stores scenery and Entities of each level and handles their interaction), GameScreen (stores and increments its Level member upon completion of each), ScreenManager (stores a stack of Screens to update, like GameScreen, but also MenuScreen, PauseScreen, LoadingScreen)... The list goes on. At this point all your Game1 class does is update ScreenManager, and if you inherit ScreenManager from IDrawableGameComponent, you don't even have to do that.
I hope I haven't dived too far into the deep end of OO 101, but if you're having trouble keeping track of all the members of your main class, you should start to break things down. It's a fundamental OO skill.
If all else fails, learn to use the #region <name>/#endregion tags liberally. Honestly, use them anyway, they make everything better.
Context:
In a game, when each level is completed, a Rating is stored based on player performance: Poor, Good, Excellent.
The ratings are later used to evaluate the game play as a whole.
Question:
Should the Rating object contain a rating choice as an enum {RatingPoor, RatingGood, RatingExcellent} or should I make an abstract base class Rating with subclasses RatingPoor, RatingGood, RatingExcellent.
Other details
Ratings don't have complex behaviors, they are just generated from play stats at a very low frequency like every minute. They're assigned to a collection and averaged at the end of a game to generate a Rank (like Cadet, Pilot, Captain, Admiral). At the end of a level, the rating is shown as an icon (think stars, like in Angry Birds). They also get stored when the player pauses or suspends the game.
I would also appreciate knowing how to decide on enum vs. subclass, given this context.
This situation is basic enough that you should just use an enum. I typically use enum's when something can be represented by an integer (a mode, a setting, or in your case, a rating,). A subclass is only necessary if your ratings would include additional attributes or relationships.
I think that a subclass would be overkill for this situation, as it doesn't sound like you're attaching any particular methods to each rating. I would use an enum.
I'm no expert in software design, but I generally err towards using the simplest data structures that will get a job done-- in general, if the problem doesn't require you to have methods travelling with the data, a class would be more heavyweight than necessary.
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
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.