Legacy GM need help with dynamic camera boundaries

Zashiko

Member
Hey,
I'm trying to make a Camera which boundaries are dynamically changed, based on the current position of the Camera Object.
I can't get it to work how it used to be and I found nothing in the internet or in this forum for my special problem.

I try to achieve that only certain parts of a level will be visible.
for example in the picture below the empty parts of the level should never be visible, but i can't get it working the right way.

example Level for specified boundaires

The Camera Object itself is clamped to the room borders, so it can't get outside the room.

Here is the Code i got so far for the Camera Object:

Create event:
GML:
lock_x_left = false;
lock_x_right = false;
lock_y_top = false;
lock_y_bot = false;
x_cord_left = 0;
x_cord_right = 0;
y_cord_top = 0;
y_cord_bot = 0;
Step event:
GML:
if(instance_exists(Player)) {
    //move camera x
    if     (lock_x_left&&!lock_x_right) x += (x_cord_left  - x) * .4;
    else if(!lock_x_left&&lock_x_right) x += (x_cord_right - x) * .4;
    else x += (Player.x - x) * .2;

    //move camera y
    if     (lock_y_top&&!lock_y_bot) y += (y_cord_top - y) * .150;
    else if(!lock_y_top&&lock_y_bot) y += (y_cord_bot - y) * .150;
    else y += (Player.y - y) * .075;

    //define boundaries
    scr_CamBound_y(0,1024,0,"top",0);
    scr_CamBound_y(1024,3072,256,"top",0);
    scr_CamBound_y(3072,4096,512,"top",0);
    scr_CamBound_y(4096,4680,256,"top",0);
    scr_CamBound_y(4680,4864,512,"top",0);
    scr_CamBound_y(4864,6656,768,"top",0);
    scr_CamBound_y(6656,8192,1024,"top",0);
    scr_CamBound_y(8320,12800,1536,"top",0);
    scr_CamBound_y(12800,13056,1792,"top",0);

    scr_CamBound_y(0,2560,512,"bot",0);
    scr_CamBound_y(2560,4096,768,"bot",0);
    scr_CamBound_y(4096,5888,1024,"bot",0);
    scr_CamBound_y(5888,7936,1280,"bot",0);
    scr_CamBound_y(7936,11264,1792,"bot",0);
    scr_CamBound_y(11264,13056,2048,"bot",0);

    scr_CamBound_x(0,256,1024,"right",0);
    scr_CamBound_x(1024,1536,8192,"right",0);

    scr_CamBound_x(512,768,2560,"left",0);
    scr_CamBound_x(1264,1792,7936,"left",0);
}
End Step event:
GML:
///set view position
view_object[0] = noone;
view_xview[0] = x-view_wview[0]/2;
view_yview[0] = y-view_hview[0]/2;
view_xview[0] = max(0, min(room_width-view_wview[0],view_xview[0]) );
view_yview[0] = max(0, min(room_width-view_hview[0],view_yview[0]) );
Script scr_CamBound_y:
GML:
///scr_CamBound_y(x1,x2,y,top/bot,view_number);
//x1 - x2     -> range where the bound should be applied
//y           -> bound limit applied
//view_number -> the number of the view applied to camera

//additions to get to view borders
xview_add = view_wview[argument4]/2;
yview_add = view_hview[argument4]/2;

if(x+xview_add>=argument0&&x-xview_add<argument1 ) {
    if(argument3 == "top") {
        scr_update_Camera_y(true,false,argument2+yview_add,0);
    }
    if(argument3 == "bot") {
        scr_update_Camera_y(false,true,0,argument2-yview_add);
    }
}
Script scr_update_Camera_y:
GML:
///scr_update_Camera_y(lock_y_top,lock_y_bot,y_cord_top,y_cord_bot);
//lock_y_top   -> lock the top boundary
//lock_y_bot   -> lock the bot boundary
//y_cord_top   -> the top position the camera will be locked on
//y_cord_bot   -> the bottom position the camera will be locked on

//Lock Y Top
if(argument0) {
    y_cord_top = argument2;
    if(y<y_cord_top) lock_y_top = true; //move Camera if outside boundary
    else lock_y_top = false;            //free Camera if inside boundary
}

//Lock Y Bottom
if(argument1) {
    y_cord_bot = argument3;
    if(y>y_cord_bot) lock_y_bot = true; //move Camera if outside boundary
    else lock_y_bot = false;            //free Camera if inside boundary
}
The scripts scr_CamBound_x and scr_update_Camera_x and basically the same like scr_CamBound_y and scr_update_Camera_y.

the problem i get is that the boundaries change not fast enough (that means you see parts of the level which should be not seen)
and the camera gets stuck at the top boundary untill the next boundary is defined, which is obviously not what i wanted.

if I snap the boundaries directly without smoothing the camera towards it, it doesn't look nice.


