Part 2
Setting the device size.
We have set the display to 100 x 100 with an aspect ratio of 1. Whether you chose to do that with
SetVirtualResolution(100, 100) or
SetDisplayAspect(1) is irrelevant. They both produce the same result. The next step is to simulate the device size.
That is easy, all we have to do there is call
SetWindowSize(width, height)
However, that means we need to hardcode for a specific device size and if we want to change that to see how the game looks on a different sized device, then we need to hardcode some other values.
My preferred method is to have a ‘debug’ menu at the start of the game which allows us to choose the device size. However, when I first started using that method I quickly got fed up of having to choose. So what I now do, and what I propose for you, is to save the display settings and choose those each time we run the game. If we want to change them, then hold shift at the start of the game and the debug menu pops up allow us to choose the device size
That sounds a lot more complex than it is. It’s actually very simply to implement and the code for it is below.
Throughout the code we’ll often need to refer to the edges of the devices screen. We’ll also need to know the width and height of it.
We’ve already established that the edges can be found with:
GetScreenBoundsLeft()
GetScreenBoundsRight()
GetScreenBoundsTop()
GetScreenBoundsBottom()
And therefore the width can be found with
GetScreenBoundsRight() - GetScreenBoundsLeft()
And the height with
GetScreenBoundsBottom() - GetScreenBoundsTop()
But that is a lot to type each time you need it so you might want to simplify that with a UDT. You will also be using this UDT later when we define other areas of the display.
type tBounds
l as float
t as float
r as float
b as float
w as float
h as float
cx as float
cy as float
endtype
You'll also need some code to establish the bounds. It's all in the project below but here's a taster:
global display as tBounds
function SetBounds(bnds ref as tBounds, x1, y1, x2, y2)
bnds.l = x1
bnds.t = y1
bnds.r = x2
bnds.b = y2
bnds.w = x2 - x1
bnds.h = y2 - y1
bnds.cx = (bnds.w * 0.5) + bnds.l
bnds.cy = (bnds.h * 0.5) + bnds.t
endfunction
I’ve called it
tBounds –
t to signify that it is a ‘type’ and
Bounds because we are defining a bounding area. As I said above, this is not just for the full display, you’ll be adding other bounds areas later.
We can set the bounds for the display by calling
SetBounds() with the four
GetScreenBounds…() parameters:
SetBounds(display, GetScreenBoundsLeft(), GetScreenBoundsTop(), GetScreenBoundsRight(), GetScreenBoundsBottom())
For now, let’s get on with getting sprites on screen.
Loading sprites, setting them to the correct size and positioning them correctly
For this part, a video would be much easier to follow, and I had very nearly finished putting one together when my cat knocked my laptop onto the floor. It mostly works but video playback and recording is now very jittery, so I’ll try it with images instead (cats are dicks!):
The first thing we need to do is decide how we want things to look.
For this example, I have a background screen and four GUI elements as shown in the screenshot below. What I will demonstrate is how to determine the size and location of each element so that it appears correct on all devices.
The first thing to note is that your background image is going to stretch. If you use a full screen image for your background there is nothing you can do about that. But there are solutions. You can either use an image that can stretch without being detrimental or in the case above we could split the image up and have the AppGameKit ‘circle’ separate to the fire so that the logo remains a perfect circle and the fire stretches. But for this example, we’ll just let the background image distort to fit.
You’ll need an image editor of some kind in-order to follow along from here. I use Photoshop but any editor would work as long as you can determine the size and position of each element in the image.
The first thing to do is establish a canvas size. That is the simulated size of the device but it only has to be a close approximation so that you get an idea of how it looks because (obviously) we don’t know the size of device it will ultimately be run on. You will also need to do some calculations too so making the canvas a reasonable size will make things a lot easier. I use 1000 x 500. It is a 2:1 (or 18:9) aspect ratio which is the same as a Google Pixel but making it 1000 x 500 makes thing a lot easier as you are about to see.
Step one is to open your image editor and create a new project at the size of your choice – I strongly recommend 1000 x 500 but you can go with 1920 x 1080 if you really want to.
Then place you GUI elements where you want them and resize them so that they look correct on this size ‘screen’.
If you are using Photoshop, open the ‘Properties’ window and ensure you have the Green box selected in the ‘Layer’ window. You will then see the position and dimensions of the image.
If you’re using some other image editor then you’ll have to figure out where to find these details yourself.
In my case it is positioned at 21 across and 11 down, with a width of 168 pixels and a height of 47.
Now we need to know what those dimension are relative to the size of the display and that is why 1000 x 500 makes things much easier!
You can get your calculator out if you prefer but 168/1000 = 0.168 so that is the value we will use for width. Height is slight trickier because it’s 500 pixels, 47/500 = 0.094.
We then take those two values and multiply them by the
unknown size of our display. It’s unknown because we don’t know the size of the display that it will be running on but we do know how to find it. We stored the values in
display.w and
display.h. Therefore, the size of the sprite is:
SetSpriteSize(greenBox, display.w * 0.168, display.h * 0.094)
To set the position of the sprite, it’s a very similar process but with the addition of an offset. We get the values again from our image editor. In this case 21 pixels across and 11 down. So, again we multiply by the size of the display but this time we need to add the edge of the display.
0.011 * display.w + display.l
If we don’t add display.l then the sprite will be positioned at zero on the x axis, and we established earlier that zero is not at the edge of the screen.
The same with Y:
0.021 * display.h + display.t
So:
SetSpritePosition(greenBox, 0.011 * display.w + display.l, 0.021 * display.h + display.t)
Then go through the same process for each of the elements. I won’t do that now, you can see that in the final code below.
if you download and run the code below, then the first time you run it you will get the debug menu that asks what dimension you want to simulate. If you want to change it after that you will need to hold sown the SHIFT key just after the program starts to run.
Next time we'll look at having different displays for different devices and orientations.