I am trying to implement a zoom into a game I am making, but I want it to zoom towards the center; it always zooms towards the top left corner. I looked through the documentation for love.graphics a ton but didn't find anything suiting my needs.
Are there any methods, formal or informal, that I could use?
Thanks
tabbul
How to change screenspace origin?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Party member
- Posts: 559
- Joined: Wed Oct 05, 2016 11:53 am
Re: How to change screenspace origin?
The origin point (0,0) in löve's API is the top-left corner, with the coordinates incrementing when going towards down-right. This applies to the screen space coordinates, as well as drawing operations involving things like quads or images (at least, can't think of an example where this isn't the case).
In order to implement zoom in/out effects, you'll have to use functions like love.graphics.translate and love.graphics.scale. Translate for moving the origin point around (so that you can set the "center" where to zoom), and scale for well, scaling things without needing to manually do that with every love.graphics.draw call. Just do keep in mind that you need to "revert" the change afterwards, otherwise your visuals might get messy (love.graphics.push/pop can be useful for this).
In order to implement zoom in/out effects, you'll have to use functions like love.graphics.translate and love.graphics.scale. Translate for moving the origin point around (so that you can set the "center" where to zoom), and scale for well, scaling things without needing to manually do that with every love.graphics.draw call. Just do keep in mind that you need to "revert" the change afterwards, otherwise your visuals might get messy (love.graphics.push/pop can be useful for this).
Re: How to change screenspace origin?
Besides what MrFariator said, there's also the use of Transform objects.
When you create a Transform with love.math.newTransform(), or when you call its setTransformation() method, you can set the ox, oy offsets that'll be used for the scaling and rotation values sent in that same call.
So when you call setTransformation() and set some sx,sy scale values and also some ox,oy values (like the center of the screen etc), the Transform object will represent a scaling from that position.
You can then use that to draw graphics like this:Remembering that you can also use a transform object in the one of the overloads for graphics.draw(), like for an additional transform onto each image.
When you create a Transform with love.math.newTransform(), or when you call its setTransformation() method, you can set the ox, oy offsets that'll be used for the scaling and rotation values sent in that same call.
So when you call setTransformation() and set some sx,sy scale values and also some ox,oy values (like the center of the screen etc), the Transform object will represent a scaling from that position.
You can then use that to draw graphics like this:
Code: Select all
local zoomTF = love.math.newTransform()
(...)
zoomTF:setTransformation(0, 0, 0, zoom, zoom, centerX, centerY)
love.graphics.replaceTransform(zoomTF)
love.graphics.draw(...)
love.graphics.draw(...)
love.graphics.draw(...)
-- In love.run it already resets the current graphics transform, so this is only needed
-- if you're drawing unzoomed things after this.
love.graphics.origin()
Re: How to change screenspace origin?
I have tried translating the screen, but it also translates everything on screen to the center, which defeats the purpose of translating it.
Here is a video demostrating my problem I guess what I'm really asking is how do I move the origin without also moving the content on screen
Here is a video demostrating my problem I guess what I'm really asking is how do I move the origin without also moving the content on screen
-
- Party member
- Posts: 559
- Joined: Wed Oct 05, 2016 11:53 am
Re: How to change screenspace origin?
If you know you are going to be drawing an area of specific size, with an arbitrary zoom, with a moving camera, you can do something like (very crude example):
There are other approaches (like using transforms like RNavega mentioned), but chaining translate and scale in different orders or compounding them can yield results like this. That said, there are some camera libraries listed on awesome-love2d repo, though I have no experience with them. gamera seems to support some form of zooming at least.
Code: Select all
local zoom = 1
local posX = 0
local posY = 0
function love.update ( dt )
if love.keyboard.isDown("z") then
zoom = math.min ( zoom + 0.016, 4 )
elseif love.keyboard.isDown("x") then
zoom = math.max ( zoom - 0.016, 1 )
end
if love.keyboard.isDown("up") then
posY = posY - 4
elseif love.keyboard.isDown("down") then
posY = posY + 4
elseif love.keyboard.isDown("left") then
posX = posX - 4
elseif love.keyboard.isDown("right") then
posX = posX + 4
end
end
function love.draw ( )
love.graphics.push ( ) -- not strictly necessary in this example program
love.graphics.translate ( posX, posY )
love.graphics.scale ( zoom )
-- draw a grid of squares for easier visualization
-- the grid is 32*8 by 32*8, so we know the total size is 256x256 pixels
-- as such, we offset the drawing by half
love.graphics.translate ( -128, -128 )
for x = 1, 8 do
for y = 1, 8 do
love.graphics.setColor ( (x*32)/256, (y*32)/256, 1, 1)
love.graphics.rectangle ( "fill", (x-1)*32, (y-1)*32, 32, 32 )
end
end
love.graphics.setColor ( 1, 1, 1 )
love.graphics.pop ( )
end
There are other approaches (like using transforms like RNavega mentioned), but chaining translate and scale in different orders or compounding them can yield results like this. That said, there are some camera libraries listed on awesome-love2d repo, though I have no experience with them. gamera seems to support some form of zooming at least.
Re: How to change screenspace origin?
Everything scales and rotates around point (0, 0). If you want to scale/rotate about some other point and keep it fixed in space while everything else changes, then you need to do a (negative) translate -> scale -> (positive) translate operations, as explained below.
From some slide presentation on 2D affine transformations:
The same but with other words:
https://stackoverflow.com/a/39296957
Re: How to change screenspace origin?
Also maybe https://love2d.org/wiki/love.graphics.setScissor might be of help to contain drawing operations.
My boat driving game demo: https://dusoft.itch.io/captain-bradley- ... itius-demo
Re: How to change screenspace origin?
I think I am getting closer to solving my problem, thanks for all of the replies. I will go try this out tonight.
Re: How to change screenspace origin?
Thanks y'all; I have gotten it to work, slightly modified so it always zooms to the center of the screen.
Re: How to change screenspace origin?
I think RNavega's suggestion of using a transform object was good, it just missed a little detail. This zooms around the centre of the screen, assuming centreX, centreY are set to love.graphics.getWidth()/2 and love.graphics.getHeight()/2 respectively:
Code: Select all
zoomTF:setTransformation(centreX, centreY, 0, zoom, zoom, centreX, centreY)
Who is online
Users browsing this forum: No registered users and 6 guests