-
-
Notifications
You must be signed in to change notification settings - Fork 646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Background image placement at a low ratio #741
Comments
Yep, I saw the same thing. It's caused by the way the viewport extents are scaled. I'll see what I can do to make it better. |
To solve this one, I'm going to define some test cases, and derive the expected equation that way. There is likely a better approach, but this will do for now. The GoalI have three rectangles:
The viewport window size is <= the viewport boundary, and is allowed to move freely inside the viewport boundary. The image layer is allowed to be any size, and is also allowed to be positioned arbitrarily, including outside of the viewport bounds. The goal is to adjust the position of the image layer based on three inputs:
The ProblemHaving three variables control the image layer position adjustment is a bit painful. Imagining the image layer's final position as an offset of its initial position simplifies things (removes the initial position as another variable). The viewport window position and scrolling ratio are very easy to deal with; just multiply them together. The anchor point is where things get tricky, because the image layer is required to scroll backwards when anchored to the bottom/right corner of the viewport bounds... as we will see. The Anchor PointThe Platformer 2 example was created in part to demonstrate an image layer being anchored to the bottom of the viewport bounds; the bottom of the dark blue mountain background needs to be aligned with the bottom of the viewport bounds when the viewport window is scrolled to the bottom. And thus when the viewport scrolls up, the background scrolls up as well. This presents the first challenge:
This is counter to what other maps will need; imagine a vertical level where the player starts at the top and goes down. In this case, a parallax background most certainly needs to be anchored to the top:
Our unit vector anchor point can give us this flexibility. But how does the math work? The Test CasesBelow are two data sets (along the Y-axis), followed by description of the state (image layer final position) expected for these configurations when the viewport is at the top and the bottom. These test cases show the complexity that is added by the anchor point input.
For all final states, subtract the viewport position to translate it to screen coordinates. (Historically, In other words, the initial position is only used when the ratio between (the viewport window's position and the viewport bounds) matches the anchor point. The ProcessGiven the above goals and test cases, let's define an equation that matches our needs:
The additive and subtractive expressions are now just a matter of scaling the viewport position by the inverse of the scrolling ratio. We arrive at the final equation: this.offset.y - (bh - viewport.height - vpos.y) * (1 - ry) * ay + vpos.y * (1 - ry) * (1 - ay) - vpos.y Simplified by Wolfram Alpha: ay * (ry - 1) * (bh - viewport.height) + this.offset.y - ry * vpos.y EndAll that's left to do is remove the "position is the anchor point" hack from #737 (because they are distinct inputs). With that, here's a patch: diff --git a/src/level/TMXLayer.js b/src/level/TMXLayer.js
index 5bc11ec..b5662a3 100644
--- a/src/level/TMXLayer.js
+++ b/src/level/TMXLayer.js
@@ -99,6 +99,8 @@
// displaying order
this.pos.z = settings.z || 0;
+ this.offset = new me.Vector2d(x, y);
+
/**
* Define the image scrolling ratio<br>
* Scrolling speed is defined by multiplying the viewport delta position (e.g. followed entity) by the specified ratio.
@@ -123,9 +125,6 @@
}
if (typeof(settings.anchorPoint) === "undefined") {
- var aw = me.game.viewport.bounds.width - this.imagewidth,
- ah = me.game.viewport.bounds.height - this.imageheight;
-
/**
* Define how the image is anchored to the viewport bounds<br>
* By default, its upper-left corner is anchored to the viewport bounds upper left corner.<br>
@@ -142,10 +141,7 @@
* @default <0.0,0.0>
* @name me.ImageLayer#anchorPoint
*/
- this.anchorPoint.set(
- aw ? x / aw : 0,
- ah ? y / ah : 0
- );
+ this.anchorPoint.set(0, 0);
}
else {
if (typeof(settings.anchorPoint) === "number") {
@@ -277,8 +271,9 @@
* direction when anchored to the bottom or right sides of the
* viewport boundary.
*/
- x = ~~(-ax * (1 - rx) * (bw - viewport.width) + ax * (bw - width) - vpos.x * rx),
- y = ~~(-ay * (1 - ry) * (bh - viewport.height) + ay * (bh - height) - vpos.y * ry);
+ x = ~~(ax * (rx - 1) * (bw - viewport.width) + this.offset.x - rx * vpos.x),
+ y = ~~(ay * (ry - 1) * (bh - viewport.height) + this.offset.y - ry * vpos.y);
// Repeat horizontally; start drawing from left boundary @Giwayume Please let me know if this resolves the issue. |
is the wolfram calculator/optimizer (or whatever it should be called) really reliable ? |
The ratios have flipped back again to 1 being attached to the viewport. Is that intentional? Also you can't get rid of the width/height variables because of the background repeating code. This works, but in practice it's a little odd because all the backgrounds need to be placed in relation to <0,0> in the room. This is fine if you're imagining the viewport being positioned there when constructing the level. Hope the Tiled guys work on that camera feature! |
I've made the correction to the patch for the width/height variables. Not sure about the ratio being flipped. If you're talking about the background moving at the same speed as the viewport when Background positioning with parallax is not easy to imagine. I agree having this feature in the editor is the best way to make a level designer's life easier. Until then, you have to make a mental map of the viewport "window" while designing, and configure the It's much more difficult when the viewport is somewhere in the center of the map. But if you have an idea of where the viewport is going to be, the exact anchorPoint is easy to calculate. (It's the same math as before.) You could even simulate it a bit if you want a quick hack; Create a semitransparent image to represent your viewport (it should be roughly the same size as your viewport), and insert it into the map as an image layer. You can position the layer where you expect the viewport to be located at runtime, and fill in the variables in the following equation:
Hide the viewport image when you're done (if you want to reuse it later) and set the background layer's Does that help at all? |
I only mentioned them being flipped because you flipped them in the last patch, intentionally or not. 0 was acting as 1 and 1 as 0. I get how it's supposed to work I'm just thinking it may be a bit confusing to new users. I may go make an attempt at that camera patch on the Tiled side... |
I didn't notice the behavior of There is more configuration involved (it was attempting to be purely automated previously). So if you miss that extra configuration step of positioning the layer when you set the Really, we're just trying to find the right compromise. It's still not going to be super easy to reason about, but that's what the editor is for. |
No, the ratio was flipped, not the anchorPoint. Sorry if I'm being confusing. There was a 1-rx and 1-ry. |
Oh, my mistake... I tested the ratio quite heavily. Like I commented, it works as intended; |
Well dammit. You were right all along. |
This is a continuation of #737.
Upon testing with a background image of ratio 0.1 (mostly sticks to the view but slightly moves), it seems the lower I place the background in Tiled (high y values), the higher it ends up in the game.
So if I place the background at the top of the screen in tiled it will be at the bottom of the screen in the game and vice a versa.
The text was updated successfully, but these errors were encountered: