HaxeFlixel / flixel

Free, cross-platform 2D game engine powered by Haxe and OpenFL
https://haxeflixel.com/
MIT License
1.99k stars 439 forks source link

StageSizeScaleMode causes strange positioning behaviour on resize #1694

Closed IBwWG closed 8 years ago

IBwWG commented 8 years ago

Context: My ultimate goal is to have manual control over layout so that I can dynamically support desktop (with whatever size/shape window), tablet, and phone (in either orientation) resolutions in a way that makes use of every available pixel (i.e., no black bars at the side, and I control the scaling of multiple custom cameras.)

The default scaleMode does not fit this paradigm, but I believe StageSizeScaleMode would, expect that I cannot seem to reliably position a sprite after that, unless it's centred. Specifically, I'm trying to have a logo sprite always be at the top, so I set its .y property to 0, but this seems to vertically centre it around y = 50 no matter what its current size is, so it almost always looks wrong.

I've posted a demo and made an issue with screenshots at https://github.com/GimmickyApps/ScaleHuh/issues/3

I've tried everything I could think of with cameras and scales and I could not seem to figure out how to get this to work in a simple and intuitive way. I'm hoping either someone can help explain what I'm not understanding, or help fix HaxeFlixel, if necessary.

FlashDevelop 5.0.2.2, Haxe 3.2.1, flixel: [3.3.12], openfl: [3.5.3], targets on Win 7:

scalemode-centre-problem-cpp1 scalemode-centre-problem-cpp2

IBwWG commented 8 years ago

May be related to #921 and #922 but wasn't fixed, so maybe different.

Gama11 commented 8 years ago

Centering on cpp / neko works correctly on dev.

IBwWG commented 8 years ago

@Gama11 I hadn't tried neko. Did native Windows look wrong for you too, or flash?

I haven't tried the dev branch. It looked like it was difficult to have them both installed at once (should I be building the latest OpenFL too?), and I guess I had chosen stability over bleeding edge since I'm new to HaxeFlixel...then again, I'm a bit confused how everyone else was handling what I assume is not a completely obscure use scenario, without being bleeding edge. (Maybe it so happens that immersivers like me only use the dev branch?) Anyway, I'll have a look into it again.

Gama11 commented 8 years ago

Cpp and Neko behaved the same for me on 3.3.12.

OpenFL dev versions are not required for Flixel dev.

IBwWG commented 8 years ago

@Gama11 Ah I see. cpp != neko. (Neko is unfamiliar to me.)

Perfect, good to know. Thanks :)

IBwWG commented 8 years ago

OK, I switched to the dev branch, and most of my files broke due to various things having been refactored out of existence. So I'll need a bit of time to verify this and other issues using the dev branch...

As an aside, I wonder if there would be a better way to indicate things like this in the documentation, so that for folks like me who are HF newbs, they are aware that certain things in the latest 'stable' release are not actually so stable / working, and it may be worth it to start a project using HF dev. Or maybe this is just me, always trying to do something a bit differently, a strategy which will inevitably find things broken even in well-supported libs like HaxelFlixel. :) In that case, never mind...

IBwWG commented 8 years ago

I have it compiling now with the dev branch. I can confirm the issues you closed are also now in good working order. Thanks! This is also true about the above screenshots, that there's no special windows-specific centering bug, i.e. centering works on windows and flash.

As for the y=0 issue, this is still ongoing exactly as before, unfortunately, and makes it rather difficult to lay out UI elements.

IBwWG commented 8 years ago

@player-03 solved this, it's simply a matter of calling updateHitbox() on a given sprite!

Maybe I had misunderstood the term 'hitbox'. I thought it implied its use was for physics and collisions. (I've been working with Nape for physics, so I was mostly ignoring HF physics- and collision-related functions.) My understanding had been that a sprite has its graphic and its hitbox, and if the graphic is rectangular, the hitbox is the same as the graphic, whereas for non-rectangular graphics you may have a custom hitbox to make physics a little more visually understandable.

Is that correct? If so, maybe I'll add a quick note to the documentation somewhere to emphasize that in the case of scaling, hitboxes matter even if you're not using HF physics.

IBwWG commented 8 years ago

Alternatively, should updateHitbox() be automatically called on all sprites during a resize when the scale mode is StageSizeScaleMode? Would there be a reason to leave this to be done manually?

player-03 commented 8 years ago

Based on the code comments, it used to be done automatically. I suspect it was removed to optimize performance.

IBwWG commented 8 years ago

@player-03 But in the case of this particular scale mode, would one ever not need to do this? I.e. would it make sense to add it back in, but conditionally?

player-03 commented 8 years ago

It's unrelated to the scale mode. You'd see the same issues no matter what.

Gama11 commented 8 years ago

updateHitbox() happens to update offset, which determines the hitbox position in relation to the graphic. sprite.y actually refers to the y position of the hitbox, not the graphic itself, which is why your graphic wasn't positioned at 0 with y == 0 - the hitbox was:

Setting sprite.origin.y to 0 seems to help.

This has nothing to do with scale modes.

IBwWG commented 8 years ago

I think I understand now a bit more, although I'm not sure how I'd set origin.y when it's read-only.

I guess because you closed this @Gama11 you wouldn't want me to change the docs in any way? I.e. am I alone in not understanding any of this at first? :-) (To be sure, I'm happy just to have a working solution now, but I wonder if some future person in my position could be aided with a note or two somewhere. At the very least this will show up in search results, anyway, but you know...)

player-03 commented 8 years ago

origin is read-only, but origin.y is not. In other words, you would not be allowed to run this code:

sprite.origin = new FlxPoint(0, 0);

...but this would be fine:

sprite.origin.y = 0;

Why is this? It's because origin is a FlxPoint object, and the FlxPoint class declares y as (default, set). So as long as you have access to the FlxPoint instance (which you do), you're allowed to use the setter for the y value.

IBwWG commented 8 years ago

@player-03 lightbulb moment. That's something I didn't know was possible in Haxe. Thanks!

I meant to also ask you, as for it not being limited to a particular scale mode, in what case would you not want to update all the hitboxes, i.e., when is the optimization of removing the autoupdate useful? (I'm not at all trying to call it useless, I'm just trying to understand things better.)

Thanks muchly you two for your explanations and patience.

player-03 commented 8 years ago

I assume it's because you might want the hitbox to be different from the graphic.

Gama11 commented 8 years ago

Yes, it wasn't an optimization (I doubt it's very expensive). It's more that setting the scale of the graphic and updating the hitbox to that scale are different things. You might only want to do the former and leave the hitbox as-is. Doing it automatically reduces flexibility in that regard.

IBwWG commented 8 years ago

Understood. Thanks again. :)