Hot answers tagged

67

Favour composition over inheritance in your entity and inventory/item systems. This advice tends to apply to game logic structures, when the way in which you can assemble complex things (at runtime) can lead to a lot of different combinations; that's when we prefer composition. Favour inheritance over composition in your application-level logic, everything ...


20

You got a few nice answers already, but the huge elephant in the room in your question is this one: heard from someone that using inheritance must be avoided, and we should use interfaces instead As a rule of thumb, when somebody gives you a rule of thumb, then ignore it. This not only goes for "somebody telling you something", but also for reading stuff ...


17

As long as you keep your system relatively simple, this should work. But when you add things like temporary skill modifiers, you will soon see a lot of duplicate code. You will also run into problems with different weapons using different proficiencies. Because each skill is a different variable, you will have to write different code for each skill-type ...


16

I can't imagine designing a game without using object oriented programming, because my entire understanding of how to design a game-program is based on OOP. Then it will probably be good for you to try writing some programs in non-OO style. Even if you discover that this is not pragmatic for you, you'll probably learn a lot along the way that will help you ...


14

The idea that inheritance must be avoided is simply wrong. There exists a coding principle called Composition over Inheritance. It says that you can achieve the same things with composition, and it's preferable, because you can reuse some of the code. See Why should I prefer composition over inheritance? I have to say I like your weapon classes and would ...


13

Any object-oriented program can be refactored to a procedural program by replacing all classes with structures and converting all member-functions into stand-alone function which take the object which would be this as an argument. So missile.setVelocity(100); becomes setMissileVelocity(missile, 100); or when that function is trivial, you just do ...


8

Your approach is fine, and was used widely by game developers of the past. You see with inheritance hierarchy you often find yourself in a situation there you want inherit from a multiple classes, but they don't usually mix well (including The diamond problem). Because of that, a component based architecture is being widely adopted. One variation of this ...


8

It is perfectly possible to mix both styles. The same GameObject can have some of its functionality implemented with the new ECS system and other functionality in classic MonoBehaviour events. What Unity recommends in their ECS tutorial is in fact to start with a project which uses the old style and then look for features which you think would benefit from ...


7

I do it as follows: All OOP classes/methods have access to this. In order to utilise this in a non-OO approach, simply pass in whichever instance (see next point) this should be, as the first parameter. Now, as for instances, you can pass structs into your functions as this, but I find the best way to achieve good cache performance for objects which are ...


7

You're correct that the problem (well, nuisance) is the if statements. Sadly, no matter what language your working in or what programming fanciness you employ you are going to have to check some component data / entity types / other flags on the colliding entity that will tell the present entity how to react to a collision. Good Practices (my experience) ...


6

As you've noticed, there are pros and cons to each architecture scheme. Each pattern has its own implications for how objects will interact, and when. First, I'd recommend a quick refresher on SOLID design. Now, what we strive to accomplish with good architecture is enough abstraction that we aren't hampered by the system when we want to add a feature. If ...


6

Inherit from sf::RenderWindow SFML actually encourages you to inherit from its classes. class GameWindow: public sf::RenderWindow{}; From here, you create member draw functions for drawing entities. class GameWindow: public sf::RenderWindow{ public: void draw(const Entity& entity); }; Now you can do this: GameWindow window; Entity entity; window....


6

A rule of thumb is that you use different classes when objects require different code and instances of the same class when the objects only require different values. So when ShortBow, HuntingBow, CompositeBow, ElvenBow etc. all behave identical except for having different stats, then they would all be instances of the same class. When bows have different ...


6

Taking the example of the guitar: (...) a player you can, for example, not only play on guitar as a Musical Instrument, but use it as a Weapon or, what is perhaps more unobvious, throw it right to the furnace to get some heat in a cold winter night. First off, move away from using object inheritance to model this. Although, I want to note that using OOP is ...


6

