(Complicated) Matching mini-map with scale

Not favoritedFavorited Favorited 0 favourites
  • 13 posts
From the Asset Store
Two types of minimap: "full map" and "player is the center" (square map and radial map)
  • I want to be able to interact with my world while using a mini-map.

    I've attached an example showing what I'm aiming for. It all works fine at 1x scale, but the moment I try something else, everything breaks.

    Can anyone have a look at this code and let me know what I'm doing wrong?

    https://1drv.ms/u/c/45d17dca4e466456/EW2nb7BZfLZAleIZ3m_iZo4B6Tze1yNAjJ7SFCeAFNLrUQ?e=qFLbR1

  • Try this:

    -> OffScreenMouse: Set position to (lerp(SmallScreen2.BBoxRight, SmallScreen2.BBoxLeft, unlerp(SmallScreen.BBoxTop, SmallScreen.BBoxBottom, LayerToLayerY(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y))), lerp(SmallScreen2.BBoxTop, SmallScreen2.BBoxBottom, unlerp(SmallScreen.BBoxLeft, SmallScreen.BBoxRight, LayerToLayerX(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y))))

    {"is-c3-clipboard-data":true,"type":"actions","items":[{"id":"set-position","objectClass":"OffScreenMouse","parameters":{"x":"lerp(SmallScreen2.BBoxRight, SmallScreen2.BBoxLeft, unlerp(SmallScreen.BBoxTop, SmallScreen.BBoxBottom, LayerToLayerY(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y)))","y":"lerp(SmallScreen2.BBoxTop, SmallScreen2.BBoxBottom, unlerp(SmallScreen.BBoxLeft, SmallScreen.BBoxRight, LayerToLayerX(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y)))"}}]}
    
  • I want to be able to interact with my world while using a mini-map.

    I've attached an example showing what I'm aiming for. It all works fine at 1x scale, but the moment I try something else, everything breaks.

    Can anyone have a look at this code and let me know what I'm doing wrong?

    https://1drv.ms/u/c/45d17dca4e466456/EW2nb7BZfLZAleIZ3m_iZo4B6Tze1yNAjJ7SFCeAFNLrUQ?e=qFLbR1

    I don't know why your map has a different shape than the surface and I don't understand why the actions on the map are inverted along the coordinate axes. Perhaps something happened to your hero in the story.

    I tried to make a simple example.

    fex.net/s/73anrpo

  • So the black oval is like a scaled version of the screen rotated 90 degrees, and you want the mouse over that to translate to a position over the view?

    Let’s try and simplify it a bit first. If you make the oval not rotated and move the origin to the center then the calculated xy position on the view would be:

    (Mouse.x(1)-oval.x)/oval.width*viewportWidth(0)+scrollx

    (Mouse.y(1)-oval.y)/oval.height*viewportHeight(0)+scrolly

    Note: mouse.x(1) is the mouse position on the hud layer.

    Now let’s make it work if the oval is rotated 270 degrees like you have. Basically (x,y) rotated -90 will become (y,-x), but you have it vertically flipped (y,x). So swapping things around a bit the xy formulas will be:

    (Mouse.y(1)-oval.y)/oval.width *viewportWidth(0)+scrollx

    (Mouse.x(1)-oval.x)/oval.height *viewportHeight(0)+scrolly

  • So the black oval is like a scaled version of the screen rotated 90 degrees, and you want the mouse over that to translate to a position over the view?

    Let’s try and simplify it a bit first. If you make the oval not rotated and move the origin to the center then the calculated xy position on the view would be:

    (Mouse.x(1)-oval.x)/oval.width*viewportWidth(0)+scrollx

    (Mouse.y(1)-oval.y)/oval.height*viewportHeight(0)+scrolly

    Note: mouse.x(1) is the mouse position on the hud layer.

    Now let’s make it work if the oval is rotated 270 degrees like you have. Basically (x,y) rotated -90 will become (y,-x), but you have it vertically flipped (y,x). So swapping things around a bit the xy formulas will be:

    (Mouse.y(1)-oval.y)/oval.width *viewportWidth(0)+scrollx

    (Mouse.x(1)-oval.x)/oval.height *viewportHeight(0)+scrolly

    I'm afraid I struggled to follow this. I ended up with:

    {
     "is-c3-clipboard-data": true,
     "type": "events",
     "items": [
     {
     "eventType": "block",
     "conditions": [
     {
     "id": "every-tick",
     "objectClass": "System"
     }
     ],
     "actions": [
     {
     "id": "set-position",
     "objectClass": "OffscreenMouse",
     "parameters": {
     "x": "((OnscreenMouse.Y - SmallScreen.Y) / SmallScreen.Width) * ViewportWidth(0) + ScrollX",
     "y": "((OnscreenMouse.X - SmallScreen.X) / SmallScreen.Height) * ViewportHeight(0) + ScrollY"
     }
     }
     ]
     }
     ]
    }
    

    which didn't work. I'm assuming I did something obvious wrong.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I don't know why your map has a different shape than the surface and I don't understand why the actions on the map are inverted along the coordinate axes. Perhaps something happened to your hero in the story.

    I tried to make a simple example.

    https://fex.net/s/73anrpo

    Lol, yeah, our hero has problems XD

    This worked well for scale, but I note you added in a lot of variables and disabled the scrolling aspect of my code. The moment I put that back in, your version stopped working :(

  • Try this:

    -> OffScreenMouse: Set position to (lerp(SmallScreen2.BBoxRight, SmallScreen2.BBoxLeft, unlerp(SmallScreen.BBoxTop, SmallScreen.BBoxBottom, LayerToLayerY(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y))), lerp(SmallScreen2.BBoxTop, SmallScreen2.BBoxBottom, unlerp(SmallScreen.BBoxLeft, SmallScreen.BBoxRight, LayerToLayerX(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y))))

    > {"is-c3-clipboard-data":true,"type":"actions","items":[{"id":"set-position","objectClass":"OffScreenMouse","parameters":{"x":"lerp(SmallScreen2.BBoxRight, SmallScreen2.BBoxLeft, unlerp(SmallScreen.BBoxTop, SmallScreen.BBoxBottom, LayerToLayerY(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y)))","y":"lerp(SmallScreen2.BBoxTop, SmallScreen2.BBoxBottom, unlerp(SmallScreen.BBoxLeft, SmallScreen.BBoxRight, LayerToLayerX(OnscreenMouse.LayerName, SmallScreen.LayerName, OnscreenMouse.X, OnscreenMouse.Y)))"}}]}
    

    This works perfectly, no matter the scale and the scroll. Impressive.

    I don't understand how the magic is working, because I don't understand lerp and unlerp, but it does work no matter what I throw at it. Tempted to add rotation to it to see if it continues to work :D

    I wonder if this is the simplest way to do it. Rojo's words seem to suggest I've overcomplicated things. I try to avoid using variables, and this seems smart, but I'm going to have to sit down and tinker with it to better understand it.

    Thank you.

    Edit - Rotation does indeed break it XD But that wasn't what I was trying to learn, so it's still perfect.

  • ChatGPT explains it better than I could ever do :)

    Explanation:

    LayerToLayerY(...)

    Converts the Y coordinate of the OnscreenMouse sprite from its current layer to the coordinate system of the SmallScreen layer. This gives you the mouse's vertical position as if it were on the SmallScreen layer.

    unlerp(SmallScreen.BBoxTop, SmallScreen.BBoxBottom, <converted Y>)

    Calculates how far vertically the converted mouse Y-position is within the bounds of the SmallScreen sprite.

    If the mouse is at the top of the sprite, this returns ~0.

    If it's at the bottom, this returns ~1.

    If it's halfway down, this returns ~0.5.

    So the result is a normalized vertical position from 0 (top) to 1 (bottom), relative to SmallScreen.

    lerp(SmallScreen2.BBoxRight, SmallScreen2.BBoxLeft, <normalized Y>)

    Now this takes that normalized vertical position and maps it horizontally within the SmallScreen2 sprite — specifically, from its right edge (0) to its left edge (1).

    This is effectively flipping the Y-position into an X-position, which may be used for something like a sideways scrolling effect, or rotating the screen logic 90 degrees.

    Summary in Plain English:

    This expression finds how far down the mouse is on the SmallScreen sprite (top to bottom as 0 to 1), then uses that value to pick a corresponding horizontal position from right to left across the SmallScreen2 sprite.

    You could say:

    “This calculates the vertical position of the mouse relative to SmallScreen, then maps that position to a horizontal coordinate across SmallScreen2, from its right edge to its left edge.”

  • This worked well for scale, but I note you added in a lot of variables and disabled the scrolling aspect of my code. The moment I put that back in, your version stopped working :(

    This is an example and it would be more convenient for me to do it through variables than to directly insert the parameters of objects into the formula.

    You didn't say anything about the scrolling, you only talked about the scale.

  • OnscreenMouse.x/y should be the coords on the hud layer, but since it’s on a normal layer you’ll need to convert it with the layerToLayer expression or just use mouse.x(“hud”) or mouse.x(1) which gets the mouse position on the hud layer which is cleaner.

    Considering your replies to the other examples it sounds like you want something different than what I suggested. More like mapping a position on the oval on the hud to a position on the other oval on the layout.

    If that’s the case then you needn’t worry about the view size, scale or scroll position.

    Relevant change to my suggestion would be to replace the view size and scroll position with the layout ovals size and position.

    And to handle the ovals being rotated? Well it involves some trig or we could utilize the move at angle action to avoid it a bit.

  • Since you mentioned rotation, here is an example of one way to do it that handles either oval being rotated. And as mentioned in the previous post it is completely independent of view scale, scrolling or rotation. The math is done across three actions to be more readable since combining it into one formula isn't very pretty. The trig functions are just used to rotate the xy position.

    dropbox.com/scl/fi/f30qzkjny5nl2fed85udn/map_map_to_layout.capx

  • This is an example and it would be more convenient for me to do it through variables than to directly insert the parameters of objects into the formula.

    You didn't say anything about the scrolling, you only talked about the scale.

    Don't get me wrong, I appreciate the help, but what I essentially said was "How do I get this current version of my program to work with scale."

    It's like if I was making a platformer, and asked "How do I make him jump?" and you add in the jump, but remove the ability to walk.

    Again, as I said, I appreciate the attempt, but I'd have thought it's implied that I didn't want the other features of the program removed.

    Not to worry, thanks again for the help :)

  • Since you mentioned rotation, here is an example of one way to do it that handles either oval being rotated. And as mentioned in the previous post it is completely independent of view scale, scrolling or rotation. The math is done across three actions to be more readable since combining it into one formula isn't very pretty. The trig functions are just used to rotate the xy position.

    https://www.dropbox.com/scl/fi/f30qzkjny5nl2fed85udn/map_map_to_layout.capx?rlkey=jz3bnfrrrfxqca247o12ibprp&st=bffq95ky

    Wow! This is impressive! It works with scale and scrolling. That is remarkable. Thank you!

    I'm going to have to spend some time studying this. Love it!

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)