Newbie question - scale for Android phones/tablets

Previous topic - Next topic

finnk

It won't really tell you anything about implementing different screen sizes. It has a line to activate the autoscaling, and some config options that sets up stretching types (letterbox, fill, prefix/affix for different file resolution). The rest is handled by Corona's internals so it just works, but you won't really know how.

But in general seeing how it creates sprites, display layers, transitions and tweens, click, collision, and how nicely they're integrated, you get an idea of how to set up your whole engine so that everything is extremely well integrated and self managing. Scaling is something you just have to build into these functions but once you got it done, it's off your mind forever (once you get it bug free).

I use Unity for 3D, GLBasic for 2D. Unity is free for mobile publishing now and in terms of 3D there are several pros about it that I could not do without (skeletal animation/physics/collision/scriptable components/shaders) for 3D games. I've grown accustomed to both of them. Also was able to download scripts for Morph Targets which I'd never be able to figure out on my own. The math is beyond me.

I stopped using Corona because it didn't support Z-sorting (only x and y, and layers that are really inconvenient to move objects between), it only published for mobiles, and several other customizations that are only possible if you build all the functions yourself. It was good to learn with though and very feasible for people who just want to make mobile games. But I feel a lot more accomplished making my own framework too.

SFguy

Thanks for the elaboration, finnk. I know nothing about z-sorting!  I assume it is available in GLBasic while it is not in Corona, which is why you moved to GLBasic...  I will take a closer look at Corona.

spacefractal

Im does my own scaling rutine using either sprite scaling or polyvectors. I'm diddent like offscreen scaling, due it's did slow down by half.

So you might need your own implementation.

In greedy mouse I'm used 3 size of textures to choice from and downscaling. Only some icons did I'm choice to upscale as well.

In Karma Miwa, I'm use 960-640 to around 1388x768 as base resoulution, and up or downscaling it. Backgrounds can use retina and its might scroll up/down as well....

So it's depend on project doing.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

aroldo

 SFguy

I had these issues my self dealing with different scale my solution works fine resizing sprites but it uses more memory. Depending on how many sprites you have to import you may have to scale the images outside GLB and have an app for each resolution.


  • I start by making all the images/sprites for retina display resolution (1536 x 2048)
  • Get  the screen size

Code (glbasic) Select
GETSCREENSIZE screenW, screenH

  • Calculate the image index coordinates

Code (glbasic) Select
FUNCTION getimgIDX:
GLOBAL Widx = 1536/screenW
GLOBAL Hidx = 2048/screenH

IF Widx < Hidx THEN Widx = Hidx

ENDFUNCTION


  • Load the images. (Here is were some devices with less memory have a problem, for instance iPod / iPhone 3rd Generation)
    Code (glbasic) Select
    FUNCTION loadImages:
    LOADSPRITE "Media/images/paddle.png",0 // paddle
    LOADSPRITE "Media/images/ball.png",1 // ball
    ENDFUNCTION

    [/i]Now Resize the images

Code (glbasic) Select
FUNCTION resizeIMG:
// Resize the Brick, Paddle and Ball
GETSPRITESIZE 0, PADDLEW, PADDLEH // Paddle
GETSPRITESIZE 1, BALLW, BALLH // Ball

PADDLEW= INTEGER (PADDLEW/Widx) // resize Width
PADDLEH= INTEGER (PADDLEH/Hidx) //resize Height
BALLW= INTEGER (BALLW/Widx) // resize Width
BALLH= BALLW // resize // this is for round shapes to keep the aspect ratio!
ENDFUNCTION


[/i]Now in your draw function use the SPRITE RESIZE[/li][/list]
Code (glbasic) Select
STRETCHSPRITE 0,paddle_x,paddle_y,PADDLEW, PADDLEH


It would be nice if GLB had a command that allowed resizing the sprites to be resized at load time, this way it would save memory
For instance something like this:
Code (glbasic) Select
LOADSPRITE bmp$, num%, width%, height%
[a http://apd-games.com/][img http://apd-games.com/images/APDGames135.png][/a]
MacBook Pro OS X El Capitan
XCode Version 7
iPhone 6 running  iOS 9
iPad Mini running  iOS 7.1
Galaxy S5
Dell Latitude Windows 8 Enterprise
Palm Pre, Palm Pre2

MrTAToad

Yes, would be nice - plus of course, resizing during plotting does consume a bit of time...

erico

In my case, I guess I´m using one of the offscreen solutions mentioned, it does with a few SETSCREEN / USESCREEN / ZOOMSPRITE commands.
It is quite easy to implement and you will get you app scaled to whatever device.

1- The problem here is that you distort pixels (ye, the aspect ratio) when full screen (using all device´s pixels).
2- It is easy to implement black borders and then keep the pixel ratio square, but....gah black borders?.

Both problems suck. But my game goes fine with the first option. Keep in mind that it is a single screen pixel art action game, no tiles (something on the lines of arkanoid).
You will have these kind of problems on any programming language, real problem is too many different screens with different aspect ratio on android. If the programming language resolves them automatically, then it must be using one of the 2 solutions.

Those 2 are quite easy to do on GLB, check the manual for those 3 command´s definition I stated up there, together with GETSCREENSIZE and you should be done.
...
Couple days ago, I decided to revamp my scaling solution to fit the more important android resolutions out there, no black borders and with square pixels.
Core game so far was in 320x240.

I spent a day studying that table of android screen sizes I posted somewhere and came to some solution:
Core game will have to be 428 x 240, some devices will use 400x240 and the caanoo will use 320x240.

The extra pixels on the androids will also host the game on screen controls.
On the 320x240, the players are allowed a bit off screen just enough to cover the extended 428 res.
PLayers have to collect falling stuff, and whenever it falls off screen on whichever device´s resolution, it does not score so to keep it a bit fair.

Here is a non sense table I did to figure that out:
Code (glbasic) Select
--------Xp------SCREEN SIZE-------------Xi------VERTICAL SIZE
|
CAANOO--320 x 240------------ x1 320 240
ANDROID----------------------
0--1920 x 1080---6.8% x4 480 270 x4.5 428 240
1--1280 x 720---20.8% x3 428 240 x3 428 240
2---960 x 540----4.1% x2 480 270 x2.25 428 240
3---800 x 480---14.3% x2 400 240 x2 400 240
4--1280 x 768----6.8% x3 428 256 x3.2 400 240
5--1280 x 800----3.2% x4 480 200 x3.2 400 242
6---854 x 480----1.6% x2 428 240 x2 428 240
-----------------------------
TOTAL ANDROID MKT 57.6%
-----------------------------

PANDORA-800 x 600------------ x2.5 320 240


Here is a screen shot of the game considering those 2 new resolutions, I´m currently redesigning to accommodate stuff.
So, like I said, you will have no problem doing your own scaling inside GLB and doing so will help teach you how you can optimize it for your game type.


SFguy

Thanks, everyone, for showing me some solutions on how you manage the issue of screen size.  Looks like there is no one-size-fits-all standard solution.

aroldo, thanks a lot for your detailed explanation - this helps!

erico, your screenshot looks beautiful! :)  If you design for a core game size of 320 x 240, and need to scale up for much higher resolution screens (e.g., tablets), won't the game look chunky?  Why not design for 1280 x 720 (20.8% of the Android phones, according to your table), and then scale down if necessary?

erico

It is supposed to be a game on the oldschool´s looks, like an amiga AGA game.
I love 320x240, and pure pixel art style. No transparencies, no pixel blending, no smoothshading. No rotation. Just pure blocks.

Yep I´m up scalling stuff with the Xi value and then moving a pixel up or down, left or right to accommodate details.
While I can keep the Xi value close to integer, it will scale better. I might have to check on android #2 (960x540) though...

