How to get size of the display window?

Hello, I’m trying to display an image at the centre of the screen, and I’m using a script to calculate the position. The display is 960x640 in game.project, but window.get_size() returned 1200x800?

Can someone let me know if I should change a setting somewhere or use a different function? Thanks

Are you using window.get_size() to get the size?

Yes, and its is returning 1200x800, but the setting in game.project is 960x640, so that’s not right.

Maybe your OS is using functionality like display scaling (at x1.25) so the actual window size is different than what you set in game.project?

That might be it, I’ll have to check later.

That aside, is there a way to get the “correct” window size? Because my mouse position (action.x & y) in the middle of the window is showing 960/2 x 640/2.

All I want is to get the dimension of the window so I can set the position of a game objection at the centre…

I believe the “correct” window size is just returned by the window.get_size(), you can check that by reading the window dimensions from “outside” of Defold, depending on your OS (Linux has xwininfo, I don’t know about the others).

And why the mouse action.x and y are different I don’t know, honestly. Maybe (if it’s caused by display scaling) you could compensate for that using window.get_display_scale()?

And beside all that: how about using GUI and setting the node’s of interest pivot to “center” and position to half of the game.project display size? Will this give you what you want?

Thanks for the suggestions. I measured the window with screenshot and it is 1200 x 800, and window.get_display_scale() returned 1.25, so you’re right that it is being scaled up. I suppose I could just include that in the calculation…

Another good suggestion with GUI! I’m still quite new at this and haven’t really looked at GUI yet, but I have some questions:

  1. I’ve set the pivot to ‘center’ but it seems I still need to position the node at the center of the screen myself? So I would still run into the same problem trying to get window size at runtime?
  2. I tried manually positioning a box node at the center of the screen with Adjust Mode Stretch and Pivot Center, then setting the position of my game object to that of the box node with gui.get_position(), but I got the error that gui function can only be called in a gui script, so what’s the proper way to do it?

Hello again,

As for 1., if you only keep the node’s Size Mode as “Automatic” and GUI Adjust Reference as “Per Node” (you have to select the gui node in the Outline), after you manually set the position to half of your project dimensions (from game.project) the engine should keep the node in the center of the screen at all times, no calculations needed on your part - that’s the default way the GUI works in Defold.

And 2. - you could send a message with the node’s position each time window is resized (I think best way to achieve this would be an Event Listener - window.set_listener()). I’m not sure but maybe you have to check Shared State in your settings for this. Oh, and I think you’d have to use camera.screen_xy_to_world() to switch between screen > world spaces. Now, it makes me think the first thought was better:

And one my thought is that I think you should try things a little bit more :wink: No offense!

Thanks again!

Re: 1) I did the settings as you said but when I changed the display dimension the node stayed in the same place (the previous center but off center in the new dimensions). Unless you mean it only ‘stays in the center’ if you change the window during runtime?

Re: 2) I think I misunderstood your point initially. I thought you were saying I could use GUI to define a center point which I can then used to position GO, but it seems you’re telling me to do without GO entirely and just use GUI?

After reading your reply to 1) and your initial post again, I’m thinking: you don’t want to display it at the center of the game window, but the whole screen? If so, I don’t know how to do this…

Edit: or you want to have it in the center after changing the project size in settings?

I do want to display a thing at the center of the screen.

Hmm how do I explain this better… So first off I’m new to gamedev and still figuring out Defold. I have messed around in love2d before and one thing that was very helpful there was creating a small lua module to calculate points like center of the screen, 1/3 to the left, etc, which I could reuse for different projects as-is. Hence why I want it to work regardless of what I set the display dimension to in game.project.

I initally thought there was going to be a simple answer like “oh, what you wanted was the display.get_size() function instead” or “your camera was zoomed in” (not that I have a camera but something like that.)

((Side note: I’ve since found the render() functions which did returned the game.project dimension but (1) I’m apprehensive of messing around with a render script, (2) seems like over-complicating things (3) since I can’t seem to pass values between script and gui script I’m not hopeful I can pass the value from render to script (4) I couldn’t modify the render script anyway))

After these few days I think the easiest solution is to use window.get_size and scaling with window.display_scale, except, my mouse pos is showing the game.project dimensions, sprite.get_size is showing the editor size and not on-screen size, and I only know that because I print() all those numbers to check, because so far I’m only trying to display things on the screen. Imagine trying to make things move :scream: I can already see this scaling and dimension inconsistency causing issues down the line.

What you want is a conversion from a screen coordinate (ie half the window width and height) into a world coordinate (the coordinate space in which your game objects live).

The easiest way to do this is to attach a camera component and then use camera.screen_to_world() and use the returned world coordinate to center your game object. This will then work regardless of your camera zoom level and position.

-- main.script
function update(self, dt)
	local ww, wh = window.get_size()
	local screen = vmath.vector3(ww / 2, wh / 2, 0)
	local world = camera.screen_to_world(screen, "camera#camera")
	go.set_position(world)
end

Thanks for the reply! I think world coordinate and screen coordinate are the terminology I am lacking!

I started a new project so I could replicate your example, but I keep getting the error: “attempt to call field ‘screen_to_world’ (a nil value)” when I run it ?

Additionally, I have two questions:

  1. Could you explain why you put the code in update()? I would have thought this would be more suited to init().
  2. I noticed that if I run the game without a camera, the (0, 0) in the editor ended up in the bottom left corner of the window, whereas if I run it after adding a camera, (0,0) ended up at the center of the screen (hence why I started a new project). I don’t see a way to move the camera, so I’m guessing I would need to set it through the script? I don’t have a ‘player character’ GO for the camera to follow, so how would I set the camera so (0,0) is at the bottom left of the screen?

I have not looked into camera in details because I didn’t expect to use it, so maybe I missed something obvious :sweat_smile:

Perhaps you made a typo?

  1. Init is only run once, so as an example, it makes sense to put it in update, in order to react to any resizing events.

Are you using the latest version of Defold (1.12.0)? The camera.screen_to_world() function is new.

2 Likes

This is it! I updated Defold and the script runs fine now, and the GO in the new project is centered. I’m a bit confused how setting the GO to (600, 400) put it in the center of the screen in this project whereas it was off center in my other project despite same dimension in game.project, but I supposed that’s what the screen_to_world function is for.

I cannot figure out how to reply to two people in one reply but thanks for the init() vs update() explanation. I’d wonder about the runtime cost of it in the update() but I suppose that’s something I can worry about if it starts having an impact.

Now that you have a camera in your project it will draw whatever it “looks at”. If you move the camera it will draw whatever you point the camera at. The camera.screen_to_world() will in such a case when the camera is moved return the world space coordinate of the screen space coordinate you provide. If the camera moves you’ll also see a change in world space coordinate for the center of the screen/camera.

1 Like

Thanks! I think I’m going to have to play around with the camera and coordinates to really understand it, but I think for now I’ll take it step-by-step and continue with my current project first.

1 Like