Looking up/down

J

Jscoombs

Guest
Hello everyone.
I am making a platformer game and I want the player to be able to look up or down while holding the up or down key for a few seconds. I haven't done much with alarms, so I don't totally understand them. I have the camera movements working, but I'm not sure how to implement an alarm so that it happens after holding the button for 3 seconds. I'm typing this on my phone so I don't really have my code for examples, but I'm hoping someone can help me understand the logic behind alarms. Thanks in advance!
 
J

Jscoombs

Guest
To elaborate, I want something a bit like this:

Camera Object Step:
Code:
If (keyboard_check_pressed(ord("W")))
{
 alarm[0] = 5 * roomspeed
}
Alarm[0] Event:
Code:
Camera.y + 50
 
B

Bayesian

Guest
Alarms are just timers. The code in them triggers once the time reaches 0 and they count down automatically. In the code you posted the alarm event will happen 5 seconds after the W key goes down. Its not making sure the play has continuously held the key for 3 seconds like you want. Alarms won't be the best thing to use for that case. Instead you can check for frames that the W key is held down with a normal keyboard_check. Each frame that it is true that W is held down count another variable up. Then check if that variable is equal to 3 * roomspeed for 3 seconds and then move the camera. You need to clear the counting variable so that its ready to count again. keyboard_check_released() is a good time to do that. We can also use a flag to make sure the camera only moves up once then we disable our code that moves it.

Code:
if(keyboard_check(ord("W"))){
    upHeldCount ++
}
if(keyboard_check_released(ord("W"))){
    upHeldFlag = false
    upHeldCount = 0
}
if(upHeldCount==3*room_speed){
    if(!upHeldFlag){
        upHeldFlag = true
        //Move camera
    }
}
 
J

Jscoombs

Guest
Alarms are just timers. The code in them triggers once the time reaches 0 and they count down automatically. In the code you posted the alarm event will happen 5 seconds after the W key goes down. Its not making sure the play has continuously held the key for 3 seconds like you want. Alarms won't be the best thing to use for that case. Instead you can check for frames that the W key is held down with a normal keyboard_check. Each frame that it is true that W is held down count another variable up. Then check if that variable is equal to 3 * roomspeed for 3 seconds and then move the camera. You need to clear the counting variable so that its ready to count again. keyboard_check_released() is a good time to do that. We can also use a flag to make sure the camera only moves up once then we disable our code that moves it.

Code:
if(keyboard_check(ord("W"))){
    upHeldCount ++
}
if(keyboard_check_released(ord("W"))){
    upHeldFlag = false
    upHeldCount = 0
}
if(upHeldCount==3*room_speed){
    if(!upHeldFlag){
        upHeldFlag = true
        //Move camera
    }
}
Thank you so much for the quick reply. Your explanation was thorough and pretty simple to understand. What I'm not really understanding though, is what the Flag is exactly. Is that just a variable that becomes true if we've hit our target number, and false if not? It does seem to work, but the camera doesn't stay in position while holding the up key, its just goes to those coordinates for a second before returning to follow the player. I'm not sure if I'm missing something or not. Here's my code for my camera:

Obj Camera Create:
Code:
camera = camera_create();

var vm = matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
var pm = matrix_build_projection_ortho(178,112,1,10000);

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

view_camera[0] = camera;

follow = obj_player;
xTo = x;
yTo = y;

upHeldCount = 0;
upHeldFlag = false;
Obj Camera Step:

Code:
x += (xTo - x)/8;
y += (yTo - y)/15;

if (follow != noone)
{
    xTo = follow.x;
    yTo = follow.y;
}


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

//Look Up/Down

if (keyboard_check(ord("W"))) //if we are holding the up key
{
    upHeldCount ++;            //Increase the count for holding up key
}

if (keyboard_check_released(ord("W"))) //if we release the up key
{
    upHeldFlag = false;                   
    upHeldCount = 0;                    //return count to zero
}
if (upHeldCount == 3 * room_speed)        //if we are at target count
{
    if (!upHeldFlag)                    //and flag is false
    {
        upHeldFlag = true;                //set flag to be true
        xTo = follow.x;               
        yTo = follow.y-30;    //set camera position 30 pixels above
    }
}
Thank you very much for your help, I really appreciate it.
 
B

Bayesian

Guest
What I'm not really understanding though, is what the Flag is exactly. Is that just a variable that becomes true if we've hit our target number, and false if not?
Sorry it might have made more sense if I didn't invert it the way I did. But basically it get set once we meet our condition then reset once we've used it. Flags are generally useful concepts to guarantee that code only gets run once or selectively ignored based on other conditions.

yTo = needs to be only set once then applied to x then applied to the matrix last. A state machine may help with that. Do you know how to make one with enums and switch statements?
 