If I design for 1280x720, on those DPI, it won´t look like old school pixel art, and if I downscale it to 320x240 for the caanoo, art will be destroyed.

So the only reason here for the upscale is to preserve the art style.
I currently looks nice on a galaxy note II at 1280x720.
It may look a bit blocky on a bigger tablet, but then all havoc is set loose in game and players may not bother ::)

Hence why I told you that each game type can benefit from a different solution.

EDIT: Another thing, is that everything is moving internaly on the 320x240 resolution, and the movement scales fine too. If I design for 1280 and objects are capable of moving a single pixel...when I get to 320x240, I will have to deal with the speed and probably subpixels movement. Could bring a lot of trouble since I want the game to flow exactly the same on all different devices. Again, for example, if you are doing a tiled chess board game or a rogue like, you may not have this problem at all.

erico

Extra bla bla... :-[

In my opinion, I take the screen size and DPI not as a problem on the dev tool (be it GLB, corona, etc) but a problem of the game design nature. Specially the UI.

I´m not sure how corona or other tools handle that, but the cheapest way is by free scaling things.
You can get that done in GLB quite easily:

GETSCREENSIZE and then SETSCREEN 0 for your phone resolution.
CREATESCREEN 1 on your core game resolution and set it to draw on sprite 200 and USESCREEN 1 to deal the game.
Before SHOWSCREEN, you USESCREEN -1 and ZOOMSPRITE 200 to the % and position that will fit better on the device resolution.

So this may scale to everything but with distortion. You can work this out a bit to get perfect scaling + black borders too, but I dislike black borders.
Best is to adapt this to your game needs and adapt your game to the nature of it.

I guess this is what friends around here stated as off-screen rendering, since the game is actually happening not on the main screen.
It is said to be slow, but fits my game type, it is going 60fps fine.

SFguy

Thanks, erico.  Makes sense.

Looks like there is no escaping the need to program in customization of the screen display and game format for mobile phones with different sizes.  So long as the resizing of sprites can happen outside the game loop, and not slow the game down, I'm fine.

kanonet

Quote from: aroldo on 2013-Jun-10It would be nice if GLB had a command that allowed resizing the sprites to be resized at load time, this way it would save memory
For instance something like this:
Code (glbasic) Select
LOADSPRITE bmp$, num%, width%, height%

Its very easy to implement this on your own, at least as long as grabsprite or usescreen are working. Just load your sprite in old size, draw it scaled, create new sprite from this with usescreen/grabscreen, unload original sprite -> use scaled sprite in your game. Once you created a function for this, you can use it for every sprite you want. But wit Mem2sprite it even would be possible to do this without grabsprite or usescreen, but may be slow (and using RAM instead of VRAM).
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

SFguy

Quote from: kanonet on 2013-Jun-10
Its very easy to implement this on your own, at least as long as grabsprite or usescreen are working.

But GRABSPRITE only works in iPhone in Portrait mode?  I wonder why. Pity there are no universal solutions! :(

kanonet

But you still can use landscape mode for GRABSPRITE. Or use USESCREEN. Or use MEM2SPRITE. So its still to possible to scale all your sprites at app start. So no resizing at runtime at all.
Btw. can you write to your app's folder? so you could resize your sprites on 1st launch, save them (and maybe delete original ones to save space) and only load the resized ones on later starts.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

SFguy

Interesting - thanks for all the input, guys.  :)

r0ber7

Kanonet's idea is something I'll remember myself, it'd save a lot of time.

SPRITE2MEM & MEM2SPRITE are very useful once you understand how to handle the data. Right now I use it to detect the edges in the tileset I use for landscaping a level. In the case of scaling your sprites, you could even add graphics effects like a simple blur during the data handling after SPRITE2MEM... Assuming you have the algorithm. Maybe one day I'll make one. :P