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 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .