How do I use DragCameraExtension in a container within a unique scene?

Hello, my goal is to use this extension: DragCamera.

However, I want to use it in a specific container of the screen (the highlighted element in the screenshot):

Basically, the user could drag another camera only within the highlighted container you can see in the screenshot. It would act like a map of some kind for my game, where the user could see the entirety of the world.

It would be like having a scene within another one. I’m having trouble describing my goal I hope it’s clear. Thank you.

Note that the texts and everything you see in the screenshot are on the layer “UI”. It’s the menu that sits on top of the player when they press the “Escape” key.

Condition
LMB or touch is on CONTAINER

And in action you allow to drag camera on layer you want

Hi,

first, a little question, what’s LMB? x)

Here is the event I added after your answer:

Second, it’s not quite what I’m trying to achieve. It’s one step, but it’s not where I’m stuck.

I’m struggling with the camera movements being limited to the borders of the static container. The container itself shall not move. So far, I’ve placed the container, and its content, to a new layer, on top of the everything else, named “StarMap”.

The issue right now is that the container isn’t static. I can drag it around on the screen right now.

Also, the content of the container can exit the container when dragged around ;( (but I want them to be hidden if they are out of view)

Left Mouse Button
IF you want container not to move you drag every layer you want to move
But not layer on which container is

Also at this point idk if drag camera is best option for you
I would consider multi touch joystick extension or built in one


And either leave it visible so ppl see there is a joystick to use
Or make it invisible but at the size of container
So you would like fake camera dragging with container

And for joystick you simply set it to move camera in some direction based on which direction it is pulled

For example if pulled to the right you would go with change camera X position add 10
If pulled left change camera X position subtract 10

And do it only on layers you want to move

I do not understand what you mean with

Hi, thank you, I’ll try that.

When I said “the content of the container can exit the container” I meant that by dragging the camera within the container, the elements inside the container can currently leave the container. Basically, this container is a map, and like any map in a game, there are points, markers, places, and a red dot to indicate the position of the player for example, etc. But the map in my game is kinda huge, hence this topic. When dragging the camera, I don’t want the elements within the map to be visible outside of the container. Imagine the container to be the screen, well sometimes you have objects outside of the screen that should be hidden.

There is also one last issue: borders. The map isn’t infinite, so I don’t want the player to be able to drag the camera within this container indefinitely. To do that, I guess I’ll have to use another camera number and set borders to this one, but I’m not sure, right now it’s almost 1 a.m so I’ll test this tomorrow.

Uu now i get what you mean and what you are trying to achieve

To answer your 1st question
You need to have have your map and all that indicators and crap on layer which is below on the list of layer of your UI layer
By ui layer i mean in your 1st post you pasted screenshot
You have there black background that covers everything and just have cut out box for map
So layer with that black background need to be above layer of map and eventually layer with any kind of indicator

So if you look on layer list it should be

UI
Markers
Indicators
StarMap

In this order

And now when you use drag actions in events you simply need to add action for each layer you want to move

To answer your 2nd question

There are 2 things you need to do
1 - There is condition camera X position and same for Y
Now for you to understand
Value of X which is - means more to the left so -10 means move 10 pixels to the left
While +10 will mean move 10 pixels to the right
Now for Y - means go up + go down

Armed with that knowledge you add conditions to event where you drag camera
Camera X position is higher than > SOME VALUE
Camera X position is lower than < SOME VALUE
And same for Y

And now you need to find these values

You are looking for value on the right side so it will be higher than + something
Looking for lower than you are looking for - value on the left

This way you are checking if camera X is between some X position and not outside of it
IF you do the same for Y you created virtual box in which camera will be able to be dragged
Meaning if you drag your camera outside of that virtual box you will stop dragging from working

2nd thing
Using same values or little closer to center value by let’s say 5 or 10 pixels (just for example)

You do like
Condition
Camera X position is lower than < X - some value (checking if camera is moved too far to the left)
In action you change camera position to X add + 20 for example
This way if you move camera too far to the left it will be moved back to the right 20 pixels enabling again camera dragging

Now you do another event (for each side here you need separate event)
Condition
Camera X position is higher than > X + some value
Action
Change camera X position - Subtract 20

And you repeat process for Y
Basically you invert here checking higher than > and < lower than to what i wrote in 1st point of this post
Because in there you were creating virtual box inside which camera will be allowed to be dragged
Here you check OUTSIDE of this box if camera went outside of that virtual box and do your movement logic to it

For you to have easy time

  • DO NOT do all sides all at once
    Prepare events for one side then test it and if it work you move to preparing events for next side
  • Start with stoping camera events
    Once you got that right you can use same values for moving camera back inside virtual box
  • If you FOR EXAMPLE stop camera on X -1000 (meaning it is too far to the left)
    You use that -1000 for your change camera position event
    But i would suggest instead of going
    Conditon
    Camera X position is lower than < X-1000
    Going with X-995
    For example so you leave yourself some extra space before you hit dead end
    Then in action change camera X position +add 10 or 20
    And that 10 or 20 needs to be higher number than difference between where you turn of camera dragging and camera position check for moving it back into virtual box
  • In this case it is 5 since -1000 and -995
    IDK what would be better here 10 or 20 maybe even 7 would be good for your
    You need to find your numbers yourself
    I simply described logic for you and i hope you get all that
  • I intentionally typed it in words and signs and double checked if i am correct on each part
    Higher than is >
    Lower than is <
    Do not mess it up or you will not get it working
    Or simply like i said do one side at a time and then you can mix > or <
    It is like either option A or option B will work so you can only make mistake once for each side

And as my last words trust me
Most important thing here
ONE THING AT A TIME then test if it works or not

I have a quick and dirty example similar to what you’re looking for using one layer, Draggable Behavior and the Object Masking extension. It is not exactly what you want since I didn’t use the Drag Camera extension, but the Object Masking bit and the calculations used to keep the image constrained in the container may still be useful. If you’d like to check it out I have the project file here:

Map Drag Example by lucky-j (itch.io)

1 Like

Object masking works only for one object
And from his description seems his objects are not part of map
But just attached objects to map

But rest is perfectly fine

Hello, thank you for your help. I managed to make my own solution based on your ideas:

I have absolutely no idea why and how the camera boundaries work but apparently this nonsense allows me, if the user drags the contents too far from the borders, to automatically teleport them to the boundaries. This way, the user cannot drag the elements forever and lose them:

The way I detect when the elements are outside the virtual box is by using the extension “is on screen” but slightly modified. I’m comfortable with JavaScript so it was easier for me to just edit the extension’s code:

/*
Get the object layer, convert the position from this layer to the container coordinates.
Get the point on each side on the object on screen, and compare with the container area.

This way even if the camera has a rotation or custom scale the object is always compared to the container area.
*/

/**
 * @param {gdjs.RuntimeObject} object
 * @returns {{left:number, right:number, up:number, down:number}}
 */
function getCornersOfObject(object) {
    const layer = runtimeScene.getLayer(object.getLayer());

    // Get the aabb of the object on his layer.
    const aabb = object.getVisibilityAABB();

    // Get the layer to convert the coordinates of the AABB to the screen coordinates
    const topLeft = layer.convertInverseCoords(aabb.min[0], aabb.min[1]);
    const topRight = layer.convertInverseCoords(aabb.max[0], aabb.min[1]);
    const bottomRight = layer.convertInverseCoords(aabb.max[0], aabb.max[1]);
    const bottomLeft = layer.convertInverseCoords(aabb.min[0], aabb.max[1]);

    // Get the points on each side of the object on screen.
    const posLeftObjectOnScreen = Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]);
    const posRightObjectOnScreen = Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]);
    const posUpObjectOnScreen = Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]);
    const posDownObjectOnScreen = Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]);

    return {
        left: posLeftObjectOnScreen,
        right: posRightObjectOnScreen,
        up: posUpObjectOnScreen,
        down: posDownObjectOnScreen
    };
}

// The container (the fake screen)
const container = eventsFunctionContext.getObjects("ContainerObject")[0];

// Get the layer of the target object, which is the object to have the behaviour.
const targetObject = objects[0];
const targetBorders = getCornersOfObject(targetObject);
const containerBorders = getCornersOfObject(container);

const padding = eventsFunctionContext.getArgument("Padding");

if (
    !(targetBorders.left - padding > containerBorders.right ||
        targetBorders.up - padding > containerBorders.down ||
        targetBorders.right + padding < containerBorders.left ||
        targetBorders.down + padding < containerBorders.up
        )
) {
    eventsFunctionContext.returnValue = true;
}

If an object gets out of the container, then a condition detects it and applies a tween on the opacity property. It’s not very clean as you can see the objects getting out of the box and slowly fading, it would be better to cut the image as you’d expect on a normal screen, but it does the job.

In my humble opinion, I think it’s the easiest way to go with. If you have some new ideas, let me know.

Thanks again.

1 Like