I'm starting a game project, my first, it'll be like a civilization clone, with a big focus in war. I always worked with C# but for business apps (mostly web apps) so I have a doubt about what would be a good design to build the map positioning system.
I would like to each unit know where it's positioned, and to the map to know all units at each point, a two-way relationship, but I can't see what would be the best way to model this! I'd like some ideas and pseudo-code, if you could!
Thankz.
Make your map a two-dimensional array. At each position, put an array of all objects at that position. In addition, add position attributes to each object.
Yes, this will duplicate the information! So on each move you'll have to change the object and update the map.
However, fast reading and fast finding of the objects is very important for that kind of game. In addition, this solution avoids any search routine (e.g. go through the map and look for a particular object), which is generally a good idea: Replace all search routines over large datasets with indexes. The map should be seen as some kind of index over the object's position attributes.
The map should have all knowledge of all object on it. Furthermore, only each object on the map should know its location. This way, the map can ask all objects where they are and place them in their correct locations. You should never have to store the positioning information twice.
Here's one approach that should avoid duplication
Have a class which holds all objects on the map, and within it collections of different types of object
public class MapObjects
{
private Collection<GamePiece> gamePieces;
}
Each item in the collections will hold its (current) map co-ordinates
public class GamePiece
{
private MapCoordinate mapCoordinate;
// Other items relevant to a GamePiece.. Health, ItemType, etc
}
To find where a particular selected item is on the map should be easy, you have a reference to the GamePiece which holds its coordinates. To find what items are in a particular coordinate you need a helper method, probably within the MapObjects class:
public class MapObjects
{
public Collection<GamePiece> GamePiecesAtLocation(MapCoordinate mapCoordinate)
{
// Iterate through gamePieces collection and build a result
// collection of items at specified coordinates.
}
}
Good luck, sounds like an interesting project with plenty of challenges.
I would make the map hexagonal instead of a grid, so you don't have the odd Civilization phenomenon where you can cover more ground diagonally. Beyond that, I would just have each unit store its own position, and when you need to know which units are in a particular hex just iterate through the whole collection. It's hard to imagine having so many units involved that this approach would be a performance problem.
NSPoint is extremely useful when it comes to things like this. Each gameobject should have it's own location. You could store these gameobjects in arrays, one for each player, one for the whole game, it's up to you.
I will warn you that this is a huge project, not only codewise, but content wise, and requires lots of back and forth work while balancing the game. You should really try a few smaller games before you go after this one. Nothing is stopping you from diving in, but you are going to hit a lot of walls and write some serious spaghetticode if your first game is something this large. I would suggest starting with something like checkers, to get the turn based side of things down.
This is all coming from the guy who is currently writing a roguelike as his first game project. In my defense it is relatively straightforward, but there are a lot of things I was not expecting, and something as simple as calculating the sight / fog of war taking obstructions into account uses complex algorithms. I don't regret picking a roguelike as my first game, but after seeing how complex even the most basic concepts can be to implement, something like a turn based strategy game is simply something I'll leave to the pros for now.
If you're currently having trouble thinking of a way to not only create the units, but represent the map and store the locations, what are you going to do when it comes time to code in research? cities? production? resource gathering? A random map generator? Trajectory calculation? Hit probability? Armor? Mobility? Line of sight? Random events? AI?
I'm not trying to crush your dreams by any means, it's just that the genre you picked is more complex than it seems. Your brain will overload and burst at the seams. (I could continue rhyming on topic, but I will refrain to remind you that you should really try something like checkers first.)
Good design = simple design.
Make the map a list of objects.
Object
int X { get; set; }
int Y { get; set; }
Map
List<Object> objects
Add(Object)
Remove(Object)
GetAt(X, Y)
GetInBox(X,Y,Width,Height)
GetInRadius(X,Y,Radius)
That should be all you need. If the Get(..) queries get too slow, add caching or divide the map into sectors and keep a list of objects for each sector and update it when they move. This helps dramatically if you have many static objects or objects that don't move too quickly from sector to sector. My guess is that in a turn-based game, you won't need to optimize at all.
Related
I started making a simple 2D game than runs on LAN using C++ and SFML library. The game uses a typical update function every frame with its loop to change state of the objects. The game class stores a vector/list of players and monsters and two maps (one for tileset - just graphics, 2nd one holding terrain mechanics - wall, ground etc).
In loop, I call a Think() function (which does move/jump/attack, etc) on every monster (different monsters behave differently but all are inherited from abstract class Monster with theirs appropriate override).
The problem is:
For every monster I need to loop through every other object to check collision
For every monster I need to find near objects (by its coords) so the monster can behave according to what it is seeing
For every non-living object (like flying fireball, any other projectile) I need to update its coords according to passed time (this is easy) but again check collision
For every player I need to loop through all other players/non-lived/monsters to collect information about near objects to send appropriate state of the game to them.
I'm scared how many loops/nested loops this game would have.
I've already seen that some games implement small-instance-based maps world so the loops are always going through small amount of data and since every map is separated its easy to find anything/send update to players.
I could apply this approach to every floor with ease but the floor 0 would be still really huge (array around 5000x5000 tiles to walk on).
I'm thinking now of changing world map array to class that stores references to each object by its coordinates. I just came up with an idea that sorting objects by theirs coords would improve performance of loops or even replace them.
Is this a correct design? Or does exist a better idea?
You should not worry to much about many loops. You can always optimize once you run into problems.
However for the collision you should avoid to check each object against all others, as this will require n^2 checks. Still, this only applies if you really run into performance problems. If this happens, the default approach is to use a grid, which is updated once per frame (or less) to calculate each object's position in the grid. This means each of your cells will know about all objects in it.
Then, if you want to find collisions for a single object, you just check it, with the objects in the same cell and in adjacent cells.
If you have a big amount of objects, you might consider a dynamically adjusting grid, which can be achieved via a quadtree for example. But in most cases a simple statically defined grid should be sufficient.
My goal is to implement a (very simple) strategy game.
For the moment, I'll start with the map and two characters (I want the terrain to affect them differently) to experiment with pathfinding
The problem is that I have very little or no experience in object oriented design. I've used C++ classes before, but it was pretty straightforward: for instance, a class Graph implemented using an array of sets, with a method AStar. I didn't have in mind the concept of "several players".
I've thought of the following elements/classes: Game, Map and Character. Eventually a Pathfinder class.
First question: the position of a character is something the game should know? The map? or each character?
( I think the game should )
Second question: where would it be a good choice for a "findPath" method?
The Game?
Should a pathfinding algorithm be a method of Map? Something like map.findPath(character, srcpos, dstpos)
In the Character class? It makes more sense to do character1.findPath(map, srcpos, dstpos)
If I added a Pathfinder class, it would have to build its own representation of the map in order to determine the shortest path. And before doing that, it would have "to ask" the map how the terrain affects each player.
( I prefer the latter )
It seems the construction of an auxiliary structure (and asking the map) to apply, let's say, A* is something that I can't avoid.
Making things object-oriented is not a goal, it's a tool to be used when it makes sense. C++ is a language with lots of functionality that you can easily drown yourself with, so my advice is to keep things simple and easy.
This can mean keeping data and logic tightly together sometimes, or separating it completely other times.
First question: My initial reaction is that the character should know its position. But how you represent it with data depends on how you intend to use it, so both the game, the character and potentially also the map needs to know where the character is.
Second question: It depends on what the Map class is. Is it an object representing the map itself with necessary functionality exposed to the rest of your program, or is it a toolbox of functions that works on a simple data representation of the map?
If the Map class represents the map, it should have the necessary functionality exposed for a Pathfinder class to work on it (the pathfinding algorithm will need to have some additional data derived from the map, maybe temporary, maybe persistent).
If the Map class does not represent the map, you can put the pathfinding functionality in it. I think it would belong there in that case. If the pathfinding code causes the Map class to get too big, you should separate it into its own class anyway.
First Question: The position of the character should be a part of character itself (makes sense this way) for me.
Second Question: Finding a path logically cannot be a part of Map. Then you would be violating one of OOP principles i.e. Single Responsibility.
According to me you should create the PathFinder class. You can design it in this way
class PathFinder{
PathFinderAlgorithm algorithm;
//other required values according to your design
Path findPath(){
algorithm.apply();
}
//other required methods according to your design
}
PathFinderAlgorithm is an interface.
Using this you can also change the algorithm that you are using to find the path. Like if you in future need to find the longest path, all you have to do is create another class which will find the longest path and replace it in the PathFinder class.
(Please keep in mind I'm a relatively inexperienced programmer. I'm aware that this question can be viewed as too open ended because there are so many philosophies on inheritance in OOP. This question is directed more toward my thought process, i.e., am I approaching this scenario in a way that would seem correct by an experienced programmer? What is it about my ideas that are obviously accurate or inaccurate?)
I'm designing an inventory system that tracks information about IT hardware including computers, printers, switches, routers, mobile phones, hard drives, and other devices. I have a database designed and I'm now in the process of planning a front-end application. I intend for the application to use data access layer, business logic layer, and business entities. I'm still in conceptual planning stages and I realize I should not be considering implementation details at this point, but my mind tends to race forward. The way the search feature is supposed to work is: the user enters search criteria and executes the search. A list of matching devices (or the only matching device) is returned. The list of devices is displayed in some type of list view, and a details view is displayed for the device when it is selected.
I've been wondering if using inheritance in my eventual business entities would benefit my application, or if it will add unneeded complexity... or if it's just plain wrong. My initial thought is the setup as illustrated:
(This is not the actual design, just a simplified concept for this post)
In addition to each device having type-specific attributes, any device at any given time can be in one of two states, active or archived. I don't know how to model this at all.
I started thinking about how queries might work when using this setup. It seems simple enough to query any specific subclass of a device from a data access layer, such as
Pseudocode:
Computer comp = getComputerBySerialNumber(sn);
List<Router> routers = getRouters();
// I can then write code to display a list of basic device information and
// additionally display all details of a computer or router when requested.
// Obviously display would be handled in a different layer.
The issue that lead me to writing this question is how to handle queries such as "get all devices from a specific location".
// Returns a list of devices regardless of device type
// as long as they have the same location
List<Device> devsFromLocation = getDevicesByLocation(loc);
// List contains computers, routers, printers, etc.
How would I display basic device details and then specific device details if I have a base class object reference? (Trying to avoid crazy casting or using reflection).
Each of the devices from that location would be missing the specific attributes of their subtypes. If I wanted to display all of the data about a particular device I would have to query the database again to get the remaining fields. Is having to execute another query a sign of poor design? Furthermore, how would I determine the correct type of device? Possibly a large switch/case statement testing each Device.Type attribute, execute the correct query, return the full subtype and display details to the user? Or...Is it better to return separate lists containing objects of full subtypes and then iterate through all lists to display common attributes in the list view and then easily display subtype details in the details view?
Is this a useful case of inheritance or am I misusing it? I'm currently suffering from the problem of too much information. I read everything possible about OOD, and I have so many rules and guidelines in my head I never know if I'm doing anything right. I feel like my brain is looking to apply the information I've been absorbing, so I'm imagining an implementation that is incorrect. I keep thinking about all this business about programming to abstractions to keep code flexible, but at some point you need to deal with concrete classes, right? From my perspective, inheritance is about behavior and not attributes. Since I'm not actually modeling any behavior (or am I and I just can't see it?) and just collecting data about the devices it's making it difficult for me to interpret their relationships. Since these classes are essentially dumb collections of attributes I feel like they should all be separate classes. Then again, I will have duplicate fields in all the classes, but does it really matter in this case?
I know there are tons of books on OOD, inheritance, composition, etc. I've read some of those books; I'm currently reading some more and I've spent days researching online. Everyone conveniently uses obvious examples of inheritance. I'm having nightmares about Fruit, Animal, and Shape examples.
Thank you for taking the time to read my question, and thanks for any information or insight you can provide. Please feel free to offer any other tips, insights, trade secrets, maps to buried treasure, a sea-worthy boat and a sextant, or anything else you think might help.
The most straightforward way is to add an information method to your base class that returns the information, and have each derived type override that method with the correct information.
This would allow you to do:
foreach (Base b in list)
Write(b.Information());
If your output needs to be more dynamic consider a device information object.
Having skimmed your post only (so I might have missed some detail that makes this a bad idea) I would also suggest that you make Active State a member of the Device base class, since a Device 'has-a(n)' Active State (and Archive State if the same is true).
Other than that your design is nice and simple and makes sense.
EDIT:
So you might have a Report object that you want the information to be written on so you would have:
class Device{
write_information_to_report(Report report);
}
This can be overridden by the derived classes to add the derived specific information.
You could abstract the Report out also to be somthing like InformationOutputter if you really wanted to.
A good example of this sort of thing looking at drawing shapes:
class Graphics{
line(int, int, int, int) = 0;
curve(float, float, float, float) = 0;
class OpenGLDrawer : Graphics {
line(int, int, int, int) { // Use open gl to draw a line };
curve(int, int, int, int) { // Use open gl to draw a line };
}
class DirextXDrawer : Graphics {
line(int, int, int, int) { // Use directX to draw a line };
curve(int, int, int, int) { // Use directX to draw a line };
}
class Shape{
draw(Graphics g) = 0;
}
class Triangle : Shape{
draw(Graphics g) { g.line(... /* draw a triangle using line */ };
}
class Circle : Shape{
draw(Graphics g) { g.arc(... /* draw a circle using arc */};
}
Here you can see you can have each object responsible for its own function, common functionality can be shared at the baseclass level and any graphics object can draw any shape.
I keep hitting this problem when building game engines where my classes want to look like this:
interface Entity {
draw();
}
class World {
draw() {
for (e in entities)
e.draw();
}
}
That's just pseudo-code to show roughly how the drawing happens. Each entity subclass implements its own drawing. The world loops through all the entities in no particular order and tells them to draw themselves one by one.
But with shader based graphics, this tends to be horribly inefficient or even infeasible. Each entity type is probably going to have its own shader program. To minimize program changes, all entities of each particular type need to be drawn together. Simple types of entities, like particles, may also want to aggregate their drawing in other ways, like sharing one big vertex array. And it gets really hairy with blending and such where some entity types need to be rendered at certain times relative to others, or even at multiple times for different passes.
What I normally end up with is some sort of renderer singleton for each entity class that keeps a list of all instances and draws them all at once. That's not so bad since it separates the drawing from the game logic. But the renderer needs to figure out which subset of entities to draw and it needs access to multiple different parts of the graphics pipeline. This is where my object model tends to get messy, with lots of duplicate code, tight coupling, and other bad things.
So my question is: what is a good architecture for this kind of game drawing that is efficient, versatile, and modular?
Use a two stages approach: First loop through all entities, but instead of drawing let them insert references to themself into a (the) drawing batch list. Then sort the list by OpenGL state and shader use; after sorting insert state changer objects at every state transistion.
Finally iterate through the list executing the drawing routine of each object referenced in the list.
This is not an easy question to answer, since there are many ways to deal with the problem. A good idea is to look into some Game/Rendering engines and see how this is handled there. A good starting point would be Ogre, since its well documented and open source.
As far as I know, it separates the vertex data from the material components (shaders) through the built-in material scripts. The renderer itself knows what mesh is to be drawn in what order and with what shader (and its passes).
I know this answer is a bit vague, but I hope I could give you a useful hint.
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.