J

Jscoombs

Guest
Sorry it might have made more sense if I didn't invert it the way I did. But basically it get set once we meet our condition then reset once we've used it. Flags are generally useful concepts to guarantee that code only gets run once or selectively ignored based on other conditions.

yTo = needs to be only set once then applied to x then applied to the matrix last. A state machine may help with that. Do you know how to make one with enums and switch statements?
Okay, I think I understand a bit better now. I am still fairly new to state machines, but I have used them for idle, attack and chase states. If I'm thinking about this correctly, wouldn't I set up enums in the cameras create event, then assign each state a script in the step event? Like 'case Camera State.LookUp: scr_lookup. So, I would have to check for the flag, then if it's true, run the look up script? I hope that makes sense.
Sorry if my reply seems messy, I don't have my computer in front of me so I'm trying my best to work this out in my head. Thanks again for the help
 
B

Bayesian

Guest
If I'm thinking about this correctly, wouldn't I set up enums in the cameras create event, then assign each state a script in the step event? Like 'case Camera State.LookUp: scr_lookup. So, I would have to check for the flag, then if it's true, run the look up script?
Yeah sounds about right. Try it out and let me know if it works.
 
J

Jscoombs

Guest
Hello again! So, after fiddling with this for a bit, I seem to have it working properly. I'm still unsure if my code is organized properly however. Here's what I've got working at the moment:

Obj_Camera Create Event:
Code:
state = CAMERASTATE.FREE
camera = camera_create();

var vm = matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
var pm = matrix_build_projection_ortho(178,112,1,10000);

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

view_camera[0] = camera;

follow = obj_player;
xTo = x;
yTo = y;

upHeldCount = 0;
upHeldFlag = false;

enum CAMERASTATE
{
    FREE,
    LOOKUP
}
Obj_Camera Step Event:
Code:
x += (xTo - x)/8;
y += (yTo - y)/15;

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

switch (state)
{
    case CAMERASTATE.LOOKUP: scr_camera_lookup() break;   
    case CAMERASTATE.FREE: scr_camera_free() break;
}
//Look Up/Down

if (keyboard_check(ord("W"))) //if we are holding the up key
{
    upHeldCount ++;            //Increase the count for holding up key
}
else
{
    upHeldCount = 0;   
}

if (upHeldCount == 3 * room_speed)        //if we are at target count
{
    if (!upHeldFlag)                    //and flag is false
    {
        state = CAMERASTATE.LOOKUP;
    }
}
scr_camera_free:
Code:
if (follow != noone)
{
    xTo = follow.x;
    yTo = follow.y;
}
scr_camera_lookup:
Code:
upHeldFlag = true;    //set flag to be true
xTo = follow.x;               
yTo = follow.y-50;    //set camera position 30 pixels above

if (keyboard_check_released(ord("W")))
{
    upHeldFlag = false;
    upHeldCount = 0;
    state = CAMERASTATE.FREE;
}
This is all working perfectly, but I kinda feel like it could be more organized. I have a feeling that I'm putting something in the wrong place here, even though it's working fine, but I could be wrong. Thank you for all your help Bayesian, I've learned a couple things from you and for that I am very grateful :D
 
J

Jscoombs

Guest
Hmm.. Actually, after some more modifying and testing, I've added a duplicate script for lookdown, but it seems I can only enter each state once. I'm not sure why that is, but I'm going to attempt to mess with it a bit more and see if I can get this working properly.
 
B

Bayesian

Guest
The only thing I'd change is again to apply x/yTo to x/y then apply it to the matrix last.

edit: see comments for details
Code:
//Set State first
//Look Up/Down

if (keyboard_check(ord("W"))) //if we are holding the up key
{
    upHeldCount ++;            //Increase the count for holding up key
}
else
{
    upHeldCount = 0;  
}

if (upHeldCount == 3 * room_speed)        //if we are at target count
{
    if (!upHeldFlag)                    //and flag is false
    {
        state = CAMERASTATE.LOOKUP;
    }
}

//Apply State Second to set x/yTo
switch (state)
{
    case CAMERASTATE.LOOKUP: scr_camera_lookup() break;  
    case CAMERASTATE.FREE: scr_camera_free() break;
}

//Apply x/yTo to x/y Thrid
x += (xTo - x)/8;
y += (yTo - y)/15;

//All calculations are done, apply to matrix Last
var vm = matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
camera_set_view_mat(camera,vm);
 
J

Jscoombs

Guest
Oh, I see what you mean now. I'll go do that now. As for my other issue, I combed through everything and found a typo that was causing it. I had a downflag variable where an upflag variable should have been. Works great now, no issues!
 
Top