Detecting when mouse is over a hex grid object in a C# Windows Forms application

79 Views Asked by At

Preface: I am not a programmer by trade. I just dabble.

Is there a better way to do this?

I'm making a simple hex map program, and I want to efficiently determine when the mouse moves over a hex element. I know I can create regions for form objects, but that seems inefficient. I decided to simply define square hit-boxes inside each element so I can use simple modulus operations and integer division to calculate the column and row numbers without having to use floating point math. Maybe I'm overthinking this back from the days when every CPU cycle mattered on my old 286, but I'd rather have my code be as efficient as possible.

Here is an image that shows a rough idea of where the numbers come from in the X dimension. The Y dimension is similar, but not illustrated. The red boxes aren't actually shown in the program. They are just an illustration of the size of the hit-box I chose:

Hit-box illustration (In the image, Xodd should be xOffsetOdd)

Here is the code I produced, and it seems to work well. I'm just wondering if there is a better method for doing this and if it would allow me to define the entire hex region without wasting too much CPU power. Note that this is just for my own personal use for building map images for later use. It doesn't have to be perfect, but I want it to be as good as possible.

        private void checkMapElementMouseOver(MouseEventArgs e, Bool overElement, int column, int row)
        {
            /*
             * Tile offests:
             * Column X increment 152
             * Column X-odd-offset 76
             * Row Y increment 68
             * Row Y-odd-offset 34
             */
            const int xPad = 10;    // Map tiles are inset
            const int yPad = 10;    // Map tiles are inset

            const int xStep = 152;  // Spacing between tile bounding boxes on a row
            const int xOffsetOdd = 76;  // Offset for tile bounding boxes on odd rows
            const int yStep = 68;   // Spacing between tile bounding boxes on a column
            const int yOffsetOdd = 34;  // Offset for tile bounding boxes on odd columns
            const int boxWidth = 56;    // Hit-box width
            const int boxHeight = 52;   // Hit-box height

            int xEven = e.X - xPad;
            int xOdd = e.X - xOffsetOdd - xPad;
            int yEven = e.Y - yPad;
            int yOdd = e.Y - yOffsetOdd - yPad;
            int modXEven = (xEven % xStep);
            int modXOdd = (xOdd % xStep);
            int modYEven = (yEven % yStep);
            int modYOdd = (yOdd % yStep);

            if ((modXEven >= 0) && (modXEven <= boxWidth) && (modYEven >= 0) && (modYEven <= boxHeight))
            {
                overElement = true; 
                column = 2 * (xEven / xStep);
                row = yEven / yStep;
            }
            else if ((modXOdd >= 0) && (modXOdd <= boxWidth) && (modYOdd >= 0) && (modYOdd <= boxHeight))
            {
                overElement = true;
                column = 1 + (2 * (xOdd / xStep));
                row = yOdd / yStep;
            }
            else
            {
                overElement = false;
                column = -1;
                row = -1;
            }
        }

Returning -1 for the row or column is just to indicate that I'm not over one of the hit-boxes. Those values are used to look up the element in my list/array variable.

0

There are 0 best solutions below