Jump to content
  • Advertisement

Gameplay A little question about polymorphism

Recommended Posts

Hi all,

I was reading Game engine architecture and with that, brushing up some coding theory.

If I recall correct, polymorphism can help you for example to achieve the following:

 

- create a parent class with a virtual function, that needs to implemented in child/ inherited classes

- let's take a shape for example

- I have a triangle and square class implementing their own Draw function, like declared a virtual function in the shape class

 

Now my question is, how do I iterate through all child class objects?

Simplified code:

class Shape
{
public:
	unsigned int someVar;

	virtual void Draw();
};


class Triangle : public Shape
{
public:
	void Draw();
};

class Square : public Shape
{
public:
	void Draw();
};


// some program

std::vector<Triangle> myTriangles;
std::vector<Square> mySquares;

// generate some triangles and squares

for(size_t i=0;i<myTriangles.size();++i) myTriangles[i].Draw();
for(size_t j=0;j<mySquares.size();++j) mySquares[j].Draw();

I believe it should be possible to do the last 2 lines at once.

How would I iterate through them at once, using the advantage that polymorphism should bring here?

Share this post


Link to post
Share on other sites
Advertisement

The specific case of drawing is a bad example because it follows a highly inefficient data path. Drawing is best done in large batches with a small number of calls because each call has an overhead. Calling each object results in tiny batches of size 1 and an enormous number of draw calls, which is the worst case for drawing hardware.

 

There are generally two patterns used.

 

In one situation you would use a shared interface and process them as a group. Instead of making Shape have Draw, you might have an interface called "Drawable"

For a C++ loop, you might have something like this:

...
for( size_t i = 0; i < SceneList.Size(); i++ ) // I'd prefer a newer ranged for loop, but whatever works.
{
  if( Drawable* drawable = dynamic_cast<Drawable*>SceneList.GetItem[i] )
  {
    drawable->Draw();
  }
}

There is a small cost to be paid for the dynamic cast, but since it will return a null pointer if the cast fails and it gracefully handles a bunch of data hierarchy problems, the cost is generally something you would pay anyway if you're detecting that an operation is supported.

 

Alternatively, if you don't want to pay for a conversion or a type test you can provide a function that is called for every object rather than just the specific interface functions, and implement the function differently based on the derived type of object:

For that style of system:

//Do this:
for( size_t actorIdx = 0; actorIdx < actors.count; ++actorIdx )
{
  actors[actorIdx]->DoPrimaryAction();
}

//Not this:
for( size_t actorIdx = 0; actorIdx < actors.count; ++actorIdx )
{
  if(actors[actorIdx]->type == ActorType.Wizard)
    actors[actorIdx]->DoFireball();
  else if(actors[actorIdx]->type == ActorType.Warrior)
    actors[actorIdx]->DoSwordSwing();
  else if(actors[actorIdx]->type == ActorType.Rogue)
    actors[actorIdx]->DoKnifeStab();
  else if(actors[actorIdx]->type == ActorType.Archer)
    actors[actorIdx]->DoFireBow();
...
}

In both cases your code would not know or care about the concrete class it has.  There are a collection of things that all implement the same interface. You have a factor method somewhere that created the things for you. The things might be triangles or squares or circles, but you don't care because you only care about shapes.  Or the things might be wizards and warriors and rogues, but you don't care because you only care about actor objects.  When you follow SOLID principles, you should generally be focused on abstractions, not the actual objects.

Share this post


Link to post
Share on other sites

I think the pointer way can work, as suggested above. Since Triangle and Square both is a Shape, we can use one list/vector to hold all kind of Shape.

