Skip to content

Resolution offset Aspect ratio

Zariep edited this page Jul 6, 2026 · 1 revision

If your touches register but hit the completely wrong spot, or your game is rendered inside a small square with massive black bars, your rendering resolution is mismatched with the physical screen.

Identify the Mismatch in Logcat

Look closely at your Raylib display logs:

DISPLAY: Device initialized successfully
 > Display size: 600 x 1256   <-- Physical device screen (Portrait)
 > Screen size:  1280 x 720   <-- Your virtual target (Landscape)
 > Viewport offsets: 0, 918   <-- Raylib's auto-generated padding

If your Viewport offsets are huge, your coordinate space is heavily distorted, causing the visual representation to diverge from the physical touch grid.

Lock Your Orientation Natively

If your game is intended to run in widescreen landscape mode, you must stop Android from starting the application in portrait mode. Be sure your AndroidManifest.xml looks like:

<activity android:name="android.app.NativeActivity"
          android:screenOrientation="landscape"
          android:configChanges="orientation|keyboardHidden|screenSize">

Initialize Using Dynamic Screen Matching

Instead of declaring hardcoded game dimensions to your initial hardware setup, query the real resolution or decouple your rendering using a RenderTexture2D.

Option A: Full Responsive Scaling (No Letterbox) Let Raylib initialize directly to 100% of the mobile viewport, then place UI elements using dynamic percentages rather than absolute pixel coordinates:

// Passing 0, 0 on Android usually forces Raylib to fetch real fullscreen resolution
InitWindow(0, 0, "My Game");

float sw = cast(float)GetScreenWidth();
float sh = cast(float)GetScreenHeight();

// Dynamically center a button:
Rectangle button = Rectangle(sw * 0.5f - 100, sh * 0.5f - 25, 200, 50);

Option B: Fixed Virtual Space with Aspect-Ratio Remapping

If you must use a fixed base texture sizing (like 1280x720) wrapped inside a scaling destination boundary matrix (destRect), you have to translate your touch inputs using the inverse proportions of that box:

```D
Vector2 getVirtualMousePosition(Rectangle destRect, int virtualWidth, int virtualHeight) @nogc nothrow
{
    Vector2 physicalMouse = GetMousePosition();
    Vector2 virtualMouse;

    // Subtract the black bar padding and scale by the transformation ratio
    virtualMouse.x = (physicalMouse.x - destRect.x) * (cast(float)virtualWidth / destRect.width);
    virtualMouse.y = (physicalMouse.y - destRect.y) * (cast(float)virtualHeight / destRect.height);

    return virtualMouse;
}

Use the output of this function for all your button CheckCollisionPointRec calculations instead of the raw GetMousePosition().

Clone this wiki locally