0

I am working on a 2D java game engine using AWT canvas as a basis. Part of this game engine is that it needs to have hitboxes with collision. Not just the built in rectangles (tried that system already) but I need my own Hitbox class because I need more functionality. So I made one, supports circular and 4-sided polygon shaped hitboxes. The way the hitbox class is setup is that it uses four coordinate points to serve as the 4 corner vertices that connect to form a rectangle. Lines are draw connecting the points and these are the lines that are used to detect intersections with other hitboxes. But I now have a problem: rotation.

There are two possibilities for a box hitbox, it can just be four coordinate points, or it can be 4 coordinate points attached to a gameobject. The difference is that the former is just 4 coordinates based on 0,0 as the ordin while the attached to gameobject stores offsets in the coordinates rather than raw location data, so (-100,-100) for example represents the location of the host gameobject but 100 pixels to the left, and 100 pixels up.

Online I found a formula for rotating points about the origin. Since Gameobject based hitboxes were centered around a particular point, I figured that would be the best option to try it on. This code runs each tick to update a player character's hitbox

            //creates a rectangle hitbox around this gameobject 
        int width = getWidth();
        int height = getHeight();
        Coordinate[] verts = new Coordinate[4]; //corners of hitbox. topLeft, topRight, bottomLeft, bottomRight
        verts[0] = new Coordinate(-width / 2, -height / 2);
        verts[1] = new Coordinate(width / 2, -height / 2);
        verts[2] = new Coordinate(-width / 2, height / 2);
        verts[3] = new Coordinate(width / 2, height / 2);
        //now go through each coordinate and adjust it for rotation
        for(Coordinate c : verts){
            if(!name.startsWith("Player"))return; //this is here so only the player character is tested
            double theta = Math.toRadians(rotation);
            c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
            c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
        }
        getHitbox().vertices = verts;

I appologize for poor video quality but this is what the results of the above are: https://www.youtube.com/watch?v=dF5k-Yb4hvE

All related classes are found here: https://github.com/joey101937/2DTemplate/tree/master/src/Framework

edit: The desired effect is for the box outline to follow the character in a circle while maintaining aspect ratio as seen here: https://www.youtube.com/watch?v=HlvXQrfazhA . The current system uses the code above, the effect of which can be seen above in the previous video link. How should I modify the four 2D coordinates to maintain relative aspect ratio throughout a rotation about a point?

current rotation system is the following:

  • x = x*Cos(theta) - y *Sin(theta)
  • y = x*Sin(theta) + y *Cos(theta)

where theta is degree of rotation in raidians

joey
  • 104
  • 12
  • 1
    1) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) You've described a requirement or specification, but asked no question. What is your question? – Andrew Thompson Dec 15 '18 at 01:47
  • You'd be surprised what you can do with the inbuilt Apis, [for example](https://stackoverflow.com/questions/20927189/detecting-collision-of-two-sprites-that-can-rotate/20928531#20928531) – MadProgrammer Dec 15 '18 at 01:57
  • @AndrewThompson My question is hwo to modify the coordinate location to maintain a proper rectangle around the character for the duration of the rotation @ MadProgrammer thank you, ill look into that – joey Dec 15 '18 at 02:14
  • *"hwo to modify the coordinate location to maintain a proper rectangle around the character for the duration of the rotation"* So whack a '?' on the end of it and [edit] it into the question. Where is the MCVE of your attempt? BTW - only one person can be notified per comment, so @MadProgrammer would not have been notified of that comment. – Andrew Thompson Dec 15 '18 at 02:25
  • @AndrewThompson I have added clarifications to the question body. Appologies for poor video quality in advance. – joey Dec 15 '18 at 08:17
  • *"Appologies for poor video quality in advance"* No apologies needed. I don't watch videos of programing problems. *"I have added clarifications.."* Add an MCVE / SSCCE & don't notify me until it can be plainly seen above. – Andrew Thompson Dec 15 '18 at 08:51
  • @AndrewThompson thankfully MBo offered a constructive response so I dont need you – joey Dec 15 '18 at 23:22

1 Answers1

3

You made classic mistake:

    c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));

In the second line you use modified value of c.x. Just remember tempx = c.x before calculations and use it.

    tempx = c.x;
    c.x = (int)(tempx*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(tempx*Math.sin(theta)+c.y*Math.cos(theta));

Another issue: rounding coordinates after each rotation causes distortions and shrinking after some rotations. It would be wise to store coordinates in floats and round them only for output, or remember starting values and apply rotation by accumulated angle to them.

MBo
  • 77,366
  • 5
  • 53
  • 86