And maybe we use pure virtual function: virtual void Draw() = 0; at the parent class Shape.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Shtabbbe
      I've had a game idea for a while, and I wanted to finally try to create it.
      Its a 2D open-world tile-based MMO. The concept is it is one world and multiplayer only, so everyone shares one world no matter region, platform, etc.
      I am having problems finding out what to use to start development, I tried Unity but saw some of the negatives and refrained and now im stuck, could anyone recommend some intermediate friendly 2D engines that can support what I am looking for? Preferably in languages that are or are somewhat like Java, C#, Python, JavaScript, Lua.
      Thanks for your help, im very new at this if you cant tell
    • By APKirito
      Hey guys,
       So I started making this 2D side-scrolling platformer a while back, and I just wanted to get some feedback on my current progress. I am making this game purely for entertainment/experience, and I have no intentions to monetize it. 
      Here is my general story that is yet to be implemented. The game starts off with a cut scene where the player, a teenage fox, is together with his family, and he is told to go sleep (who needs curfew) by his parents. The fox reacts bitterly and wishes his parents were to disappear. The fox then goes to sleep and wakes up the next day. However, everyone is gone. The fox then says "Wow I can do anything now and no one will care!!." He then picks up a rifle and walks out the door and then tutorial begins. (Link to tutorial video).
      After the tutorial, the player is brought into a randomly generated dungeon (Link to Dungeon Generation Demo) (Link to dungeon traversal video). In dungeons, the fox is tasked to extract catnip from randomly placed bong objects (don't do drugs kids). However, there are traps and enemies randomly scattered that the player needs to watch out for. Every dungeon has a kitty that the player can pick up. These kitties spawn Challenge Rooms which I will explain later. Every dungeon also has a store that accepts catnip as currency. The store sells rifle upgrades and guns. To buy a gun, the player needs a kitty to equip it to. Guns are used to kill enemies and bosses. To exit the dungeon, the player needs to find a house object which is placed on the bottom layer of the dungeon. The dungeon exploration part of the game was heavily inspired by Splunky. 
      When the player exits the dungeon, he goes back home. If he picked up a kitty while in a dungeon, a Challenge Portal will be in the room. The challenge portal teleports the player into a challenge room. In these challenge rooms, the player needs to dodge obstacles to get from the entrance to the exit. The player is rewarded with a lot of catnip if they reach the end without taking any damage. (Link to Challenge Room 1 video) (Link to Challenge Room 2 video) (Link to Challenge Room 3 video) <= Ranked in difficulty imo
      After a certain number of dungeon traversals, the fox is confronted with difficult boss fights, and this is where the story progresses. The fox starts to miss his parents. (Link to Boss Fight 1 video)
      I am thinking about making two alternative endings after the final boss fight. One is where the kitties the player picked up in the dungeons transform into the fox's parents. This shows that parents are always looking after you even when you don't know. This ending is triggered if the player picks up a minimum amount of kitties. The other ending is where the fox finds out that his parents were shot by hunters. This ending is triggered if the player picks up less than a minimum amount of kitties (lowkey just want the players to find kitties). If you read this far, you are a legend. Any feedback would be appreciated!! (story-wise, gameplay-wise, response to my video clips). THANKS
      -APKIRITO







    • By Josheir
      I just looked at an interesting web browser game called Call of War 1942.  The idea is to keep playing you purchase gold with pay pal (interesting idea.)  It is pretty much pay right away.  The game is pretty impressive.  I was wondering if anyone could venture to tell me what programming language/languages are in use.  The content is great with a video right away that takes no time to load.  Than after a quick first win a professional pop-up declares your victory.  The screen has the choice of moving tanks, etc.  which happens right on the screen.  It really is a neat game so far, so how was it made? 
      Thanks,
      Josheir
    • By CircleOfAwesome
      I'm not sure if you guys can help me, but I figured an entity-component OOP design would be in your realm of experience. I want some feedback on it.
      Lets suppose that I have the following (it's mostly pseudo code):
      A header type of file:
      public: Button (textLabel, position); private: GuiComponent label; GuiSystem gui; A implementation type of file:
      // Event hookers / hooks the events to the corresponding functions: label.Clicked(onClickObj); // label is actually a pre-existing object that I can hook an event to. Now whenever user clicks, onClickObj. executes. function Button(text, position){ label.Text = text; label.Color = "Blue"; label.Position = position; } function onClickDo(){ gui.ChangeColor(label,"Red"); // Passes in our label obj. that we have in private and set its color to red! gui.ChangeText(label, "Button was clicked!"); pause(2); gui.ChangeText(label, "Button"); // Changes text back to "Button." } This is basically a button that whenever is clicked, turns red and displays "Button was clicked!" which then turns back to "Button." It's just a simple example. Label is a pre-existing object and I can already manipulate it. I just want to place a whole ECS system on it.
      GuiSystem is a container or class blueprint full of methods that can be used on the GuiComponent such as flash color a.k.a makes the label flash random colors, etc.
      Then whenever I make something really custom like a server menu and I need buttons, all I need to do is create a custom class blueprint and inherit the Button class above. Then I replace/overwrite some of the functions and bam, I have a server menu. I would add more GuiComponent labels if needed too. Is this generally how gui-design-architecture works?
      To show you the example in detail for instance, lets say I want a server menu. I create class blueprint detailing all member functions a server menu would do e.g: AddServer() which adds server buttons, ConnectServer() which calls something like ServerSystem.Connect(server) and connects you to the server, etc. I would then override the click function onClickDo() to do the ConnectServer() type of function. Right?
      -------------------------------------------------------------------------------------------------------------------------------------
      I know guis usually don't use ECS but I already have a gui class blueprint premade with all the properties and such and abilities to connect events. I'm just adding ECS ontop of it and putting functions in the GuiSystem container and when/if that container becomes full or bloated, I can split it off like GuiSystem.Effects.CreateEffect(label, effect) and etc.
      Do I have the idea of ECS on right? Thanks for reading!
    • By JackOfCandles
      I'm working on adding grappling hooks in my 2D game. I've finished the rope throwing implementation and now I've started working on implementing a targeting system, and it's a little trickier than I imagined. Consider the following situation:
       

       
      The player is standing on a platform, and is surrounded by three potential grappling hook targets, A, B, and C. I'd like to avoid having a manual targeting mechanism, because that seems like it would detract from the experience.  So the problem is, how do I infer which one the player should swing to when they press the throw grappling hook button?
       
      The first thing I've done is using the player's look vector to determine which targets they are looking at. So if the player is looking to the left, target C would not be considered, leaving only A and B. The most likely option in this scenario is of course target B, as the player has no need to grapple to a target right below their feet, so my first instinct was to eliminate all targets that are below the player, but this doesn't give the desired behavior in all scenarios. For example, if the player were falling from above and they wanted to grapple to a ledge on their way down, this would fail.
       
      Another option I've considered is defining invisible regions which are associated with a particular target, and only allowing grappling to a target if the player is within the associated region. An issue I've found with this is sometimes regions will overlap, so this approach still didn't entirely solve the problem either. If for example, the region for A and B were to overlap, and the player were to hit the throw grappling hook button while in both of these regions, problem of determining which one to choose remains unresolved.
       
      So I am wondering if anyone else has implemented a similar system, and/or might have some ideas I hadn't considered.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!