0

I'm programming a game where various GameElement classes can collide with each other. All GameElements are stored in a main list. This list is iterated over to determine collisions, and then each GameElement in the main list is given a list of other GameElements it collided with. So far so good

I have several Classes derived from GameElement, for example Tree or Car.

Now when handling the collision between Tree and Car a Tree may wish to call getEngineType() if the GameElement it collided with is in fact a Car. Or the Car may wish to call getTrunkLength() if the GameElement it collided with is in fact a Tree.

Currently im calling instanceof to determine what subclass im dealing with, but this feels unclean. The only solution i can think of is to have seperate lists for Tree and Car objects, but this could get cumbersome as the number of classes grows.

Is there a best practice to deal with interactions between "similar" objects (GameElements) when these interactions depend on subclass specific methods and members?

EDIT: collision detection is not the issue! EDIT2: a similar question that uses the same instanceof solution i currently am Avoiding instanceof in Java

Community
  • 1
  • 1
Claude Hasler
  • 396
  • 1
  • 14
  • Yes, meet the [Visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) – fps Apr 20 '17 at 19:02
  • The more general pattern is called "refactoring" and it's [Replace Conditional with Polymorphism.](https://refactoring.com/catalog/replaceConditionalWithPolymorphism.html) For your specific case all of your GameElements should probably implement a common interface like "BoundingBox" and do your [collision testing that way.](http://www.gamasutra.com/view/feature/131833/when_two_hearts_collide_.php) – markspace Apr 20 '17 at 19:06
  • Hi, the Bounding Box is in fact implemented in GameElement. It's not the collision detection im having trouble with, but rather reacting to collisions of different object types. As far as I understand the Visitor pattern I use method overloading to call object specific methods right? For example int foo(Car) and int foo(Tree) I dont understand how this will help me with my example of getEngineType and getTrunkLength, which are two functions with possibly different parameters as well as different return types. – Claude Hasler Apr 20 '17 at 19:08
  • The normal way then is to make smaller bounding boxes around for example the trunk, the tires, the hood, the door, etc., and then recursively test each box to see what particular part of the car was collided with. [Here are some ideas.](http://www.gamasutra.com/view/feature/131598/advanced_collision_detection_.php?print=1) Note sphere subdivision and OBB tree in particular. – markspace Apr 20 '17 at 19:11
  • I feel like youre missing the Issue, collision DETECTION works just find. its the reactions based on subclass exclusive members/methods that is difficult. After a collision with a Tree i may wish to access tree specific information and after a collision with Car i may wish to access car specific information. – Claude Hasler Apr 20 '17 at 19:14
  • If you can determine the collision just fine, then I don't understand the issue. Maybe look at call-back methods, so you can attach some procedure to the trunk to call specifically when it's collided with. – markspace Apr 20 '17 at 19:15
  • After a collision with a GameElement which in fact is a Tree i would like to know the color or number of it's leaves for example. This information is specific to Tree, and not to GameElement. Collision detection is in the GameElement class. I would like to know if it there is a best practice solution to this problem, for instance looking for Tree collisions seperately from GameElement collisions. Currently i handle this by checking the subclassclass, then casting to the subclass. – Claude Hasler Apr 20 '17 at 19:19
  • What do you do with these properties after you get them? I'm imagining your code is filled with conditionals, but at some point an action occurs. For instance, if a tree's leaves are supposed to shake, or a car's engine is supposed to rumble, they could both override a @react method left abstract in "GameElement" and you could handle the actions there. – RaceYouAnytime Apr 20 '17 at 20:49
  • 1
    @FedericoPeraltaSchaffner I'm sorry, the Visitor model is indeed the solution to my problem! thanks! – Claude Hasler Apr 21 '17 at 07:41

0 Answers0