Looking up/down

Discussion in 'Programming' started by Jscoombs, Jul 23, 2019.

  1. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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!
     
  2. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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
     
  3. Bayesian

    Bayesian Member

    Joined:
    Sep 13, 2016
    Posts:
    423
    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
        }
    }
     
  4. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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.
     
  5. Bayesian

    Bayesian Member

    Joined:
    Sep 13, 2016
    Posts:
    423
    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?
     
  6. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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
     
  7. Bayesian

    Bayesian Member

    Joined:
    Sep 13, 2016
    Posts:
    423
    Yeah sounds about right. Try it out and let me know if it works.
     
  8. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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
     
    Bayesian likes this.
  9. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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.
     
  10. Bayesian

    Bayesian Member

    Joined:
    Sep 13, 2016
    Posts:
    423
    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);
    
    
     
  11. Jscoombs

    Jscoombs Member

    Joined:
    Feb 17, 2019
    Posts:
    10
    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!
     
    Bayesian likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice