How should I structure my hitbox class?

Jul 13, 2012 at 3:58am
I am making a game that requires hitboxes.
There will be rectangular and circular hitboxes.
I want a function that returns a bool that indicates whether any two hitboxes are overlapping.
Both shapes must be able to be stored in the same container at once.

Should I just have one class contain all the variables for both shapes and use a "shape" variable to indicate which shape related variables to ignore completely? (What would the constructor look like?)

Or should I have 2 separate, similarly structured, classes?

Thanks in advance!


Jul 13, 2012 at 4:38am
I want a function that returns a bool that indicates whether any two hitboxes are overlapping.


I have yet to find a really good way to do this polymorphically. If you know you are going to only have 2 different kinds of hitboxes, you can probably get away with a few if/else checks. But if you want it to be expandable that approach kind of sucks.

I'd probably do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class HitBoxRect;
class HitBoxCirc;

class HitBox
{
public:
    virtual ~HitBox() { }
    virtual bool Overlap(HitBox&) = 0;
    inline static bool Overlap(HitBox& a,HitBox& b) { return a.Overlap(b); } // alternate entry
    virtual bool Overlap(HitBoxRect&) = 0;
    virtual bool Overlap(HitBoxCirc&) = 0;
    // add more functions here as you introduce more types

protected:
    static bool Overlap_RectRect(HitBoxRect& a, HitBoxRect& b);  // write your bodies for these
    static bool Overlap_RectCirc(HitBoxRect& a, HitBoxCirc& b);
    static bool Overlap_CircCirc(HitBoxCirc& a, HitBoxCirc& b);
    // and also here
};

class HitBoxRect : public HitBox
{
public:
    // put rect dims and stuff here

    virtual bool Overlap(HitBox& b)     { return b.Overlap(*this);      }
    virtual bool Overlap(HitBoxRect& b) { Overlap_RectRect(*this,b);    }
    virtual bool Overlap(HitBoxCirc& b) { Overlap_RectCirc(*this,b);    }
};

class HitBoxCirc : public HitBox
{
public:
    // put circle radius and stuff here

    virtual bool Overlap(HitBox& b)     { return b.Overlap(*this);      }
    virtual bool Overlap(HitBoxRect& b) { Overlap_RectCirc(b,*this);    }
    virtual bool Overlap(HitBoxCirc& b) { Overlap_CircCirc(*this,b);    }
};

// example usage:

HitBoxRect a = whatever;
HitBoxCirc b = whatever;

if(a.Overlap(b))
{
}

// alternatively
if(HitBox::Overlap(a,b))
{
}


This approach probably isn't very "straightforward", but it makes it harder to miss a combination.


But yeah... it isn't great. I just haven't really figured out a better way to do it.
Last edited on Jul 13, 2012 at 4:41am
Jul 13, 2012 at 2:54pm
I think I'll just have the different shapes separate to keep things simple.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Circle;
struct Rectangle;

struct Circle
{
    Vector3d center;
    double radius;

    bool isOverlapping (Circle);
    bool isOverlapping (Rectangle);
};

struct Rectangle
{
    Vector3d center;
    double height;
    double width;

    bool isOverlapping (Circle a) {return a.isOverlapping (*this);}
    bool isOverlapping (Rectangle);
};


What do you think?
Jul 13, 2012 at 3:05pm
Yeah that's much simpler, but then they don't share a common base class. Which is fine if you don't need that.
Topic archived. No new replies allowed.