Screen Resolutions and Fullscreen in Quorum

This tutorial tells you how to change the screen resolution of games in Quorum

An Introduction to Screen Resolutions in Quorum

This tutorial discusses changing the size of the game window. This includes how to make a game fullscreen and the way screen resolution on the screen relates to cameras.

Setting the Size of the Game Window

When creating a Quorum game for use on Windows or Mac, by default a game will launch in a window that is 800 pixels wide and 600 pixels tall. To change the size of the window, we use the SetScreenSize action from the Game class. In the example below, we use SetScreenSize before calling StartGame. This will ensure that when the game launches and that the window that appears is the correct size.

use Libraries.Game.Game

class Main is Game
    action Main
        SetScreenSize(1000, 8000)
        StartGame()
    end
end

We can also change the size of the screen at any time after launching a game. The example below shows how to change the size of the game after StartGame is called. As a reminder, CreateGame is called after the window has been opened and is shown on the screen. SetScreenSize can be used to set the game window to any given positive width and height.

use Libraries.Game.Game

class Main is Game
    action Main
        StartGame()
    end

    action CreateGame
        SetScreenSize(1000, 8000)
    end
end

Fullscreen Games

When running an application in fullscreen mode, desktop displays have a limited number of supported resolutions (width x height). These resolutions can differ with different kinds of computers and platforms, which means there is no universal fullscreen resolution that will work everywhere.

To see what resolutions are supported by a particular monitor, there is an action built in to Quorum called GetAvailableResolutions. This will give us an Array of ScreenResolution objects.

use Libraries.Game.Game
use Libraries.Game.ScreenResolution
use Libraries.Containers.Array

class Main is Game
    action Main
        StartGame()
    end

    action CreateGame
        Array<ScreenResolution> array = GetAvailableResolutions()
        integer counter = 0
        repeat while counter < array:GetSize()
            ScreenResolution resolution = array:Get(counter)
            output "Supported Resolution #" + counter
            output "Dimensions: " + resolution:GetWidth() + " x " resolution:GetHeight()
            output "Frequency: " + resolution:GetFrequency()
            output "Bits Per Pixel: " + resolution:GetBitsPerPixel()
            output "Supports Fullscreen: " + resolution:IsFullscreen()
            counter = counter + 1
        end
    end
end

In the above code, we get the available screen resolutions and output some information about them. Each ScreenResolution object contains the following information:

  • Width: How many pixels wide the screen resolution is.
  • Height: How many pixels tall the screen resolution is.
  • Frequency: How many times per second the monitor updates its image when using this resolution.
  • Bits Per Pixel: How many bits are used to store information on each pixel. 32 bits is typical.
  • Fullscreen Support: If the monitor can display this resolution in fullscreen mode.

Once we have found a ScreenResolution we want to use, we can make our game fullscreen by using the SetScreenResolution action.

use Libraries.Game.Game
use Libraries.Game.ScreenResolution
use Libraries.Containers.Array

class Main is Game

    number exitTimer = 0

    action Main
        Array array = GetAvailableResolutions()
        // We'll use the first available resolution for this example.
        ScreenResolution resolution = array:Get(0)
        SetScreenResolution(resolution)
        StartGame()
    end

    action Update(number seconds)
        // Since our game is going fullscreen, there won't be a window with an exit
        // button. For this example, we automatically exit the game after 5 seconds.
        exitTimer = exitTimer + seconds
        if exitTimer > 5
            Exit()
        end
    end
end

In some cases, we might want to look at all the available screen resolutions and choose the one which best suits our game. One way we might do that is to get the resolution currently on the user's desktop. The GetDesktopResolution action will give us this information. We can also call UseDesktopResolution to tell our game to use it as a default.

Let’s look at what our last example would look like if we use the desktop resolution:

use Libraries.Game.Game

class Main is Game

    number exitTimer = 0

    action Main
        UseDesktopResolution()
        StartGame()
    end

    action Update(number seconds)
        // Since our game is going fullscreen, there won't be a window with an exit
        // button. For this example, we automatically exit the game after 5 seconds.
        exitTimer = exitTimer + seconds
        if exitTimer > 5
            Exit()
        end
    end
