Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / How to Zoom and Offset camera to unknown values?

Author
Message
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 19th Oct 2017 10:56 Edited at: 19th Oct 2017 12:42
Hey,

The short question:
How do I position the 2D 'camera' so that I am viewing an area of the world at a specific size on screen and centred at a specific location on screen?

The longer question:

Imagine the game "Settlers" for an example of what I am trying to do.
Pretend you have a world that is 10x10 screen units in size (for example).
Now you click a button to focus on something that is currently off-screen (a house perhaps).
You want the camera zoomed in on the house so that the house occupies 1/4 of the screen (regardless of the actual dimensions of the house). But also because of HUD elements you need it to be offset from the centre of the screen to be positioned at some arbitrary co-ordinates.

Obviously I can't just set the zoom to a value - I would need to calculate it based on the size of the display and the size of the 'house'
And setting the offset would also need calculating so that the 'house' is centred at the location I want.

Any takers?

[EDIT] Another way to describe what I'm trying to achieve: I would like to shift and zoom the world so that a sprite within the world is positioned within a "window" of a given size and position on screen.
PartTimeCoder
AGK Tool Maker
9
Years of Service
User Offline
Joined: 9th Mar 2015
Location: London UK
Posted: 19th Oct 2017 12:49
I experimented with something like this a while ago but without the use of 'views' I gave up as the current AppGameKit system is a bit primitive, In GM:S this is very easy.

However, I did roadmap a plan (but never got round to coding it) to make a view system, grab desired area of the back buffer at the default res and resize the image giving the effect of zooming, you then use sprites as view areas, but this would mean grabbing the buffer, updating the sprite on each frame effectively taking over the drawing process so I'm not sure how practical the idea would be, I wanted the same kind of thing but also with a mini map.

I did also consider a 3D ortho topdown system to gain more control over the camera, but life got in the way.

CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 19th Oct 2017 14:42
You can use ScreenToWorldX and ScreenToWorldY in conjunction with GetPointerX and GetPointerY to get the click location in world coordinates, and use SetViewOffset and SetViewZoom close in on the click.

Here's a really rough example (click around to jump/zoom to click location):



Obvious improvements would include tweening to new location and tweening the zoom level to make it all nice and smooth.

(Sorry if I've got the wrong idea!)
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 19th Oct 2017 14:58
Thanks for your input, but no, that's not what I'm trying to do.
Here's what I have so far:

You can move the offset by clicking and dragging the mouse.
And zoom with the mouse wheel.
Pressing 1 will focus on the blue sprite and pressing 2 will focus on the red sprite.
The white square is the area of the screen that I want the red/blue sprites to be focused.

With this code the zoom sets correctly to fit the sprites into the white square but the offset is wrong. I can change the code to get the offset correct but only when the zoom is 1.0. I can't seem to get the zoom and offset to play nicely together.
CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 19th Oct 2017 15:29
Try this:

get current zoom value
set zoom to 1
set offset
restore zoom value
sync

Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 19th Oct 2017 15:44
Thanks again but no.
I don't want to restore the current zoom value I want to change it.
I want to change the zoom and offset so that the sprite appears in the square and fills the square.
CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 19th Oct 2017 17:27
Getting closer. I've got it to zoom / offset to the same area for the red / blue sprites (need to take into account the amount of zoom), just not quite in the right place yet... I'll take another look when I get home but you'll have probably sorted it by then:

Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 19th Oct 2017 17:32
puzzler2018
User Banned
Posted: 19th Oct 2017 19:13
Ive just looked at Settlers and got the gist of what trying to achieve.

If you still need some help in making the camera do what settlers does - then ill have a go at knocking something up on Saturday

CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 19th Oct 2017 20:25
Does this work? (I added a zoom adjusted offset in addition to the individual zoom adjusted sprite offsets)

Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 20th Oct 2017 07:38 Edited at: 20th Oct 2017 08:06
Thanks CJB.
That's a step in the right direction but not right yet. It works perfectly for that set-up but it uses nasty hard coded numbers!
Your code works great until you change either the display size or the zoom areas size and/or position.

I'll keep working on it but ideally I need it to work on whatever display it is running on and for any zoom size/position.

Thanks

If you remove this line:
Then the camera positions itself perfectly over each sprite but only if the zoom as 1.0
So, I'm thinking - I need to find the size of the world that is currently within the display bounds and work out that as a percentage of the actual pixel size of the display then use that value to offset the offset (or something). I'll keep playing.

Preben
AGK Studio Developer
19
Years of Service
User Offline
Joined: 30th Jun 2004
Location:
Posted: 21st Oct 2017 14:55 Edited at: 21st Oct 2017 22:27
Hi Scraggle,

I changed CJB version so it works on all resolutions and sprite positions , i never tried any of these commands , so i just aligned CJB code to take resolution into account, and it works

Subscribe and checkout great AppGameKit video's here: Videos click here
Latest GameGuru Loader news: News click here
best regards Preben Eriksen,
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 23rd Oct 2017 07:37 Edited at: 23rd Oct 2017 07:39
Thanks for your input Preben.

Unfortunately that still doesn't work for all cases. If you change the position and/or size of the 'ZoomViewArea' then the system fails.
I've taken your version of the code and changed it slightly so that each run will give a different resolution, and a different position and size of the 'ZoomViewArea'.


The main change that I made is to functionalise the input variables for SetViewZoomArea() so we can move the calculations from the function call to the function implementation.
When you run this you see that the zoom level works correctly but the offset is still skewed.
I had a busy weekend so I didn't get chance to work with it until this morning. I'll keep trying things but still welcome anyone's help.

I'm intrigued by the hardcoded numbers. Obviously nothing should be hardcoded for a dynamic system like this but I'm wondering how you have come up with them? Knowing how they were calculated for one particular set-up should help determine how to calculate them dynamically.

Thanks
CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 23rd Oct 2017 13:43
What do those numbers actually represent? Let's pseudo code it:

if 1 is pressed
set zoom to required amount based on size of target sprite
put target sprite in centre of screen
offset view so target sprite appears in target destination box (This is where those hard-coded numbers come in)
end if.

So... this should work:

Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 23rd Oct 2017 17:01 Edited at: 23rd Oct 2017 17:06
Thanks CJB,
That works a treat!

It's these numbers that concerned me:
Which I had taken from Preben's code when I moved it from here:

With your implementation of the FocusCameraOnSprite() function the above bit of code doesn't need to be there so all of the 'nasty' hard-coded numbers can be removed.

Thanks again, much appreciated!

And for anyone else that stumbles across this whilst looking for something similar, here is the final working implementation:
CJB
Valued Member
20
Years of Service
User Offline
Joined: 10th Feb 2004
Location: Essex, UK
Posted: 23rd Oct 2017 17:08

Login to post a reply

Server time is: 2024-03-29 12:51:30
Your offset time is: 2024-03-29 12:51:30