0
\$\begingroup\$

I am creating my first 2D game in monogame. I have used RenderTarget2D to maintain a 4:3 aspect ratio. If it is played in a window of any other ratio it will offset the RenderTarget2D position to create a Letterbox black bar effect. I accomplish this with:

        Rectangle RenderArea;
        // Calculate target and current aspect ratios
        float outputratio = (float)Window.ClientBounds.Width / (float)Window.ClientBounds.Height;
        float targetratio = (float)Screen.Width / (float)Screen.Height;

        // Calculate rectangle on screen we will be drawing to
        if (outputratio <= targetratio)
        {
            // output is taller than it is wider, bars on top/bottom
            int currentheight = (int)((Window.ClientBounds.Width / targetratio) + 0.5);
            int barheight = (Window.ClientBounds.Height - currentheight) / 2;
            RenderArea = new Rectangle(0, barheight, Window.ClientBounds.Width, currentheight);
        }
        else
        {
            // output is wider than it is tall, bars left/right
            int currentwidth = (int)((Window.ClientBounds.Height * targetratio) + 0.5);
            int barWidth = (Window.ClientBounds.Width - currentwidth) / 2;
            RenderArea = new Rectangle(barWidth, 0, currentwidth, Window.ClientBounds.Height);
        }

(Screen being my RenderTarget2D)

I then draw my RenderTarget2D to this area on the screen. This works great. The only issue I have is how to get touch and mouse inputs offset to this location on the screen without having to offset my TouchPosition.Position.X and Y manually every time I check their position.

I have already set my TouchPanel virtual size with:

        TouchPanel.DisplayWidth = Screen.Width;
        TouchPanel.DisplayHeight = Screen.Height;

but I don't know of a way to offset the returned TouchLocation X and Y by my RenderArea X and Y.

Is there any way to accomplish this without manually offsetting every position check?

\$\endgroup\$
1
\$\begingroup\$

I have not gotten an answer for a while, so I will post what I came up with. Hopefully it helps someone else.

I stopped trying to manipulate the TouchPanel size as I discovered it keeps reverting back to the window size anyway. I wrote a method that all touch checks must run through:

    bool Touched(Rectangle target, TouchCollection touchcollection)
    {
        foreach (TouchLocation tl in touchcollection)
        {
            if (tl.State == TouchLocationState.Pressed &&
                ((tl.Position.X  - RenderArea.X) * ((float)Screen.Width / (float)RenderArea.Width)) > target.Left &&
                ((tl.Position.X - RenderArea.X) * ((float)Screen.Width / (float)RenderArea.Width)) < target.Right &&
                ((tl.Position.Y - RenderArea.Y) * ((float)Screen.Height / (float)RenderArea.Height)) > target.Top &&
                ((tl.Position.Y - RenderArea.Y) * ((float)Screen.Height / (float)RenderArea.Height)) < target.Bottom)
            {
                return true;
            }
        }
        return false;
    }

It offsets for the black bar based on the XY location of the already calculated RenderArea. It then calculates a multiplier also based on the already calculated RenderArea.

Seems to work well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.