The problem is that inheritance leads to coupling--your objects need to know more about each other. That's why the rule is "Always favor composition over inheritance". This doesn't mean NEVER use inheritance, it means use it where it's completely appropriate, but if you are ever sitting there thinking "I could do this both ways and they both kind of make ...


5

In object-oriented programming, you expose private data with getter-methods. When your player-class wants to know the terrain-type of a tile, it would call level.getTerrain(int x, int y). That public function of class Level would access the private terrain array and returns the value of the terrain tile. When you don't want the player-class to depend on ...


5

AI being costly, performance is often the driving factor in architecture. To ease your concerns around data access models, let's consider a few different AI examples both in- and outside of the games industry, working from that which is furthest from human navigation to that which is most familiar to us. (Each example assumes a single, global logic update.)...


5

Generally speaking, you will need a separate draw call for each set of objects that have a different material (by material I mean a different shader, texture or other shading parameters). So the obvious approach is to group objects that have the same material, so that they can be rendered together, avoiding the expensive state changes. This is normally done ...


5

A singleton works. A global works. I'll stand by that statement. I don't think they're the best solution for this particular case, though. Yes, you can put all your GameObject instances into a World of some kind. The World then likely needs to be managed by an object if you plan to have more than one of them, e.g. some kind of WorldManager. This manager ...


5

No. Grass, Sand and Water aren't different TYPES of tiles, they are different tiles. i.e. class Tile { private: Sprite sprite; bool collidable; bool flamable; bool walkable; public: Tile(Sprite s, bool col, bool flam, bool walk) { this.sprite = s; this.collidable = col; this.flamable = flam; this.walkable = walk; } bool ...


5

obsessed with OOP What you've described isn't OOP. It's an abuse of inheritance, which is frequently attributed to OOP, but isn't an inherent part of the paradigm. :) My question is, what is the cost of using polymorphism in this way? Virtual function calls are slower than regular calls, and much slower than directly accessing data members, but are not ...


4

Why not use associated arrays?, this gives the benefit of being easily extended (using PHP for example) $Stats["Strength"] = "8"; $Stats["Dexterity"] = "8"; for things such as weapons, you would probably want to create some base classes Weapon -> MeleeWeapon, RangedWeapon and then create your weapons from there. The end result I would aim for is a class ...


4

"My goal was to teach them the fundamentals of C++ using OOP", following this, I think you're making the right choice. I find the OpenGL API doesn't lend itself to OOP( in the programming sense, anyway ) very well. I'm surprised you're even exposing 12th grades to C++ and OpenGL. Most university courses I've seen avoid both of these like the plague. So, yes,...


4

Take the following relations into account A team has players Team Red is a team A player is associated with a team So, the following approach should give you a good hint. Team Red and Team Blue are instances of a team, with the same attributes but they just differ in values. Unless you need to implement different behaviors (member functions) for each team,...


4

The idea is to have spell objects hold some reference to the in-code action you want that spell to do. Python's first-class functions make this quite nice (I'll assume Python 2.7.x): class Spell: def __init__(self, name, description, activationFunction): self.name = name self.description = description self.activationFunction = ...


4

Your JSON firstly is faulty and secondly does not match the data model. To break down your JSON: { "series": [ {, "points":[ { "ts": "1473850836254", "value": "11.27" }, { "ts": "1473851256637", "value": "...


3

While the conditional block is inevitable, your implementation has one serious flaw: Every new type of Entity you create will require you to alter the handleCollision() for every entity it could affect - in order for it to respond to the new type of collision. To prevent this you could rather use an attribute in the base Entitiy that "classes" each one's ...


3

I almost voted that this is too opinion-based, but on thinking on it further, I think it's safe to say with some sureness that the second option presented is just bad. Don't do that. Among other things, it means that any components which must create objects needs a dependency on another component, potentially a different component for each type of thing it ...


Only top voted, non community-wiki answers of a minimum length are eligible