Resolution Neutral Apps - The best approach?

Monkey Forums/Monkey Programming/Resolution Neutral Apps - The best approach?

Rex Rhino(Posted 2012) [#1]
Hello Everyone,

I am new to Monkey (although I own just about every Blitz product and have been using them for years).

Anyway, I was wondering the best way to approach designing an app to work in all resolutions... so I can code once, and use it on Mac, PC, iPhone, and Xbox360 without changing the code.

On Mac and PC, I will default run in fullscreen with the graphics width and height set to zero (in order to use the desktop resolution). On Xbox360 I will set the resolution to 720p to scale either up or down. On iPhone I will use the native resolution.

What I would like to do, is put objects on the screen, with the center as the 0,0... have my graphics sized to be relative to the screen size... and to position them relative to screen size. That way I can layout the screen the same way on all machines (I will need to detect the graphics ratios, but that won't be a problem). However, I am open to changing that approach if there is a better way to do it.

Scaling, Rotation, Translation, all seem to work a bit different in Monkey than in BlitzMax, and I am still wrapping my head around that... I am wondering, what would be the best approach to use to scale and place relative to screen size?

What do you guys think?


Shinkiro1(Posted 2012) [#2]
Hey, and welcome to the monkey board :)

Using scaling, translation and rotation isn't that different than in BMax.
The only real difference is that you use a PushMatrix() before any of these commands and after a PopMatrix(). Look in the docs for more info.

A good way to render generally is to use a Camera Class (you have to write it yourself).
Then Render every object in relation to that camera.
For the Screen ratio thing take a look at the Autofit Demo located in the bananas folder of your Monkey directory.


GfK(Posted 2012) [#3]
+1 for James Boyd's Autofit code. Works great.


DruggedBunny(Posted 2012) [#4]
... but don't use the /bananas version as it's probably out of date! Use this one.


silentshark(Posted 2012) [#5]
Another vote for the Autofit code - does what it says on the tin!


therevills(Posted 2012) [#6]
Also James' code is in Diddy too (free plug :P)


Rex Rhino(Posted 2012) [#7]
I am looking at the James autofit code...

It is fantastic... but one of the problems I see with the autofit code, is that you have to commit to a specific resolution, and thus a specific screen proportion. You will either have black bars on the top, or on the sides, depending on the proportions you choose.

I suppose one workaround would be to choose a large resolution, and then zoom in to have it fill the screen. I don't know if that is optimum.

Here is the approach I think I am going to take... Please feel free to criticize if you think it isn't a good solution... I am hoping to write a re-usable object for multiple games (and release to the community), so I rather know if I have a dud idea right now:

Basically, I am going to use the width of the screen as my baseline, so if the screen is 1920 pixels wide, 1920 pixels will equal 1.0 units. The height will be proportional, so in the case of 640x480, the screen will be 1.0x0.75 in size.

I will plan to keep all of the critical stuff inside 16:9 proportions, as that seems to be the widest screen in common use, but draw the screen for 1.0x1.0... stuff outside the 16:9 area will simply be extra background, or view range, or whatever (depending on the design of the game), for people with less wide screens. I have used that technique for 480p vs 1080p on the Xbox360, and it seemed to work well (the 480p people simply got a bit extra of the background image).


muddy_shoes(Posted 2012) [#8]
Unless you create multiple layouts then you always have to pick a compromise resolution and aspect ratio to work with as the "standard". I'm not sure I see the advantage to deciding that the virtual screen width is 1.0 rather than 640 or 800 or whatever. I'd guess that most people pick a virtual res that matches a physical res so that they can figure out how big their visual assets should be.

I don't use the autofit code, so I don't know if it actually forces black bars. If so, then I'd agree that that's a disadvantage for some layouts. I can't imagine that it's difficult to just remove the scissoring that adds the bars if you want to fill those areas though. You might want to look at it more closely as a few tweaks are probably all that's needed to do what you're proposing already.

If I remember correctly, the main reason why I chose not to go with autofit was that it mirrors mojo in only offering a single global display buffer interface. I wanted to be able to have my playfield scale in a different way from my UI (and possibly the in-game UI scale differently than the menu system) so I ended up writing my own that allows multiple res/scale strategies to be defined.


DruggedBunny(Posted 2012) [#9]
Yeah, AutoFit is definitely about choosing a particular aspect ratio (via the resolution selected, which is in itself largely irrelevant), and writing a game for that aspect ratio.

I did this because I found that trying to write a [2D] game for different aspect ratios can make a huge difference in how it plays.

For example, many shoot-em-ups (especially old arcade games) depend on a 'tall' aspect ratio to keep players in a narrow gameplay area, while having them deal with the inevitable oncoming hordes; changing this area from narrow to wide could easily have a huge effect on how easy it is to dodge bullets, for instance.

Here's an example in Ikaruga. If the width and height were swapped around, it'd be a completely different game!

However, one thing I would like to do with AutoFit soon-ish -- and the above screenshot demonstrates it perfectly -- is to return the two 'black bar' areas for the programmer to draw in, even if just to fill them with generic patterns; but these areas could also be used for scores, health, etc, as long as the programmer is willing to do the work to decide whether or not there's enough room available.

(Depending on the game and the device it's running on, the 'black bars' may be at the top and bottom, or they may be at the left and right sides; the space available either way may vary depending on the device the game is running on. There might even be no border areas at all if the device matches the ratio chosen for the game!)

Ikaruga on the consoles of the time had the luxury of being a port of an arcade game set in a vertically-aligned monitor (ie. a standard monitor turned on its side), knowing it would be running on standard horizontally-aligned televisions; therefore in turn knowing it could definitely use those side areas for scores and other information as in that screenshot.

Writing for a PC/browser and trying to cater for vertically- OR horizontally-aligned mobile phones, for example, you might not have that knowledge, so you ultimately have to decide to:

1) Aim for a given aspect ratio, which may or may not have a significant effect upon the gameplay;

2) Aim for a given [set of] resolution[s], and "hard luck" if a device doesn't support it/renders it offset, cropped, or whatever;

3) Adapt to any resolution or aspect ratio, and, again, depending on the type of game, you may end up filling in the border areas with game information (lives, health, etc) or using the borders for the game world and having to figure out where you can place that game information, etc, etc, etc, in many combinations!

I personally think that the gameplay in a 2D game is (almost always) very dependent on its aspect ratio; imagine how the Mario games would play if you had a tall, narrow, gameplay area rather than their usual short, wide gameplay areas.

Think of trying to adapt the square-ish Donkey Kong stages for arbitrary wide and narrow displays: the stages should play and look the same in both circumstances, but that's not really possible without ruining the aesthetics or gameplay via graphical stretching.

So, AutoFit is really most suited to games intended by design to play in a given aspect ratio, as in 4:3, 16:10, whatever -- the ratio being defined by the width/height selected -- and I personally think the aspect ratio of a 2D game is (usually) absolutely critical to how the game plays.

I'm rambling because I'm drunk, but on re-reading I'm pretty sure I've got my main points across!


DruggedBunny(Posted 2012) [#10]
Ooh... that's a long rant, or "explanation" as I prefer -- sorry!

Hope it explains the general idea I was going for...


Rex Rhino(Posted 2012) [#11]
Thanks James! I wasn't trying to say your approach was wrong... Or that your autofit isn't extremely useful. I am just thinking that if I am creating a game for multiple platforms from scratch, I would take a different approach.

I think that a game like Ikaruga could be done filling the whole screen. You would extend the landscape out the sides, and just make sure you keep your action that actually effects the gameplay within the tall/skinny section.

Also, a game with a scrolling map centered on the player would simply have a bigger map.

For Donkey Kong, you could show the level zoomed out between lives, and then zoom in closer to mario for the actual gameplay.

Sure, it effects gameplay. For some games, having fixed aspect ratios are a make or break aspect of the game, I guess... for some they aren't. I think that a lot of games CAN be adapted for different aspect ratios though.

In fact, all games played on the console are designed, to a certain extent, for different aspect ratios - as games for TV must be designed with a "safe area": http://en.wikipedia.org/wiki/Safe_area


DruggedBunny(Posted 2012) [#12]

Thanks James! I wasn't trying to say your approach was wrong...



I know, and I agree with *all* of what you said, including the idea of taking a different approach entirely!

However, take something like Gfk's "Crime Solitaire", with its pre-rendered backgrounds. You have a fairly stark choice here: stretch the backgrounds outside of their natural aspect ratio, making for a really ugly presentation, or retain the aspect ratio but have black borders.

There are of course other ways to deal with this, such as rendering the backgrounds for a range of aspect ratios, but I suppose AutoFit is meant to be a really easy way to cope with such a wide possible variety of display sizes/orientations: pick a resolution/ratio and forget.

I definitely agree that any game could be adapted in terms of presentation (eg. extending the display to show the outer areas), but the actual gameplay (see your Ikaruga comment, for example) is still often very much tied to the aspect ratio; even being able to see aliens, platforms, or whatever, coming in from a wider area can drastically change how a game plays.

Even with AutoFit, though, I would certainly want to lock a widescreen game to landscape/widescreen mode on my Android phone, for instance, as the AutoFit scaling in portrait/vertical mode would make it ridiculously small... but the benefit is still there in terms of not having to adapt to arbitrary resolutions, easily coping with 16:10 versus 16:9 displays, or 800 x 480 versus 1600 x 960, etc.

Of course it depends on how you plan the game from the start, and also in terms of how much work you want to take on (in terms of display layout) versus how much you want the likes of AutoFit to handle it all for you!

I do want to update it to allow filling in the black areas, though, either with a simple generic pattern or via in-depth manual programmer-querying/effort/design!

Anyway, it handles one thing rather well: lazy/limited programmer-selected aspect ratio to completely arbitrary aspect ratio!


Rex Rhino(Posted 2012) [#13]
Well, I just thought I would follow up on this for people interested.

I am using a hybrid of my original approach, and James' virtual resolution approach.

Basically, I am creating a virtual screen resolution of 1920, 1080 and designing for that... with the screen centered, all image I draw centered.

The code that makes it work is shockingly simple:
Function NormalizeScreen:Void()
	Translate DeviceWidth()/2, DeviceHeight()/2
	Scale Float(DeviceWidth())/1920,Float(DeviceWidth())/1920
End


I simply create a background image of 2048x2048, draw that in the center every time in order to fill the area outside 1920 x 1080, and voila, it looks great on every aspect ratio.

For the iphone, I am going to lock it into landscape mode.


Ken(Posted 2013) [#14]
Sorry to resurrect a really old posting, but I'm trying to wrap my head around orientation.

Rex, would you have an example of the kind of code you're talking about here? Just a hello-world sort of app that can demonstrate handling rotation on various different screen sizes?

Thanks,

-Ken


rIKmAN(Posted 2013) [#15]
Ken, I've uploaded a simple test using autofit that I did while trying to get my head around it recently.

Compile it for iOS and allow all orientations in xCode.
It should auto detect what device it is running on, and display the correct background so it is full screen and rotates fine on every device.

The green border is to help identify the screen edges, and I've tested it on iPod and iPad and it worked fine for me.

Link here

You can test using HTML5 as well if you change the canvas size in MonkeyGame.html to match an iPod/iPad so it detects the different resolution.


Ken(Posted 2013) [#16]
Thoguht I'd replied to this already...strange.

Rikman, thanks for uploading that example.

I *think* i'm getting the idea, but one question still bugs me: What handles(controls? responds to?) rotation?

There are a couple of examples either way below.

If I'm going to use something like autofit, I want to be able to still use the screen real estate outside the main game render for auxiliary information (ship status, ammo counts, inventory, minimap, you get the idea).

While I'm dreaming, I'd like to set it to be able to rotate it to a specific part of the screen. Instead of just rotating to the center of the screen (leaving a top and a bottom), I'd like to rotate it to the top /or/ bottom, leaving the maximum usable extra space in one spot.

Yeah, not asking for much, am I?

Anyway, for the examples:

e.g. this code does seem to respond to rotation. click on the screen to draw a few objects, and then rotate your device (iOS for me here). Everything will spin to match the new rotation (things that are spun off will disappear).



this code does *not* seem to respond to rotation. Rotate how I will, I don't get a response here. Why?




Ken(Posted 2013) [#17]
*sigh* Post something publicly, and /then/ find out you must have made an error.

The bezier move stuff above does seem to respond to device rotation.

Not a clue why it didn't before.

Anyway, that's one thing solved. Yay!

I'm still unclear about trying to use the border areas with autofit2.

-Ken


erebel55(Posted 2014) [#18]
rickman, could you repost the example? Looks like the link died.


rIKmAN(Posted 2014) [#19]
Sorry erebel, I have only just seen this.

It was on my dropbox and I don't seem to have it to hand in my coding folder - I'll have a proper look over the weekend and see if it is backed up somewhere.

What is it you are having trouble with?