I hope you understand what i mean, because my english is not the best. ^^

can anyone help me? or does anyone have other suggestions to solve this problem? I would be very thankful.
 
Last edited:

FoxyOfJungle

Kazan Games
I have a hunch, which may be considered a simple solution:



You will be able to create solid invisible objects that will act as invisible walls that collide with the camera, preventing for example the Y to pass directly.
But at the same time the camera is fixed on the player. For performance, you can disable these objects from a distance.
 

Tyg

Member
It really depends on your game

if its 2D, the camera would be the room size and you dont really need to move it,
unless your zooming in and out
to see a portion of the screen
you would move the viewport

for a 3D game you would move the camera, for angles yaw, pitch
 
Last edited:

Zashiko

Member
I have a hunch, which may be considered a simple solution:



You will be able to create solid invisible objects that will act as invisible walls that collide with the camera, preventing for example the Y to pass directly.
But at the same time the camera is fixed on the player. For performance, you can disable these objects from a distance.
Thanks for the reply.
I tried a similar solution only with code. but with that there is the snapping I was talk about.
the problem with this is that when the Player reaches the new boundary to fast the camera snaps to the defined boundary and this is what looks weird. so this is not the solution i wanted.

example
here is a gif example of what i mean

I tried:
Camera Step:
GML:
if( instance_exists(Player) ) {
    x += (Player.x - x) * .2;
    y += (Player.y - y) * .075;

    //definde boundaries
    scr_CamBound_y(0,1024,0,"top",0);
    scr_CamBound_y(1024,3072,256,"top",0);
    scr_CamBound_y(3072,4096,512,"top",0);
    scr_CamBound_y(4096,4680,256,"top",0);
    scr_CamBound_y(4680,4864,512,"top",0);
    scr_CamBound_y(4864,6656,768,"top",0);
    scr_CamBound_y(6656,8192,1024,"top",0);
    scr_CamBound_y(8320,12800,1536,"top",0);
    scr_CamBound_y(12800,13056,1792,"top",0);

    scr_CamBound_y(0,2560,512,"bot",0);
    scr_CamBound_y(2560,4096,768,"bot",0);
    scr_CamBound_y(4096,5888,1024,"bot",0);
    scr_CamBound_y(5888,7936,1280,"bot",0);
    scr_CamBound_y(7936,11264,1792,"bot",0);
    scr_CamBound_y(11264,13056,2048,"bot",0);

    scr_CamBound_x(0,256,1024,"right",0);
    scr_CamBound_x(1024,1536,8192,"right",0);

    scr_CamBound_x(512,768,2560,"left",0);
    scr_CamBound_x(1264,1792,7936,"left",0);
}
scr_CamBound_y:
GML:
///scr_CamBound_y(x1,x2,y,top/bot,view_number);

xview_add = view_wview[argument4]/2;
yview_add = view_hview[argument4]/2;

if(argument3 == "top") {
    if( x+xview_add>=argument0&&x-xview_add<argument1 && y<=argument2+yview_add && y>argument2 ) {
        y = argument2+yview_add;
    }
}
if(argument3 == "bot") {
    if( x+xview_add>=argument0&&x-xview_add<argument1 && y>=argument2-yview_add && y<argument2 ) {
        y = argument2-yview_add;
    }
}
 
Last edited:

Zashiko

Member
It really depends on your game

if its 2D, the camera would be the room size and you dont really need to move it,
unless your zooming in and out
to see a portion of the screen
you would move the viewport

for a 3D game you would move the camera, for angles yaw, pitch
it's a 2D platformer. the view dimensions are 256x224.
and i can't set the view the size of the room because there are many objects that are deactivated or destroyed when they are 100 pixels outside of the view.
 

Tyg

Member
Ok so your viewing a 256x224 sized area, that should be your viewport size
what is the room size?
Because you boundary code goes from 0 to 13000+
 
Last edited:

Zashiko

Member
Ok so your viewing a 256x224 sized area, that should be your viewport size
what is the room size?
Because you boundary code goes from 0 to 13000+
the room size is different in every level. so it doesn't really matter i think.
for this specifically level the dimensions are 13056x2048.

what will be the differene between moving the view_port and the view itself?
in both cases the boundaries should be defined..
 

Tyg

Member
Ok thats good, so you have this big level
Because the camera has a view mat and a projection mat
when you move the camera you also move the projection mat
The viewport moves the viewmat but the projection stays the same
So what im trying to say is yes, you can move the camera, but it will be all jerky because your constantly resetting the projection mat
if you move the view_port you will get smooth transitions
your stepping code will also affect this
you dont need all theese boundaries, your room size - your viewport size would be your boundary
you should project to the area and move the view not the other way around
its like your taking the camera and jerking it all over the place
unless thats what your going for
here is an example

View attachment 38228

good luck :)
 

Zashiko

