Page 1 of 1
Mobile screen size adaption
Posted: Fri Feb 23, 2018 8:58 am
by hasen
There's a few threads from this in the past but I'm still really not clear how this is done properly. I've tried many things and it's quite a nightmare so far. I tried using
Code: Select all
local scaleW, scaleH = screenwidth/internalwidth, screenheight/internalheight
function love.draw()
love.graphics.scale(scaleW, scaleH)
game:draw()
end
Which works okish...apart from iPhone 6 plus or the higher res iPads it starts to look weird. Then I found my on screen buttons for movement have a different position to their click zone with this graphics scale enabled. It's got to the point where I feel I need to set the sizes of every sprite, tile and image in my game as a fraction of the screen size rather than a value in pixels but that is somewhat hard to do since the values would be hard to read in the code and there are many places where graphics don't take a value for their size.
Has anyone here made any mobile games with Love2d that can share how they solved this problem? Thanks.
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 9:06 am
by PGUp
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 9:22 am
by hasen
I tried it but it didn't work very well. The camera was made to be off centre and some of the graphics were off screen. Did you use this to make a mobile game successfully? What camera lib did you use?
It actually seems to have the opposite effect that is needed here. For example I set a target resolution of 1334x750 for iPhone 6 but if the device is iPhone 4s with resolution 960x640 the graphics are scaled
smaller when in fact they should be made bigger. Not sure if this is not a library for desktop resolutions rather than mobile screen size adaption.
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 10:02 am
by Hikitsune-Red
Personally, I draw everything that is a part of the game itself to a canvas, then scale that, leaving the mobile-specific bits out to be drawn and updated relative to the device, that way they are not scaled with everything else. Not exactly a catch-all solution (at least, not the way I have it set up), and it works really well for small resolution projects, as it can help maintain pixel integrity, but for other things it could probably point you in the right direction.
For reference, this was a setup on a recent project (not elegant, but it worked) :
Code: Select all
-- Draw
function love.draw()
lg.setCanvas(canvas)
lg.clear()
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
drawScene()
--Fade Overlay
color(fadec, fade[1])
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
lg.setCanvas()
canvasScale = {1, w = lg.getWidth() / canvas:getWidth(), h = lg.getHeight() / canvas:getHeight()}
-- Draw canvas scaled according to setting
if not allowStretching then
canvasScale[1] = math.min(canvasScale.w, canvasScale.h)
if maintainAspectRatio then
canvasScale[1] = math.floor(canvasScale[1])
end
lg.draw(canvas, (lg.getWidth() / 2) - ((canvas:getWidth() * canvasScale[1]) / 2), (lg.getHeight() / 2) - ((canvas:getHeight() * canvasScale[1]) / 2), 0, canvasScale[1])
else
lg.push()
lg.draw(canvas, 0, 0, 0, canvasScale.w, canvasScale.h)
lg.pop()
end
if isMobile then
-- Draw mobile UI
lg.draw(dpad, 64, lg.getHeight() - 64 - dpad:getHeight())
lg.draw(actions, lg.getWidth() - 64 - actions:getWidth(), lg.getHeight() - 64 - actions:getHeight())
end
end
(It even looks like I have fragments of other code I hadn't cleaned up in there... Whoops...)
If you want to see what that looks like in action, you're more than welcome to open the project's (patently messy) code, run it on a mobile device, or run it with a "-mobile" command line argument to see how the screen and UI react to different resolutions.
Project is here
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 10:08 am
by PGUp
Put CScreen.update() after CScreen.init() and it should be working
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 10:33 am
by hasen
PGUp wrote: ↑Fri Feb 23, 2018 10:08 am
Put CScreen.update() after CScreen.init() and it should be working
Yes I set it all up correctly of course. I think it's not designed for this use.
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 10:35 am
by hasen
Hikitsune-Red wrote: ↑Fri Feb 23, 2018 10:02 am
Personally, I draw everything that is a part of the game itself to a canvas, then scale that, leaving the mobile-specific bits out to be drawn and updated relative to the device, that way they are not scaled with everything else. Not exactly a catch-all solution (at least, not the way I have it set up), and it works really well for small resolution projects, as it can help maintain pixel integrity, but for other things it could probably point you in the right direction.
For reference, this was a setup on a recent project (not elegant, but it worked) :
Code: Select all
-- Draw
function love.draw()
lg.setCanvas(canvas)
lg.clear()
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
drawScene()
--Fade Overlay
color(fadec, fade[1])
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
lg.setCanvas()
canvasScale = {1, w = lg.getWidth() / canvas:getWidth(), h = lg.getHeight() / canvas:getHeight()}
-- Draw canvas scaled according to setting
if not allowStretching then
canvasScale[1] = math.min(canvasScale.w, canvasScale.h)
if maintainAspectRatio then
canvasScale[1] = math.floor(canvasScale[1])
end
lg.draw(canvas, (lg.getWidth() / 2) - ((canvas:getWidth() * canvasScale[1]) / 2), (lg.getHeight() / 2) - ((canvas:getHeight() * canvasScale[1]) / 2), 0, canvasScale[1])
else
lg.push()
lg.draw(canvas, 0, 0, 0, canvasScale.w, canvasScale.h)
lg.pop()
end
if isMobile then
-- Draw mobile UI
lg.draw(dpad, 64, lg.getHeight() - 64 - dpad:getHeight())
lg.draw(actions, lg.getWidth() - 64 - actions:getWidth(), lg.getHeight() - 64 - actions:getHeight())
end
end
(It even looks like I have fragments of other code I hadn't cleaned up in there... Whoops...)
If you want to see what that looks like in action, you're more than welcome to open the project's (patently messy) code, run it on a mobile device, or run it with a "-mobile" command line argument to see how the screen and UI react to different resolutions.
Project is here
Ok I'll have a look at it. Thanks.
Re: Mobile screen size adaption
Posted: Fri Feb 23, 2018 12:35 pm
by hasen
Hikitsune-Red wrote: ↑Fri Feb 23, 2018 10:02 am
Personally, I draw everything that is a part of the game itself to a canvas, then scale that, leaving the mobile-specific bits out to be drawn and updated relative to the device, that way they are not scaled with everything else. Not exactly a catch-all solution (at least, not the way I have it set up), and it works really well for small resolution projects, as it can help maintain pixel integrity, but for other things it could probably point you in the right direction.
For reference, this was a setup on a recent project (not elegant, but it worked) :
Code: Select all
-- Draw
function love.draw()
lg.setCanvas(canvas)
lg.clear()
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
drawScene()
--Fade Overlay
color(fadec, fade[1])
lg.rectangle("fill", 0, 0, canvas:getWidth(), canvas:getHeight())
lg.setCanvas()
canvasScale = {1, w = lg.getWidth() / canvas:getWidth(), h = lg.getHeight() / canvas:getHeight()}
-- Draw canvas scaled according to setting
if not allowStretching then
canvasScale[1] = math.min(canvasScale.w, canvasScale.h)
if maintainAspectRatio then
canvasScale[1] = math.floor(canvasScale[1])
end
lg.draw(canvas, (lg.getWidth() / 2) - ((canvas:getWidth() * canvasScale[1]) / 2), (lg.getHeight() / 2) - ((canvas:getHeight() * canvasScale[1]) / 2), 0, canvasScale[1])
else
lg.push()
lg.draw(canvas, 0, 0, 0, canvasScale.w, canvasScale.h)
lg.pop()
end
if isMobile then
-- Draw mobile UI
lg.draw(dpad, 64, lg.getHeight() - 64 - dpad:getHeight())
lg.draw(actions, lg.getWidth() - 64 - actions:getWidth(), lg.getHeight() - 64 - actions:getHeight())
end
end
(It even looks like I have fragments of other code I hadn't cleaned up in there... Whoops...)
If you want to see what that looks like in action, you're more than welcome to open the project's (patently messy) code, run it on a mobile device, or run it with a "-mobile" command line argument to see how the screen and UI react to different resolutions.
Project is here
I built it for iOS with Xcode and it didn't seem to work? The dpad was huge and the screen was a tiny square in the middle of the iphone screen. Also the character moved incredibly slowly. It worked fine as a love file on my computer though of course.
Re: Mobile screen size adaption
Posted: Sat Feb 24, 2018 12:01 pm
by Hikitsune-Red
Hmm... Interesting.
I have no iOS devices of my own to test it with, so I've never seen how it reacted there, but on Android all is well and fine. I can understand a potential resolution issue, but speed? That is interesting.
Again, the principle holds the same. Draw the game content to a canvas, scale that, then draw your UI on top of it. That way, the UI is independent of the gamescreen's rescaling. The unfortunate trick is finding the right numbers to fit most screens; i.e., getting the UI to scale consistently. If you look at the controls module, you'll notice I use a small hack in order to allow the scaling of UI (which I never got around to doing properly) by making it read the color of a pixel touched by the touchscreen on an image with 0 opacity that fits the control UI. For instance, underneath the DPad, each arrow area is one of four colors, when a touch is registered, it gets the color of the area being touched and uses that as a reference for which control is being touched and responds accordingly. This way, I don't have to math out the areas, instead, all I have to do is scale the hidden image with the same scale as the UI.
Re: Mobile screen size adaption
Posted: Sat Feb 24, 2018 2:16 pm
by hasen
Hikitsune-Red wrote: ↑Sat Feb 24, 2018 12:01 pm
Hmm... Interesting.
I have no iOS devices of my own to test it with, so I've never seen how it reacted there, but on Android all is well and fine. I can understand a potential resolution issue, but speed? That is interesting.
It may not have been speed, it may have been the controls not responding well when I clicked on them. Could have been an acceleration issue? After all, the dpad was bigger than the entire play screen! I didn't try it on a device, I just built it in Xcode and tried a few different models in the simulator.
Hikitsune-Red wrote: ↑Sat Feb 24, 2018 12:01 pm
Again, the principle holds the same. Draw the game content to a canvas, scale that, then draw your UI on top of it. That way, the UI is independent of the gamescreen's rescaling. The unfortunate trick is finding the right numbers to fit most screens; i.e., getting the UI to scale consistently. If you look at the controls module, you'll notice I use a small hack in order to allow the scaling of UI (which I never got around to doing properly) by making it read the color of a pixel touched by the touchscreen on an image with 0 opacity that fits the control UI. For instance, underneath the DPad, each arrow area is one of four colors, when a touch is registered, it gets the color of the area being touched and uses that as a reference for which control is being touched and responds accordingly. This way, I don't have to math out the areas, instead, all I have to do is scale the hidden image with the same scale as the UI.
Ok that makes regarding just scaling the game separately from the controls. Not sure what you mean by getting the colour of the touch though, why would there be a colour returned and why wouldn't you need to map out the coordinates of the touch areas?