Legacy GM [Kinda solved] Camera object disapearing between rooms

V

VicoZann

Guest
So I have a camera object that is created by the player character on his create event. The object is persistent and follows him around like a good camera should do. But if I enter a door to another room, the camera disapears/stops working (I'm not sure what's the problem)

The player has a follower that I made the same way as the camera. Creates it in his create event, follows him around, is persistent and that works just fine. I go to another room, the follower is there, like a good old follower.

The 2 images I uploaded contain all the code for the camera and the creation of both the camera and follower, along with their object window for referencing. If anyone know what's going on, I'd appreciate the help
 

Attachments

jo-thijs

Member
So, your problem isn't the camera disappearing (as that would throw an error),
but either there being multiple camera instances messing up your code or there being some room settings being set incorrectly (which is what I'm guessing).
Is obBlue also a persistent object? Is it created only once?
Are room views set to follow the camera object in the room editors?
 
V

VicoZann

Guest
So, your problem isn't the camera disappearing (as that would throw an error),
but either there being multiple camera instances messing up your code or there being some room settings being set incorrectly (which is what I'm guessing).
Is obBlue also a persistent object? Is it created only once?
Are room views set to follow the camera object in the room editors?
obBlue is also persistent. He's warped, not recreated in the other room.
I'm set the room view to follow the camera object through code, not the actual room options.
Also, both rooms should have the same settings, since the second one was a copy of the first just for the purpose of testing
 

jo-thijs

Member
Then that's your problem.
You should set view_object to cam in the room start event, not the create event.
 
V

VicoZann

Guest
Then that's your problem.
You should set view_object to cam in the room start event, not the create event.

Seens like it worked, but when I enter the other room, view starts at a default position and then moves to the player, since the way I made it work makes it move smoothly. Any way to make it so the room of the view aways defaults to the camera object?
 

jo-thijs

Member
Sure, execute this in the room start event as well:
Code:
view_xview = clamp(cam.x - (view_wview div 2), 0, room_width - view_wview);
view_yview = clamp(cam.y - (view_hview div 2), 0, room_height - view_hview);
 
V

VicoZann

Guest
Sure, execute this in the room start event as well:
Code:
view_xview = clamp(cam.x - (view_wview div 2), 0, room_width - view_wview);
view_yview = clamp(cam.y - (view_hview div 2), 0, room_height - view_hview);
Didn't work. The view still starts at the top left of the room and then quickly moves to the player
 

jo-thijs

Member
Then either this code isn't executed at the correct time or this code is being undone by some other code.
I would need more information to say what exactly causes it to not work.
 
V

VicoZann

Guest
Any idea where to look at? Everything that has any relation to the camera is in those SS from my first post.
 

jo-thijs

Member
Oh, in that case the views are acting fine, but your camera isn't.
Just set cam.x and cam.y to your player's coordinates in the room start event.
 
V

VicoZann

Guest
I don't think that's the case. The camera object is created at the player's coordinates right from the start.
The thing is that the camera moves relatively slowly and the default view of the rooms is the top left corner, so that everytime I enter a room, the view beggins there and then moves to the actual position of the camera. The view needs to be set to to player from the start to fix this (I guess). But I don't know how to make this work
 

jo-thijs

Member
Can you give the object information (text that appears when you click on "object information" when editing an object) of everything camera related?
 

hippyman

Member
Did you set the view to the camera's position at game start also? It could be that you are setting the camera's position but it's waiting a step to move the view to the proper position.

i.e.
Game Start Event:
Code:
var inst = instance_create(player.x,player.y,Camera);
view_xview[0] = Camera.x;
view_yview[0] = Camera.y;
 
V

VicoZann

Guest
Can you give the object information (text that appears when you click on "object information" when editing an object) of everything camera related?
Do you mean this wall of text? If so, I suppose the Player object it the only thing camera related

Information about object: obBlue
Sprite: spr_blue_idle
Solid: false
Visible: true
Depth: 0
Persistent: true
Parent:
Children:
Mask: spPlayer_Mask
No Physics Object
Create Event:
execute code:

///Initialize Player

// creates companion
instance_create(x,y,obWhite);


//Enumerations
enum PLAYER_STATE //Each state is assigned the index of the corresponding script.
{ //This means that to execute the correct state we can use
normal = PlayerState_Normal, //script_execute(state) rather than a switch statement.
ledge_grab = PlayerState_LedgeGrab,
swim = PlayerState_Swim,
climb = PlayerState_Climb,
wall_jump = PlayerState_WallJump,
defense = PlayerState_Defense,
atk = PlayerState_Atk,
followup = PlayerState_FollowUp,
slide = PlayerState_Slide,
ledge_climb = PlayerState_LedgeClimb,
badge = PlayerState_Badge
}
enum PLAYER_ACTION //This is used simply as a way of telling what the player is
{ //doing to avoid having to put animation, sound or effects
stand, //code into the state scripts. This keeps everything tidy.
run,
sprint, //It would also allow some more flexability if you need to
jump, //know what player is doing.
fall,
atk,
runningatk,
ledge_grab,
ledge_climb,
float,
swim,
hold,
climb,
traverse,
wall_slide,
wall_jump,
wall_run,
stop,
land,
defense,
defensew,
slide,
badge
}

//Objects
object_solid = obSolid; //These are all of the environment objects that the player can
object_fluid = obFluid; //interact with.
object_ladder = obLadder; //object_solid is the only required object. The others should
object_wall = obWall; //be assigned the keyword 'noone' if you do not require them.
object_slider = obSlider;

//Inputs
input_left = false; //These are the character controls, assigned in the step event
input_right = false; //code and later referenced in the player state scripts.
input_up = false; //To change the control keys you should look at the step event.
input_down = false;
input_jump = false;
input_defense = false;
input_atk = false;

//Player State Variables
state = PLAYER_STATE.normal; //These variables are used to keep track of the player's
action = PLAYER_ACTION.stand; //basic control statistics.
facing = 1; //The facing variable determines whether the player is facing
grounded = false; //left or right (-1 or 1). The grounded variable determines
xspeed = 0; //whether the player is on the ground or not (true or false).
yspeed = 0;
xspeed_carry = 0;
yspeed_carry = 0;

can_turn = true;
can_move = true;
can_ledge_climb = true;
can_ledge_grab = true; //All of these boolean values allow you to switch off specific
can_swim = true; //states. This allows you to easily implement unlockable
can_climb = true; //skills.
can_wall_slide = true;
can_wall_jump = true;
can_wall_run = true;
can_atk = true;
can_block = true;
can_stand = true;
can_stop = false;
can_dashatk = true;
can_slide = true;
can_move = true;
near_edge = false;
onrightslope = false;
onleftslope = false;


//Horizontal Movement
regular_speed = 3
run_speed = regular_speed;

sprint_speed = 1; //adds to the regular running speed
defense_speed = 1;
swim_speed = 1;
traverse_speed = 1; //When moving sideways on a ladder object.
wall_jump_speed = 4; //The horizontal speed when jumping off a wall.



//Vertical Movement
grav = 0.3;
wall_friction = 0.5;
jump_height = 38;
runatk_height = 10;
jump_number = 1; //How many times the player can jump (eg 2 = double jump).
jump_current = 0; //This is a counter and should be left at 0.
density = 0.7; //The density variable affects how deep the player floats in a fluid object.
float_damping = 0.08; //Effectively water friction. Higher value will simulate thicker fluid.
climb_speed = 2;
wall_slide_speed = 1;
wall_jump_height = 32;
wall_run_speed = 2;

hang_height = 46; //How many pixels below the ledge the player will hang.


//gamepad deadzone

gamepad_set_axis_deadzone(0,0.4);

execute code:

///create camera


instance_create(x,y,obj_cam); // create the camera object at the player's location
cam = obj_cam;


view_hborder = view_wview/2; //set the view's horizontal border to keep the camera object centered
view_vborder = view_hview/2; // set the view's vertical border to keep the camera object centered

// Initialize Camera Variables

h_dist = 50; // set how far away horizontally the camera should be from the player
v_dist = 50; // set how far away vertically the camera should be from the player
cam.xTo = x + h_dist; // set the cam's initial xTo position
cam.yTo = y - v_dist; // set the cam's initial yTo position
peek = sprite_width + 1; // set the distance to check if a player is looking over a ledge
cam_spd = 5; // set how quickly the cam should move. The lower this value is, the quicker the camera will move

Alarm Event for alarm 1:
execute code:

//can_wall_slide = true;


//ground slide
if(state == PLAYER_STATE.slide)
{
state = PLAYER_STATE.normal;
mask_index = spPlayer_Mask;
exit;
}

Alarm Event for alarm 2:
execute code:

yspeed = 0;
state = PLAYER_STATE.normal;
exit;

Step Event:
execute code:

///main functions

//pauses animation
if(global.pause == 1)
{
image_speed = 0;
exit;
}


///Process Player

//Get User Input
input_left = keyboard_check_direct(vk_left) || (gamepad_axis_value(0,gp_axislh) < 0);
input_right = keyboard_check_direct(vk_right) || (gamepad_axis_value(0,gp_axislh) > 0);
input_up = keyboard_check_direct(vk_up) || (gamepad_axis_value(0,gp_axislv) < 0);
input_down = keyboard_check_direct(vk_down) || (gamepad_axis_value(0,gp_axislv) > 0);
input_jump = keyboard_check_pressed(vk_space) || (gamepad_button_check_pressed(0,gp_face1));
input_jump_held = keyboard_check(vk_space) || (gamepad_button_check(0,gp_face1));
input_defense = keyboard_check_direct(vk_lcontrol) || (gamepad_button_check(0,gp_shoulderr));
input_sprint = keyboard_check_direct(vk_lshift) || (gamepad_button_check(0,gp_shoulderl));
input_atk = keyboard_check_pressed(ord("S")) || (gamepad_button_check_pressed(0,gp_face4));
release_left = keyboard_check_released(vk_left);
release_right = keyboard_check_released(vk_right);
input_badge = keyboard_check_pressed(ord("D")) || (gamepad_button_check(0,gp_face2));


//camera

//camera_movement();


//depth
if(input_sprint || obWhite.state == WHITE_STATE.atk || obWhite.state == WHITE_STATE.airatk)
{
depth = -1;
}
else
{
depth = -2;
}


//collision


if(place_meeting(x, y + 1, object_solid))
{
grounded = true;
}
else
{
grounded = false;
}

script_execute(state);

if(xspeed != 0 && can_turn && (input_right || input_left)) //If the xspeed variable is not 0 it means
{ //either the left or right key has been pressed
facing = sign(xspeed); //and so we can change the facing direction.
}

xspeed_final = xspeed + xspeed_carry;
xspeed_carry = 0;



//slope

if(place_meeting(x, y + 1, obSlope_Left))
{
onleftslope = true;
}
else onleftslope = false;

if(place_meeting(x, y + 1, obSlope_Right))
{
onrightslope = true;
}
else onrightslope = false;


//Horizontal Collision and Movement

if (grounded && xspeed != 0)
{
can_stand = false;
can_stop = true;
}

//makes character move up slopes
if(place_meeting(x + xspeed_final, y, object_solid))
{
yplus = 0;
while (place_meeting(x+xspeed_final,y-yplus,object_solid ) && yplus <= abs(1*xspeed_final)) yplus += 1;
if place_meeting(x+xspeed_final,y-yplus,object_solid )
{
while(!place_meeting(x + sign(xspeed_final), y, object_solid))
{
x += sign(xspeed_final);
}
xspeed_final = 0;
xspeed = 0;
}
else
{
y -= yplus;
}
}



//makes character move down slopes
else
{
yMinus = 0;
while(!place_meeting(x+xspeed_final,y+yMinus,object_solid) && yMinus <= abs(1*xspeed))
{
yMinus +=1;
}
//still not sure why exactly this needs to be here, but it does for math reasons.
yMinus -= 1;

//if there is a place of meeting at yMinus (speed+1) but not at yMinus (speed) AND we're already on the ground, move down
if(place_meeting(x+xspeed_final, round(y+yMinus)+1,object_solid) && !place_meeting(x+xspeed_final, round(y+yMinus),object_solid) && place_meeting(x, y+1,object_solid))
{
y = round(y+yMinus);
}
}
x += xspeed_final;








//Vertical Collision and Movement
if(place_meeting(x, y + yspeed, object_solid))
{
while(!place_meeting(x, y + sign(yspeed), object_solid))
{
y += sign(yspeed);
}
yspeed = 0;
}
y += yspeed;




//Sprite and Animation
switch(action) //The switch statement checks the value of
{ //'action' and then will perform the
case PLAYER_ACTION.stand: //corresponding case.
sprite_index = spr_blue_idle;
image_speed = 5 / room_speed;
break;

case PLAYER_ACTION.run:
sprite_index = spr_blue_run;
image_speed = 12 / room_speed;
break;

case PLAYER_ACTION.badge:
sprite_index = spr_blue_badge;
image_speed = 15 / room_speed;
break;

case PLAYER_ACTION.sprint:
sprite_index = spr_blue_run;
image_speed = 15 / room_speed;
break;

case PLAYER_ACTION.atk:
sprite_index = spr_blue_heavyatk;
image_speed = 18 / room_speed;
break;

case PLAYER_ACTION.runningatk:
sprite_index = spr_blue_runatk;
image_speed = 15 / room_speed;
break;

case PLAYER_ACTION.jump:
sprite_index = spr_blue_jstart;
image_speed = 5 / room_speed;
break;

case PLAYER_ACTION.fall:
sprite_index = spr_blue_jmid;
image_speed = 5 / room_speed;
break;

case PLAYER_ACTION.defense:
sprite_index = spr_blue_block;
image_speed = 10 / room_speed;
break;

case PLAYER_ACTION.defensew:
sprite_index = spr_blue_blockwalk;
image_speed = 10 / room_speed;
exit;

case PLAYER_ACTION.ledge_grab:
sprite_index = spr_blue_ledgegrab;
image_speed = 10 / room_speed;
break;

case PLAYER_ACTION.ledge_climb:
sprite_index = spr_blue_ledge_climb;
image_speed = 9 / room_speed;
break;

/*case PLAYER_ACTION.float:
sprite_index = spPlayer_Float;
image_speed = 5 / room_speed;
break;
*/
/*case PLAYER_ACTION.swim:
sprite_index = spPlayer_Swim;
image_speed = 7 / room_speed;
break;
*/
/* case PLAYER_ACTION.hold:
sprite_index = spPlayer_Hold;
image_speed = 5 / room_speed;
break;
*/
/* case PLAYER_ACTION.climb:
sprite_index = spPlayer_Climb;
if(yspeed < 0)
{
image_speed = 6 / room_speed;
}
else
{
image_speed = -6 / room_speed;
}
break;
*/

/*case PLAYER_ACTION.traverse:
sprite_index = spPlayer_Traverse;
image_speed = 6 / room_speed;
break;
*/

case PLAYER_ACTION.wall_slide:
sprite_index = spr_blue_wallslide;
image_speed = 10 / room_speed;
break;

case PLAYER_ACTION.wall_run:
sprite_index = spr_blue_wallrun;
image_speed = 10 / room_speed;
break;

case PLAYER_ACTION.wall_jump:
sprite_index = spr_blue_jstart;
image_speed = 5 / room_speed;
break;

case PLAYER_ACTION.stop:
sprite_index = spr_blue_stop;
image_speed = 15 / room_speed;
break;

case PLAYER_ACTION.slide:
sprite_index = spr_blue_slide;
image_speed = 10 / room_speed;
break;

}

execute code:

///Move Camera




if(input_sprint)
{
h_dist = 130;
}
else
{
h_dist = 50;
}




// by default, look far in the direction the player is facing and slightly upward
cam.xTo = x + facing*h_dist;
cam.yTo = y - v_dist;

// if standing near a cliff and holding down, camera moves down a bit
if(grounded)
{
if(input_down)
{
if(!place_meeting(x+30*facing, y+peek, obSolid))
{
cam.xTo = x + facing*peek;
cam.yTo = y + v_dist*2;
}
}
}
//falling camera
if(!grounded)
{
if(yspeed >= 7)
{
cam.xTo = x + facing*peek;
cam.yTo = y + v_dist*1.7;
}
}
// wallsliding camera
if(action == PLAYER_ACTION.wall_slide || action == PLAYER_ACTION.wall_run)
{
cam.xTo = x + facing*h_dist;
cam.yTo = y;
}


//move the camera

cam.x += (cam.xTo-cam.x)/cam_spd;
cam.y += (cam.yTo-cam.y)/cam_spd;

Collision Event with object obDoor:
execute code:

/// go to next room

if(room_exists(other.new_room))
{
room_goto (other.new_room);
x = other.new_x;
y = other.new_y;
}

Other Event: Room Start:
execute code:

view_xview = clamp(cam.x - (view_wview div 2), 0, room_width - view_wview);
view_yview = clamp(cam.y - (view_hview div 2), 0, room_height - view_hview);

view_object = cam;



Other Event: Animation End:
execute code:

///reverse state to normal


//attack
if (state == PLAYER_STATE.atk)
{
state = PLAYER_STATE.normal;
}
//stopping animation trigger
if ((action == PLAYER_ACTION.stop) || (action == PLAYER_ACTION.atk))
{
can_stop = false;
can_stand = true;
}

if (action == PLAYER_ACTION.atk)
{
can_dashatk = true;
}

//ledge climb
if (state == PLAYER_STATE.ledge_climb)
{




obBlue.x = obBlue.x+(20*facing);
obBlue.y = obBlue.y-46;
yspeed += grav;
can_wall_slide = true;



state = PLAYER_STATE.normal;
obWhite.x = obBlue.x+(30*facing);
obWhite.y = obBlue.y;
obWhite.state = WHITE_STATE.normal;
obWhite.action = WHITE_ACTION.stand;

if(!obWhite.grounded)
{
obWhite.y += 1;
}
if(obWhite.grounded)
{
obWhite.y +=0;
}


exit;
}

//badge

if (state == PLAYER_STATE.badge)
{
state = PLAYER_STATE.normal;
}


Draw Event:
execute code:

///Draw Player

draw_sprite_ext(sprite_index, image_index, round(x), round(y), facing, image_yscale, image_angle, c_white, 1);
 

jo-thijs

Member
My guess was right though, when changing rooms, you set the player's coordinates to new_x and new_y of the door object.
However, you never set the camera coordinates to this.
 
V

VicoZann

Guest
Doesn't the camera follows along by itself with the regular code?
 
V

VicoZann

Guest
Alright I fixed this in and absolutely not ideal way. I start the rooms with the camera speed set to it's fastest so it will instantly move the view to the correct place and, with an alarm, I set it back to the intended speed so everything works just fine. I'm pretty sure there's a better way to make this, but yeah, if it works it works
 
Z

Zaeith

Guest
Alright I fixed this in and absolutely not ideal way. I start the rooms with the camera speed set to it's fastest so it will instantly move the view to the correct place and, with an alarm, I set it back to the intended speed so everything works just fine. I'm pretty sure there's a better way to make this, but yeah, if it works it works
So, you are correct. Your Camera object's coordinates in the new room have not changed from the old room. Thus, the Camera object is far from the player and your solution works. As @jo-thijs has been mentioning, you could set the Camera object's coordinates to your Camera's relative position near the player on "Warp." That is, if you camera was xx pixels to the right of the player and yy pixels above the player, then it should warp to coordinates that xx pixels to the right of the player and yy pixels above the player.

So, although your solution works, you might experience a flicker when the player changes rooms. It may be worth warping the Camera to those relative coordinates.
 
Top