• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Making backgrounds stay in camera.

I'm working on a game where the player flies inside a tower while a smaller tower looms in the background.

So far I got this.
green background parallaxes a bit, while a tower made with a sequence rotates.

I've had this problem since moving to gms2. I need a background assets to remain static in the view. But I can't figure out how to use the camera variables to do this.

The tower needs to stay in the center no matter where the player moves, but not follow this closely.. I also need to have tile it vertically when the player moves up and down. I'm looking in the manual, but I don't see any way to tile a sequence as well.

right now I'm just making the tower follow the player for example purposes.
GML:
// Auto-generated stubs for each available event.

function seq_tower_event_create()
{
xpos=1;
rate=0.5;

//add multiple towers

}

function seq_tower_event_destroy()
{

}

function seq_tower_event_clean_up()
{

}

function seq_tower_event_step()
{
    if instance_exists(oPlayer)
    {  
       
        if oPlayer.hspd>0
        {
        xpos-=rate;
        }
   
        if oPlayer.hspd<0
        {
        xpos+=rate;
        }
       
        xpos=wrap(xpos,0,60);
       
        var a = layer_get_all_elements("tower");
        for (var i = 0; i < array_length(a); i++;)
        {
        if layer_get_element_type(a[i]) == layerelementtype_sequence
            {
            layer_sequence_headpos(a[i], xpos)
             layer_sequence_x(a[i], oPlayer.x);
             layer_sequence_y(a[i], oPlayer.y+127);
            }
        }
       
    }
   
   
}

function seq_tower_event_step_begin()
{

}

function seq_tower_event_step_end()
{

}

function seq_tower_event_async_system()
{

}

I'm also guessing the camera object I'm using is also messing with how the code works. I can't tell if if my camera creates view_camera[0] or not. as using
Code:
camera_get_view_x(view_camera[0]);
just results in objects and such being stuck in the top left corner.
1615404903991.png
1615404888560.png

Code:
//create event mostly from pixelated pope.

/// @description
/// @description set up variables  

shake=true;
shakex=0;
shakey=0;
intensity=1;


camera =camera_create();



width = camera_get_view_width(view_camera[0]);
height = camera_get_view_height(view_camera[0]);






//480
//270

//1920
//1080
/*
zoomx=480
zoomy=270
*/


zoom_level = 1;
//Get the starting view size to be used for interpolation later
default_zoom_width = GUIWIDTH;
default_zoom_height = GUIHEIGHT;

zoom=true;

var vm= matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
//this creates the viewport
var pm= matrix_build_projection_ortho(default_zoom_width,default_zoom_height,1,10000);

camera_set_view_mat(camera,vm);
camera_set_proj_mat(camera,pm);

view_camera[0] =camera

target = oPlayer;
xto=x;
yto=y;

//step event

//Move the zoom level based on mouse scrolling. Clamp the value so stuff doesn't get too silly.
if zoom=true
{
zoom_level = clamp(zoom_level + (((mouse_wheel_down() - mouse_wheel_up())) * 0.1), 0.1, 5);

//Get current size
var view_w = camera_get_view_width(view_camera[0]);
var view_h = camera_get_view_height(view_camera[0]);

//Set the rate of interpolation
var rate = 0.2;

//Get new sizes by interpolating current and target zoomed size
var new_w = lerp(view_w, zoom_level * default_zoom_width, rate);
var new_h = lerp(view_h, zoom_level * default_zoom_height, rate);

//Apply the new size
if view_w != new_w && view_h != new_h
{camera_set_view_size(view_camera[0], new_w, new_h);}

}

if shake=true && alarm[0]>0
{
shakex=irandom_range(-intensity,intensity)
shakey=irandom_range(-intensity,intensity)
}
else
{shakex=0
    shakey=0}




var vm =matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
camera_set_view_mat(camera,vm);



   
var dx = (global.right - global.left);
var dy = (global.down - global.up);

var dir =0;

    if instance_exists(oMouse)
    {
    move_towards_point(oMouse.x,oMouse.y,0);
    xto=target.x+lengthdir_x(min(100,distance_to_point(mouse_x,mouse_y)),direction);
    yto=target.y+lengthdir_y(min(100,distance_to_point(mouse_x,mouse_y)),direction);
    }
else if instance_exists(oPlayer)
{

    if (dx != 0 || dy != 0) {       
         dir = point_direction(0, 0, dx, dy);
        xto= oPlayer.x+lengthdir_x(15,dir);
        yto=oPlayer.y+lengthdir_y(15,dir);

                             }
                            else
                            {
                            xto=oPlayer.x;
                            yto=oPlayer.y;
                           
                            }

   

}

        x +=((xto-x)/8);
        y +=((yto-y)/8);
 
Last edited:

jo-thijs

Member
I'm working on a game where the player flies inside a tower while a smaller tower looms in the background.

So far I got this.
green background parallaxes a bit, while a tower made with a sequence rotates.

I've had this problem since moving to gms2. I need a background assets to remain static in the view. But I can't figure out how to use the camera variables to do this.

The tower needs to stay in the center no matter where the player moves, but not follow this closely.. I also need to have tile it vertically when the player moves up and down. I'm looking in the manual, but I don't see any way to tile a sequence as well.

right now I'm just making the tower follow the player for example purposes.
GML:
// Auto-generated stubs for each available event.

function seq_tower_event_create()
{
xpos=1;
rate=0.5;

//add multiple towers

}

function seq_tower_event_destroy()
{

}

function seq_tower_event_clean_up()
{

}

