GM:S 1.4 Punching/ One Click Sprite Animation

Discussion in 'Programming' started by Yoo, Jun 21, 2016.

  1. Yoo

    Yoo Guest

    Hi, I have a somewhat simple question, but seems like a complicated task to do. I've created an animation (sprite) for my character when he is idle. I've attached it to an object. I've also created an animation (sprite) for a punch. I've added it to the object, however...

    What to do so that, once I click a button on a keyboard... for instance space, an object/character does that action once? One click on the button, one loop of the animation/sprite. Because what I've managed to do is that only while holding a space bar down, the sprite changes from idle to the punching sprite, and once I've released it, it stops. Also, if I click very quickly on the space bar it doesn't give the full sprite animation, but only partial, as for long as I am holding the button. I want to just click the space bar once and sprite animation happens. One click, one animation.

    How to do that?

    EDIT: Basically what I did is I've added an animated idle sprite to the object, then I've added 'Key Press' for space and 'Change the sprite into...' my punch animation. Then I've added 'Key Release' for space and 'Change the sprite into...' idle animation.
     
    Last edited by a moderator: Jun 21, 2016
  2. TsukaYuriko

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,626
    You seem to have the beginning down already, so let's work on the ending: There's an Animation End event which you can use to execute code (in this case, to reset the sprite, subimage and animation speed).

    You should also check whether the animation is already running before starting it when pressing Space, as you would otherwise be able to restart it halfway through by pressing Space again (unless that's what you want).
     
  3. johnwo

    johnwo Member

    Joined:
    Jun 20, 2016
    Posts:
    239
    Using the press/release method might work for you, but you could also do something like:

    On press:
    Code:
    if sprite_index == spr_player_punch then exit; // Exits the event if already punching
    sprite_index = spr_player_punch;
    On animation end:
    Code:
    if sprite_index == spr_player_punch {
        sprite_index = spr_player_idle;
    }
    
    Best of luck!

    Cheers!

    EDIT:
    Seems like I got ninja'd...
     
  4. Zekka

    Zekka Guest

    Usually, in response to Key Press: Space, you set the sprite_index to the sprite that contains the animation, the image_index to 0 (so that the animation will start from its first frame), the image_speed to 1 (so that the animation will play at one-frame-per-step), and you set some instance variable to indicate the character is currently punching.

    Then, in the Animation End event, you check whether the character is currently punching, and if so, set the character to idle, return to idle sprite, image index, and image speed.

    Using `image_index == 0` in Step, rather than Animation End, is another way to do this that lets you put all your code in the same place. (Disclaimer: did not test in GM)

    Code:
    // this goes in your Step event
    if (state == "idle") {
      if (keyboard_check_pressed(vk_space)) {
        state = "punching";
    
        sprite_index = spr_punching;
        // NOTE: If you never change this to something other than 1, you can leave this next line out.
        // But I prefer to leave it in so that if I add an animation with
        //   image_speed = something other than 1, that doesn't break anything
        image_speed = 1;
        image_index = 0;
      }
    } else if (state == "punching") {
      // This code won't get run on the same step you press space while in "idle" state
      // So this check only triggers if we just hit the last frame of the animation and looped around
      if (image_index == 0) {
        state = "idle";
    
        sprite_index = spr_idle;
        image_speed = 1;
        image_index = 0;
      }
    }
    
    (Strictly speaking, you can factor out `state` and use `sprite_index` as state. But I usually prefer to keep them separate in case I want to briefly change sprite_index for a graphical effect, or provide an alternate spriteset, etc.)
     
  5. Yoo

    Yoo Guest

    Well, what I've managed to do, with using the least amount of coding if possible (I'm sorry for that) is... I've created an object with Idle Sprite animation. Created a new object with Punch animation. Assigned a keyboard key to an object with the idle animation. In Keyboard Event, under Actions, I've added 'Change Instance into...' the object with a punch animation (Perform events: yes). On the object with a punch animation I've added Animation End, and under Actions placed 'Change Instance into...' the object with an idle animation (Perform events: yes). And it works... But only in one direction :D. So if idle object is facing right, and I am moving my character to the left for instance, and the punch animation is to the right as well (assigned to the idle object), he will punch in the right direction, and then stay in idle position facing right, because that's what is 'Change instance into...' is telling him. Can I somehow using these Change instances, alter them so that they are responsive to the direction object is facing? I have animated sprites for all the directions, moving punching and everything. Just the problem now is how to connect them... If there is no other way than coding, please try to suggest something simple, if you know, and that can be added to this particular situation. Thanx.

    EDIT: Sorry if my explanation is a bit... ugh.
     
  6. Zekka

    Zekka Guest

    It's not really a problem if you don't want to write code imho -- that's one of the things GM is designed to be good at doing. (Although I think it's kind of sad that you can't do all the code things using just D&D.) You could still do the bulk of my solution in D&D, I think, but yours will probably work too. (It'll get a little bit ugly once you have an awful lot of Change Instance: object types though.)

    If you want to do this using Change Instance, you can pre-check whether hspeed is less than 0 (which means "moving left"), greater than 0 (which means "moving right") or 0. hspeed is a builtin variable present for any Game Maker object, and I believe there are still D&D actions that let you specify "check if variable is greater" or "check if variable is less."

    If you're using a system other than builtin speed/direction (like if you're just subtracting 4 from x whenever player hits left), replace hspeed with (xprevious - x) in all these examples. Most of the GM actions that expect a variable, if I remember right, will also be able to take a simple calculation like that, but it's been a while since I tried it.

    By the way, if you're curious (you don't have to be curious) someone wrote a program that rewrites your D&D as GML. You don't have to use the generated code, but it might help you learn GML if you're at all interested in doing that. Most D&D operations correspond very closely to one or two GML operations, so the translation is actually pretty direct in most cases.
     
  7. Yoo

    Yoo Guest

    What's the program?
     
  8. Zekka

    Zekka Guest

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