Member
Ok thats good, so you have this big level
Because the camera has a view mat and a projection mat
when you move the camera you also move the projection mat
The viewport moves the viewmat but the projection stays the same
So what im trying to say is yes, you can move the camera, but it will be all jerky because your constantly resetting the projection mat
if you move the view_port you will get smooth transitions
your stepping code will also affect this
you dont need all theese boundaries, your room size - your viewport size would be your boundary
you should project to the area and move the view not the other way around
its like your taking the camera and jerking it all over the place
unless thats what your going for
here is an example

View attachment 38228

good luck :)
I don't think you understood the main problem.
I posted a gif and the map of the level itself and tried to explain how the camera should be able to move around it.

I don't understand why you telling me such a long story about basic behavior of views. This is not my problem.
I used your kind of solution but the viewport still gets into the black areas in the map i posted.
it's exact the same result when i just move the view itself.

how should the viewport know where to stop when no boundaries are defined?

i don't know if i just don't understand you right or you just don't understand me right. but when i understand it right then this solution is not a solution to my problem. :D
or can you give me an example? the picture you posted tells me nothing related to my problem.. related to views itself, yes.. but not to my problem.
 
Last edited:

Tyg

Member
I offered a dynamically changing viewport as opposed to resizing the camera projection mat
your getting black borders because you would have to change the projection mat of the camera to zoom in and out
with the viewport you could fill the screen with the desired area, thats what i was getting at

Ok, sorry was just trying to help, good luck in your development :)
 
Last edited:

Zashiko

Member
I offered a dynamically changing viewport as opposed to resizing the camera projection mat
your getting black borders because you would have to change the projection mat of the camera to zoom in and out
with the viewport you could fill the screen with the desired area, thats what i was getting at

Ok, sorry was just trying to help, good luck in your development :)
Thank you for that, but i have a different problem than that you tried to solve ^^
the view itself should not be dynamic, only the boundaries.
i don't get black borders.
the view itself should be static. without zooms or anything like this.
 
Last edited:

Tyg

Member
Well i'm not sure of the look you are going for , either zooming in and out,
it is much easier to keep your level design consistant
you can also use multiple cameras or viewports get the look you want and just switch them
are you trying to do a follow cam with resizing limiting the view area or just flipping areas
a few pictures would help

Sorry i couldnt help :)
 

Zashiko

Member
Well i'm not sure of the look you are going for , either zooming in and out,
it is much easier to keep your level design consistant
you can also use multiple cameras or viewports get the look you want and just switch them
are you trying to do a follow cam with resizing limiting the view area or just flipping areas
a few pictures would help

Sorry i couldnt help :)
i posted pictures earlier.
the map

and this is what is going to happen when the player reaches a new boundary.
the player just gets there and the view should automatically approach the new boundary that is set.
in the gif the camera/view snaps to the position. This is not what i want.

the Camera should not Zoom or anything. the Camera itself is perfect how it is.
The only problems are the boundaries and the way the Camera behaves when reaching a new boundary.
 

Zashiko

Member
What if you create a path and make a path by the level you want and just make the camera follow the path while following the player?

This is actually a nice idea 🤔
I made a path inside that level and translated the percentage x and y progress to the percentage position on the path.

like this:
GML:
x = path_get_x(Path, (Player.x/room_width) ); //% x progress translated to % on path
y = path_get_y(Path, (Player.y/room_height) ); //% y progress translated to & on path
but that seem not to work well, because my camera has smooth following and with this Code the camera is following the Player directly.

and is it possible that the Camera is able to break out of the path for example for secret ways that are outside the path?
if yes can you give an example of a Camera following a path while following the Player? ^^
 

TsukaYuriko

☄️
Forum Staff
Moderator
I've reverted a couple of posts that were nuked to their original (most recent pre-nuke) contents. Please don't do this for any reason. It's unfair towards other members who may find this topic further down the line because they're facing a similar issue.
 

Zashiko

Member
I've reverted a couple of posts that were nuked to their original (most recent pre-nuke) contents. Please don't do this for any reason. It's unfair towards other members who may find this topic further down the line because they're facing a similar issue.
this makes sense 👍
 

FoxyOfJungle

Kazan Games
That was as much as I could do:

GML:
// get path coordenates
var _px1 = path_get_point_x(path_level, 0);
var _py1 = path_get_point_x(path_level, 0);
var _px2 = path_get_point_x(path_level, path_get_number(path_level) - 1);
var _py2 = path_get_point_x(path_level, path_get_number(path_level) - 1);
var _ww = _px2 - _px1;
var _hh = _py2 - _py1;

// follow obj_player
var _pathpos = (obj_player.x - _px1) / _ww;
camTX = path_get_x(path_level, _pathpos) - camXr;
camTY = path_get_y(path_level, _pathpos) - camYr;





However, there are some problems when the path changes Y:

 
Top