function seq_tower_event_step()
{
    if instance_exists(oPlayer)
    { 
      
        if oPlayer.hspd>0
        {
        xpos-=rate;
        }
  
        if oPlayer.hspd<0
        {
        xpos+=rate;
        }
      
        xpos=wrap(xpos,0,60);
      
        var a = layer_get_all_elements("tower");
        for (var i = 0; i < array_length(a); i++;)
        {
        if layer_get_element_type(a[i]) == layerelementtype_sequence
            {
            layer_sequence_headpos(a[i], xpos)
             layer_sequence_x(a[i], oPlayer.x);
             layer_sequence_y(a[i], oPlayer.y+127);
            }
        }
      
    }
  
  
}

function seq_tower_event_step_begin()
{

}

function seq_tower_event_step_end()
{

}

function seq_tower_event_async_system()
{

}

I'm also guessing the camera object I'm using is also messing with how the code works. I can't tell if if my camera creates view_camera[0] or not. as using
Code:
camera_get_view_x(view_camera[0]);
just results in objects and such being stuck in the top left corner.

Code:
//create event mostly from pixelated pope.

/// @description
/// @description set up variables 

shake=true;
shakex=0;
shakey=0;
intensity=1;


camera =camera_create();



width = camera_get_view_width(view_camera[0]);
height = camera_get_view_height(view_camera[0]);






//480
//270

//1920
//1080
/*
zoomx=480
zoomy=270
*/


zoom_level = 1;
//Get the starting view size to be used for interpolation later
default_zoom_width = GUIWIDTH;
default_zoom_height = GUIHEIGHT;

zoom=true;

var vm= matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
//this creates the viewport
var pm= matrix_build_projection_ortho(default_zoom_width,default_zoom_height,1,10000);

camera_set_view_mat(camera,vm);
camera_set_proj_mat(camera,pm);

view_camera[0] =camera

target = oPlayer;
xto=x;
yto=y;

//step event

//Move the zoom level based on mouse scrolling. Clamp the value so stuff doesn't get too silly.
if zoom=true
{
zoom_level = clamp(zoom_level + (((mouse_wheel_down() - mouse_wheel_up())) * 0.1), 0.1, 5);

//Get current size
var view_w = camera_get_view_width(view_camera[0]);
var view_h = camera_get_view_height(view_camera[0]);

//Set the rate of interpolation
var rate = 0.2;

//Get new sizes by interpolating current and target zoomed size
var new_w = lerp(view_w, zoom_level * default_zoom_width, rate);
var new_h = lerp(view_h, zoom_level * default_zoom_height, rate);

//Apply the new size
if view_w != new_w && view_h != new_h
{camera_set_view_size(view_camera[0], new_w, new_h);}

}

if shake=true && alarm[0]>0
{
shakex=irandom_range(-intensity,intensity)
shakey=irandom_range(-intensity,intensity)
}
else
{shakex=0
    shakey=0}




var vm =matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
camera_set_view_mat(camera,vm);



  
var dx = (global.right - global.left);
var dy = (global.down - global.up);

var dir =0;

    if instance_exists(oMouse)
    {
    move_towards_point(oMouse.x,oMouse.y,0);
    xto=target.x+lengthdir_x(min(100,distance_to_point(mouse_x,mouse_y)),direction);
    yto=target.y+lengthdir_y(min(100,distance_to_point(mouse_x,mouse_y)),direction);
    }
else if instance_exists(oPlayer)
{

    if (dx != 0 || dy != 0) {      
         dir = point_direction(0, 0, dx, dy);
        xto= oPlayer.x+lengthdir_x(15,dir);
        yto=oPlayer.y+lengthdir_y(15,dir);

                             }
                            else
                            {
                            xto=oPlayer.x;
                            yto=oPlayer.y;
                          
                            }

  

}

        x +=((xto-x)/8);
        y +=((yto-y)/8);
First up: how to use cameras.
You're currently using camera_create to create your camera and you're setting the view using camera_set_view/projection_mat.
As per the docs, camera_get_view_x/y doesn't work for cameras created using this function.
In your case, it's probably easier to create the cameras using camera_create_view (and not use the camera_set_view/projection_mat functions).
This creates a camera that behaves like in GM:S 1.4 and you can just simply use camera_get_view_x/y to get the view position to draw the static background image on.

Secondly: how to tile sequences.
This is the first time I ever heard about GameMaker sequences.
I would suggest to just use the same sequence multiple times at different y coordinates to make it tile.

I hope this helps!
If you have any questions, feel free to ask them!
 
First up: how to use cameras.
You're currently using camera_create to create your camera and you're setting the view using camera_set_view/projection_mat.
As per the docs, camera_get_view_x/y doesn't work for cameras created using this function.
In your case, it's probably easier to create the cameras using camera_create_view (and not use the camera_set_view/projection_mat functions).
This creates a camera that behaves like in GM:S 1.4 and you can just simply use camera_get_view_x/y to get the view position to draw the static background image on.

Secondly: how to tile sequences.
This is the first time I ever heard about GameMaker sequences.
I would suggest to just use the same sequence multiple times at different y coordinates to make it tile.

I hope this helps!
If you have any questions, feel free to ask them!
To be honest I don't really read up the manual unless I middle click on something I furgot. It's so boring to study.

But I didn't know that about cameras. I've been using this one for so long I haven't bothered trying something different. I'll look into this.
 
yeah camera_create_view(); works for this a lot better now.
Along with getting the center point of the camera and room center to parallax the tower a bit.

 
Top