end

Note that in the two prior code samples we included a way for the game to exit. A fullscreen game does not have an exit button like a windowed game does, so it’s important for the programmer to provide a way to shut it down. If we ever create a fullscreen game without a way to exit, we can still close it via keyboard shortcuts (COMMAND + Q on Mac or ALT + F4 on Windows).

Screen Displays and Game Cameras

At any time before or after a game has started running, it’s possible to change the size of the game window or change the fullscreen resolution. However, changing the size of the display may change the appearance of a game, especially in 2D games.

To see how this can happen, let’s look at some sample code.

use Libraries.Game.Game
use Libraries.Game.InputMonitor
use Libraries.Game.Graphics.Drawable
use Libraries.Interface.Events.KeyboardEvent

class Main is Game

    InputMonitor monitor
    KeyboardEvent keys

    action Main
        StartGame()
    end

    action CreateGame
        Drawable box1
        box1:LoadFilledRectangle(100, 100)
        Add(box1)

        Drawable box2
        box2:LoadFilledRectangle(100, 100)
        box2:SetPosition(700, 500)
        Add(box2)
    end

    action Update(number seconds)
        if monitor:IsKeyPressed(keys:SPACE)
            SetScreenSize(1000, 800)
        end
    end
end

This program starts with the window at the default size of 800 pixels by 600 pixels. It contains two black squares, which are 100 pixels tall and wide. The first square is placed in the bottom left corner, and the second square is placed in the top right corner. Pressing the spacebar will resize the window to 1000 pixels wide and 800 pixels tall.

This is an image of the default 800 by 600 pixel window with a black square in the bottom left corner and another in the top right corner.

After pressing the spacebar, the first square is still in the bottom left corner, but the second square is no longer touching the top right corner of the screen. The resized screen is larger, so now there is an extra 200 pixels above the square and 200 pixels to the right of it.

This is an image of a 1000 by 800 pixel window with a black square in the bottom left corner and another that is close to the top right corner, but is  not touching it.

When the screen is resized, the game engine also automatically adjusts the game’s default cameras to match the new dimensions. Since our game launched in a 800x600 window, the default cameras are set to view an 800x600 region. When we changed the screen size to 1000x800, the default cameras were also resized to view a 1000x800 area. The default 2D camera is also moved slightly to keep the bottom left corner in the same position on the screen.

Sometimes, we may want to adjust the screen size without adjusting the cameras. If we had done that in our previous example, after pressing the spacebar our screen would be 1000x800 pixels on the screen, but the game’s camera would be “zoomed in” on an area that was still only 800x600 game units.

All actions that adjust the screen size, namely SetScreenSize, SetScreenResolution, and UseDesktopResolution, can be given a boolean value as their last parameter. If this value is false, then the game area will be resized without adjusting the cameras. Where we set the screen size in our last example, let’s replace it with this line of code:

SetScreenSize(1000, 800, false)

Here’s what our resulting code looks like:

use Libraries.Game.Game
use Libraries.Game.InputMonitor
use Libraries.Game.Graphics.Drawable
use Libraries.Interface.Events.KeyboardEvent

class Main is Game

    InputMonitor monitor
    KeyboardEvent keys

    action Main
        StartGame()
    end

    action CreateGame
        Drawable box1
        box1:LoadFilledRectangle(100, 100)
        Add(box1)

        Drawable box2
        box2:LoadFilledRectangle(100, 100)
        box2:SetPosition(700, 500)
        Add(box2)
    end

    action Update(number seconds)
        if monitor:IsKeyPressed(keys:SPACE)
            SetScreenSize(1000, 800, false)
        end
    end
end

Now when we press the spacebar, the square in the top right is still touching the top right corner of the window. Each square is still the exact same size in the engine (100 units wide by 100 units tall), but on the screen they appear slightly larger than they did before we resized the screen. Here’s what it looks like:

This is an image of a 1000 by 800 pixel window with a black square in the bottom left corner and another in the top right corner. The squares are slightly larger than in the previous image.

Next Tutorial

In the next tutorial, we will discuss Example Games Written in Quorum, which describes games that use several systems at once..