Code for animation end

S

Sam Atkins

Guest
So, in lieu of Gamemaker providing a logical selection box to solve this, this is the code I'm trying to use within an object to stop an animation after it played once. There is the object, under which is a "space bar " event. Inside this is a "Set Sprite" event that instructs Gamemaker-2 to play the animation sprite. And under that an "Execute Code" box containing the following:

if(sprite_index = Firk)
if ( image_number = 4)
then { image_speed = 0}

......unfortunately this is still not stopping the animation sequence. Any ideas?
 
W

whale_cancer

Guest
Code:
if(sprite_index = Firk)
if ( image_number = 4)
then { image_speed = 0}
Are you manually using image_number to set which frame is being animated? If not, you need to use image_index instead of image_number.

There is an "animation_end" event under "other." When I am doing what you are trying to do, I merely use that event and set the image_speed to 0 and image_index to the last image in the sprite (if you don't do that, it resets back to 0 iirc)
 
S

Sam Atkins

Guest
Thanks guys! Tried them both in the Execute Code box just underneath and linked to the Set Sprite box, and still no stop to the looping. Any further suggestions?
 

TheouAegis

Member
if image_index + image_speed >= image_number
image_speed = 0;

That should stop the sprite on the very last frame on the STEP just before it loops.
 
T

Timze

Guest
Sounds like you need a true / false variable to turn it on or off.
Is your attack sprite in the same sprite as idle or separate?
Had this same problem not long ago and this worked. Maybe it can help you connect some dots? notes added after ///

Create
Code:
image_speed = 0 ;
attack = mouse_check_button(mb_left); /// Change this to a keyboard check for the spacebar.
can_attack = true


Step

Code:
  //check for player input and if player is allowed to attack
        if mouse_check_button (mb_left) && (can_attack == true) /// change this to a keyboard check for space bar
        {
            sprite_index = spr_plyr_atk;           //change sprite to attacking sprite /// or keep sprite index the same if your animated sprites are in 1 sprite file
            image_index = 0;                           //set sprite index to 1st frame /// if animation in same sprite set first frame of that space bar animation
            image_speed = 1.5;                         //set animation speed
            can_attack = false;                        //turn off player attack input
        }

        //check if current sprite is in attack and that animation is finished
        if (sprite_index == spr_plyr_atk) && (image_index > (16)) /// set to your main index if only 1 sprite. Change the number in brackets by the image index to the last image of your attack / space bar animation. if this doesn't work duplicate your last space bar animation frame and paste. then select the 2nd last frame of animation.
 
        {
            image_speed = 0;             //stop animation
            sprite_index = spr_plyr;   //set sprite to player idle
            can_attack = true;           //enable player input
 
        }
If you play with this a while and it's still not working tell me which frames this space bar animation is suppose to play. when does it start when does it end. Are they in the same sprite or are they separate? If separate what is the name of each sprite and do those names indicate what the action is about? (walking, attacking, etc)
 
Last edited by a moderator:
S

Sam Atkins

Guest
Thanks TheoAegis, but that one failed too....lol. Timze thanks for your code outline. I have two separate sprites. The main submarine image named "Firkmain" which is just one sprite. In the event list of Firkmain is the Spacebar event which has the sub element called "setSprite" which succesfuly changes Firkmain to "Firk" which is the four image diving sprite that works but loops eternally. Hope that helps. So would your create and step items be a new "event" or a code execution box tagged onto the set Sprite box? I'm trying to visualize the structure. ; )

Thanks!
 

Bentley

Member
Why not use the Animation End event, drag an execute code action, and then code:

if (sprite_index == the sprite I set it to)
{
image_index = image_number - 1; // Stops on the last frame
image_speed = 0; // Stops animation
}
 
T

Timze

Guest
Thanks TheoAegis, but that one failed too....lol. Timze thanks for your code outline. I have two separate sprites. The main submarine image named "Firkmain" which is just one sprite. In the event list of Firkmain is the Spacebar event which has the sub element called "setSprite" which succesfuly changes Firkmain to "Firk" which is the four image diving sprite that works but loops eternally. Hope that helps. So would your create and step items be a new "event" or a code execution box tagged onto the set Sprite box? I'm trying to visualize the structure. ; )

Thanks!


Code:
        if (sprite_index == firk) && (image_index >= (4))
        {
            image_speed = 0;             //stop animation
            sprite_index =Firkmain;   //set sprite to player idle 
        }

or if you want it to stop on the last frame


Code:
                if (sprite_index == Firk) && (image_index > (4))
 
        {
            image_speed = 0;             //stop animation
            sprite_index= Firk;   // on last frame of Firk (duplicate frame 4 in the sprite so you have a total of 5 frames. 5th being the same as the 4th)
        
        }
That should stop the looping. I'm still pretty noob at coding but i hope this works for you lol
 
S

Sam Atkins

Guest
Bentley and Timze, thanks again! Bentley your solution did the trick! I am not done with all of this objects' animations yet though, and I may be tacking some more elements onto this framework. Actually the ultimate goal is a timer that then plays the surfacing animation after 3 to 5 seconds....but I'm taking baby steps. ;) But suggestions are welcome as that's the next trick to figure. Thanks again!

S.
 
Last edited by a moderator:
S

Sam Atkins

Guest
So....a brief question regarding an Objects' Events and sub-events. I apologize if this is a dunderheaded question but I'm still trying to wrap my head around when something needs to be a distinct "Event" within an Object or a sub-event within an already existing Event within the object. For instance....the "Animation End" event that I just got to work from all of the assistance above (thanks again to all who chimed in)......why did this have to be created as a new Event and not instead be a sub event within the Keystroke Event that caused the animation to play in the first place? Seems logical to me that it would reside in the tree of things that happen related to the keystroke, not a separate and new "event entity." This is confusing me now as to when to create "Events" and when to try and make things happen within an already existing one? Does this make sense? I currently have no rule of thumb to go by.....lol . I'm somewhat confuzzed. How do you guys determine when to make this distinction and do you have a personal methodology you go by?

Merci beaucoup ; )
 
Last edited by a moderator:

TheouAegis

Member
So if I get you right, your original code was trying to do everything inside of the spacebar event? So that would mean in order for your code to even run, the spacebar would have to be pressed every single step. If you're trying to stop the animation in the space bar event and the space bar is not price, then the code for stopping the animation is never run. The animation end event is run every single step regardless of if you have any keys pressed.

Except for a few events like the step and draw events, all the other events are triggers. Triggers only happen when, well, triggered.
 

JackTurbo

Member
There is an animation end event for just this purpose.
Code:
If (sprite == desired sprite){
Image_index = image_number -1;
Image_speed = 0;
}
Edit* ignore capitalisation my phone keeps autocorrecting
 
S

Sam Atkins

Guest
Thanks Jack, yes that is what Bentley suggested and what ultimately worked. Theou you are driving more to my point though and that is; amongst Events and subevents, where to place things and why. So in response to your question.....yes initially I was trying to place the animation stop code in the subevent of the Spacebar keypress Event. Just seemed logical in my head as all of this is "happening related to the key press"....that seemed neat and tidy in my mental tree methodology. It seems GMS2 is a bit different so that's why I'm here picking your brains. My mental tree clearly needs re-arranging to fit GMS2's actualities.....lol. So at first I was putting the code in there, but it wasn't working at all either (not working on key press then not when not pressed....just looping non stop) perhaps for that to be the case I would have needed to select the key hold down event, and not just the press.....and also maybe had the right code to boot? lol. So back to your point:

"Except for a few events like the step and draw events, all the other events are triggers. Triggers only happen when, well, triggered."

Then why not put the trigger for the animation end as a subevent within the keypress event to trigger the animation end.....once? Why the need for a separate animation end event? My main goal here is to learn when to make things events or subevents. ;)

S.
 
Events are things that happen every step, IF TRIGGERED.

They are not a tree like structure.

Every step of the game, GMS triggers the appropriate events for all objects if they happened.

Putting code in the space bar pressed event means it only runs each step that the space bar is pressed.

An animation end event is triggered when a sprite that is animated reaches the last frame of its animation.

Which is totally independent of someone pressing the space bar.

I'm not sure that the term sub-event applies here, or even that GMS has sub events like you are describing.
 

JackTurbo

Member
I think you're getting mixed ideas about how the flow of the game goes.

Button pressed events only fire on the frame that the relevant button goes down. Animations by their very nature take multiple frames to complete. This then means those two pieces of logic cannot be coupled in the way you would like.

You can accomplish something similar by using state machines in your step event however.
 

Toque

Member
Thanks Jack, yes that is what Bentley suggested and what ultimately worked. Theou you are driving more to my point though and that is; amongst Events and subevents, where to place things and why. So in response to your question.....yes initially I was trying to place the animation stop code in the subevent of the Spacebar keypress Event. Just seemed logical in my head as all of this is "happening related to the key press"....that seemed neat and tidy in my mental tree methodology. It seems GMS2 is a bit different so that's why I'm here picking your brains. My mental tree clearly needs re-arranging to fit GMS2's actualities.....lol. So at first I was putting the code in there, but it wasn't working at all either (not working on key press then not when not pressed....just looping non stop) perhaps for that to be the case I would have needed to select the key hold down event, and not just the press.....and also maybe had the right code to boot? lol. So back to your point:

"Except for a few events like the step and draw events, all the other events are triggers. Triggers only happen when, well, triggered."

Then why not put the trigger for the animation end as a subevent within the keypress event to trigger the animation end.....once? Why the need for a separate animation end event? My main goal here is to learn when to make things events or subevents. ;)

S.

I struggle with this as my previous engine handled events differently. A tutorial on the topic would help new users.
 
S

Sam Atkins

Guest
"I'm not sure that the term sub-event applies here, or even that GMS has sub events like you are describing."

You are right, it probably isn't/doesn't. I'm just calling an "Event" what GMS2 calls an event to be placed in the Events window of an object, and a subevent whatever is entered beneath that in the next window that appears when you click on the event itself. You have to admit they seem "related" and therefore pertinent to each other. When you enter data into what I'm calling a subevent it (in my mind) should affect the "Event" itself and nothing else. That's why it seems weird to some of us (linear thinkers I guess) to add a whole new Event in the events list to affect something you entered as a subevent of something else when it seems it would be handled within that subevent area. It seems GMS2 however sees it as just another event affecting the overall "object" so I need to let go of the event-subevent mentality. My issue then is I get lost as to where then to put things.....does it belong as an independent event......or should it be a subevent (yes my lingo) of a pre existing one? I'm trying to create some modus operandi that helps me better guess/understand where these should go in the future.;)

"I think you're getting mixed ideas about how the flow of the game goes."

Most certainly!!:) I'm hoping to achieve more clarity. Like you mentioned though, perhaps GMS2 doesn't allow them to be coupled that way and I will just have to change my thinking. That's why I'm trying to achieve an understanding of what does and doesn't work that way....at this point it seems rather random.

"I struggle with this as my previous engine handled events differently. A tutorial on the topic would help new users."

See I'm not the only one! ;)

S.
 
Last edited by a moderator:
I would echo JackTurbo's comment on state machines. Using state machines, you can have a different sprite and animation for the start, middle and end of any time period you wanted in the instance and also have the ability to perform custom animations OUT of each of those animations if you want to get really deep (for instance, if your character jumps, you might want to have a separate firing animation when it's triggered during the jump animation...if you wanted to get *really* tricky, you could have a roll animation when you land and then have a DIFFERENT firing animation if the character fired during the landing end roll animation).

And yeah, events have been described pretty well by everyone before. The basis of any event is the room_speed, and GM will check each instance of each object every frame (which happens once every second / room_speed) for any events that might be triggered on that frame. The Step Event is triggered every frame, the Create Event is triggered on the frame that the instance is created, and Keyboard Events will trigger on the frame that a user presses the key, holds the key and releases the key. You'll learn which is which over time (pretty sure the manual will have some answers at least) if you don't know already. But understanding how events trigger and in which order is usually vital for specific code to work. I imagine there's a few tutorials if you search youtube for "game maker event system" or something along those lines. Maybe have a look through Shaun Spalding's or Heartbeasts early tutorials.

EDIT: I just read your above post. I think you're focusing WAY too hard on the 'separation' between events. There is none. If you set a variable in one event it's accessible in any other event in that instance (and if it's global, or you reference the specific instance you want the variable from, it can be accessed from any event in any instance.

GM is performing a trick when it breaks things down into the Step Event or the Create Event. They are not really separate at all, they are just convenient labels that have been put on things to make it a bit easier to understand the flow of the program. They are all basically functions and these functions (Events) are all called at specific times within the program. So, a pseudo code version of a single loop in GM would be:

Code:
if (create == false) {
  call_create_event();
  create = true;
}
if (key_press == true) {
  call_key_press_event();
  key_press = false;
  key_held = true;
}
if (key_held == true) {
  call_key_held_event();
}
if (key_release == true) {
  call_key_release_event();
  key_held = false;
  key_release = false;
}
call_begin_step_event();
call_step_event();
call_end_step_event();
That's not exactly what happens, but it might give you at least some form of a mental model to go on (and I hope it's accurate enough in spirit to be useful for that with my limited actual programming skills, hahaha). So Events are basically just little labels for things that could happen during the existence of your instance. They are not 'separate' from your instance and the code that you put in them isn't a 'sub-event'. That code is just what is called by your instance whenever that Event is triggered.

You might be getting confused about the fact that ORDER is important in your code, for instance: if you use "new_variable = 0" within the Alarm Event of your instance and you try to use "new_variable += 1" in the Step Event, you'll get an error, because you have to set a variable to a value BEFORE you try to do any maths to it and in this case, the Alarm Event will almost certainly 'fire' AFTER the Step Event has fired at least once. In other words the Alarm Event will only trigger after you set the Alarm and it has counted down, whereas the Step Event will trigger as soon as your instance is created, so the Step Event comes first in that example and you would fix it by setting "new_variable = 0" in an Event that is guaranteed to fire before your Step Event fires (usually it would be the Create Event).
 
Last edited:
S

Sam Atkins

Guest
Thanks RT. I need to re-read your response a few times, especially regarding State Machines, because I think I need to experiment with those. Also thanks for the tutorial directives....I've watched quite a few already and none really answered my questions. Your recommendations might fill in some details.;)

"But understanding how events trigger and in which order is usually vital for specific code to work."

This point seems to be at the heart of the issue as a neophyte with GMS2. Seems logical to me to stick a code that ends an animation in the same (forgive me-subevent) within the event that started it. Tag it on beneath it to say when you reach a certain frame-stop, instead of creating a whole new event to do it. That takes some re-mapping to get at. However, people saying "once you know more it will be easier" is like saying "well son once you know you'll know." That's where rules of thumb if you can find them often help folks to get from point A to point Z. I guess if GMS2 is so random as to not have some helpful guidelines, you just have to struggle till you discover all of the quirks and exceptions. Not incredibly efficient. But the quote above I think bears some vital info, in that maybe you decide where to place your code, (whether as an event or sub-event) is mostly dependant on the type of timing or triggering you are shooting for? Perhaps that's a start?

S.

Woops, you edited your post and I responded before I saw it......let me re-read and think a bit.;)
Thx!
 
Last edited by a moderator:
As you know, GameMaker is completely event driven, and that all actions happen as the result of certain events that are triggered in a specific order or by a specific occurrence within the game. There are a number of different events, each one with a specific task or timing and some of them are even split into separate "sub" events. Normally these events are run by GameMaker: Studio when it detects an in-game trigger, or every game tick (as is the case with the step and draw events), but you can also apply an event to an instance in the current room from within a piece of code.
- Generating Events (GM Manual)

Lel, apparently GM *does* have sub-events. But what they are referring to there are events like Begin Step and End Step and Begin Draw and End Draw...These can be considered 'sub' events of the Step and Draw Events, to give you more control over exactly when things happen (for instance, I like to use the Begin Step Event to register any player input, just to make absolutely sure that any variables set by input will have their values set before the Step Event is run).
 
S

Sam Atkins

Guest
Woooo, ok we are getting to good stuff here. Ok so I'm working on a mental "shape image" to assist with future design understandings in GMS2. My previous "tree" has been discarded and (at the moment) theoretically replaced by a sun type object with many rays extending from it. The center of the sun is your main "object" and each of the many rays represent various "events" that all tie back into central object and are each a part of its makeup. This seems to make more sense with what you were saying regarding the non linear nature of the events and their effects. It's more circular than top to bottom as a tree would be, and any number of variables/events potentially affect the center.

Alright.....an if then. Lol . If this is a decent representation......... then how does the timing you mentioned work with this example?;

"You might be getting confused about the fact that ORDER is important in your code, for instance: if you use "new_variable = 0" within the Alarm Event of your instance and you try to use "new_variable += 1" in the Step Event, you'll get an error, because you have to set a variable to a value BEFORE you try to do any maths to it and in this case, the Alarm Event will almost certainly 'fire' AFTER the Step Event has fired at least once. In other words the Alarm Event will only trigger after you set the Alarm and it has counted down, whereas the Step Event will trigger as soon as your instance is created, so the Step Event comes first in that example and you would fix it by setting "new_variable = 0" in an Event that is guaranteed to fire before your Step Event fires (usually it would be the Create Event)."

How do you order your events? Is it what happens top to bottom in the Events window? Or is this timing order all resident within one Event and its sub-steps -or sub events however you like to say it? So therefore are only ordered within a single event?

S.

ps.....this may seem a bit silly, but it would be great if it could be boiled down to some basic maxims like the following:

Animation End events require their own Event
All (or most) Animations are usually sub events to an Event command.
etc etc.
I know this isn't universally true.....but you get the idea. ;)
 
Last edited by a moderator:

TheouAegis

Member
All of those sub events or whatever are all within the same event. It's all in the step event. The order of logic is begin step, sub events, step event, animation end, outside room, outside View, end step, predraw, begin draw, draw, and draw, post draw, GUI stuff.

Gms2's event ordering makes quite a bit of sense. The same order logic is seen in many programs that were even written in other languages, even in assembly. If you want to keep things linear, then you need to include all of the code in one single event such as the step event, then you will code everything based off of status Flags similar to what Refresher went on about. I don't really think you need a maxim for this, though. Just read aloud what event you're putting things into. It's the space bar event, so obviously I would think it runs when the spacebar is pressed and only when the spacebar is pressed. The animation an event runs when the animation ends and only when the animation ends, that is, when it hits the last frame of the animation and rolls over into the first frame. User events only run when they are called explicitly.
 
S

Sam Atkins

Guest
Interesting......so the "sun with rays" metaphor is actually a decent visual image for the overall object construct. The way it ended up working with my actual animation solution with all the different codes/combinations I tried was more like that (object = sun) with (rays = Events) concept, and not linear. Like I said, if it was what I call linear I would've been able to put the code for animation end under the key pressed once (not held) command along with the animation itself and the sound I have playing with it. It would've travelled down the event sublist, playing the animation, and the sound then triggering the animation stop via the code attached to the very bottom. This however wouldn't work......so I had to use another "ray of the sun" to create the Animation end Event. This (to me) fits more the sun with rays image than a linear----(actions located together in a line) paradigm. Now perhaps with Steps as you mentioned you can make it more linear as you said? I need to look at Step possibilities.;)

S.
 
D

Delirious

Guest
GMS2 is anything but random, you just need to change your way of thinking about it. I feel as though your idea of what GMS2 should do, is getting in the way of you learning what it does do.

As for "helpful guidelines", since you seem to enjoy understanding by analogy, it is helpful to think of code execution as being similar to reading a book. If all of the code in your game (the code of every event, of every instance, of every object, etc., all of it) were one (bold to emphasize it is only one) big book, then GMS2 reads it how you would: line by line, from front to back. Except GMS2 reads this book front to back once every (as someone above said) second/game_speed (generally every 1/30th or 1/60th of a second). However, GMS2 will only read the paragraphs that you tell it to read. You can think of paragraphs as a single block of code for this analogy. And you tell GMS2 to read certain paragraphs using triggers or events. So for your example, GMS2 read the paragraph that said "stop animating the current sprite of this object!", but only once the animation was ended; the animation ending being the trigger. GMS2 then continues to read the rest of the book, and reads it again, and again, every 1/60th of a second, reading only the paragraphs that you told it to read using triggers and events.

To further illustrate this point, the reason you can't control animations in the button pressed event, is because GMS2 reads that paragraph ONLY WHEN the button is pressed (so it reads that paragraph once, and only once, and only on the step that the button was pressed). And it will not run any of the code inside that event again, at least not until the button is pressed again. Since animations happen over time, they won't animate in an event that is triggered, and then stopped after only 1/60th of a second. For this, you would need to introduce some trigger that turns on/off over time as well.

Same as with a book (might not apply to non-fiction, but lets not muddy the already-muddy analogy), the order in which you read the book is essential to understanding it. When reading a crime novel, you won't understand "...and it was Bob who was the murderer the whole time!" if you don't know who Bob is. GMS2 reads code in very much the same way. That is why others have said that it is important to understand the order of events. This is because you need to know in what order the compiler is reading your code. The order in which it reads your code may not seem important now, but it is essential if you want to be a proficient coder.

Objects, events, instances, etc. are all just ways of organizing the code so it is understandable and intuitive to you. GMS2's compiler will still go through all of it, one line at a time, and will only read the lines you tell it to. So in this sense, it is actually very, very, linear.

Hopefully this helped a bit.
 
Last edited by a moderator:
S

Sam Atkins

Guest
Well said;) And yes I am working on adjusting my thinking, and not trying to cram GMS2 into it.

To further illustrate this point, the reason you can't control animations in the button pressed event, is because GMS2 reads that paragraph ONLY WHEN the button is pressed (so it reads that paragraph once, and only once, that step). And it will not run any of the code inside that event again, at least until the button is pressed again. Since animations happen over time, they won't animate in an event that is triggered, and then stopped after only 1/60th of a second. For this, you would need to introduce some trigger that turns on/off over time as well.

I'm trying to "get this" because GMs2 did control my animation (starting it and in fact looping it forever) in the key press event I created. Therefore I assumed it would play through the sequence of sub-events only once and therefore end the animation with the code I tagged onto the end of the sub-events attached to that keystroke event....but it didn't. Are you saying since the keystroke is over (passed) it won't play the last bit of code I attached? Then why did it play the animation and the sound sequence I cobbled together which all played out well after that split second event was triggered, and not the end animation code as well?

S.

ps.....or are you saying the key press step timing is too short to get through it all and by the time the animation is done it's too late and not engaging that last bit of code?
 
Last edited by a moderator:
D

Delirious

Guest
The animation kept playing because I'm guessing you just put

Code:
sprite_index = spr_animation;
so the button pressed event only changed the sprite. Once the sprite has been changed, GMS2 will automatically animate the sprite based on its image_speed (which I'm guessing was set to something != 0) which happens independently of the button pressed event. This made it seem like the button pressed event was actively causing this animation to happen, when in reality it acted only as the initial catalyst once it changed the sprite. After that, GMS's internal sprite animation took over (which I must admit, I'm not 100% sure how it works, so I usually just handle it manually when possible).

As for the sound, I'm certain it worked similar to the above, although obviously not in the exact same way.

EDIT: To be clear, the above code is the GML equivalent to setting the sprite in DnD.
 
Last edited by a moderator:
S

Sam Atkins

Guest
Hmmmm, I will look at this and think a bit. Off the cuff from what I recall I used DnD and I believe it was inside "Spacebar press Event"; Set Sprite to, (and selected the animation Sprite), and then Dnd'd the Sound under that, and then tried the Dnd-Execute code box beneath that with the appropriate "animation end code" inside it. Which did nothing. lol. But let me double check.;)

......the sun analogy is still holding it's own.
 
Last edited by a moderator:

Toque

Member
Hmmmm, I will look at this and think a bit. Off the cuff from what I recall I used DnD and I believe it was Set Sprite to, (and selected the animation Sprite), and then Dnd'd the Sound under that, and then tried the Execute code box beneath that with the appropriate "animation end code" inside it. Which did nothing. lol. But let me double check.;)

......the sun analogy is still holding it's own.
Im sure it all makes sense. Just a matter of getting used to it. But your not crazy it takes a bit to get your head around some of it.
 

TheouAegis

Member
DnD set sprite action is just
Code:
sprite_index = SPRITE;
image_speed = 1;
Not sure if GMS2's resets image_index as well... But anyway, as was said, all you are doing is just setting some variables which GM will read whenever its animation code gets run (after Step Event). You yourself don't animate anything. You could see that for yourself if you put a manual animation code inside the spacebar event:

Code:
if image_index< image_number
    image_index += 1/8;
Your sprite would never animate because you took the control away from GM and threw the code in the wrong event.
 
S

Sam Atkins

Guest
Not sure I follow you Theou, the sprite did animate.....it just wouldn't stop.
 

kupo15

Member
it probably didn't stop because once it was greater than the image number (which you expected it to stop) the image_index automatically loops back down to 0, thus its less than image_number again.
 
S

Sam Atkins

Guest
That sounds likely Kupo, and this timing is likely why it is necessary to put the "animation end " event not within the keystroke event, but in another "ray of the sun" as a new "event" if you will to simply end the animation without that directive coming from within the keystroke series of subevents, which clearly wasn't getting the message.....probably due to some timing stuff as we mentioned. Again maybe step events could be useful in this regard. I need to read more.:)
 

Toque

Member
I had a similar problem last week. Animation stop worked okay. Then I wanted to speed up the animation. Changing the sprite FPS animation speed over 12 the animation would loop and never stop. FPS less than 12 it would run once and stop.

It’s a little complicated.
 
S

Sam Atkins

Guest
Interesting.......I assume your "animation end" was a unique event? Or was it imbedded in another pre-existing event?
 

Toque

Member
It’s all in one step event. I’m not sure what a “unique event” event is.

I’m the last person you should take advice from. Sorry not trying to lead you in a different direction.

But if I started with 15 FPS and could not get the animation to stop I would be lost.

The code is the same as the examples.

My point really is it’s a bit confusing sometimes.
 
S

Sam Atkins

Guest
Lol....yeah pat of my problem is I create my own lingo.

I’m not sure what a “unique event” event is.

I just meant (by unique event) that it is an event in the Event's Window....and not what I call a sub-event that is a smaller part of a pre-existing event, like say a "Set Sprite" dnd box command embedded within a Keystroke or some other larger Event. I still suck at this too so asking me to explain myself is problematic at best!:)
 
Last edited by a moderator:
D

Delirious

Guest
Okay, since I feel partially responsible for you learning GameMaker now, I'm going to try to clarify a few things.

The reason why these first few suggestions didn't work for you

if image_index >= image_number - 1 { image_speed = 0; }
if image_index + image_speed >= image_number
image_speed = 0;
is because you were putting them into the keyboard_check_pressed (or what ever the DnD equivalent is). That is it. That is the reason. I will explain in a bit why it did not work. First, I just want to say that the reason it did not work has NOTHING to do with any sort of tricky timing, the actual reason is actually quite straight forward and simple.

It did not work because, as was previously mentioned, the keyboard pressed events only run ON THE FRAME THE KEY WAS PRESSED DOWN. Sorry for the bold all-caps, but I cannot stress this enough. So ALL of the code you put into the keyboard pressed event will only be read through ONE time and ONE time only per key press. This is important because the above solutions you were provided were never run because their conditions were never satisfied. For example:

This
if image_index >= image_number - 1 { image_speed = 0; }
will not work in the keyboard pressed event because "image_index >= image_number - 1" will NEVER be true, so the code inside the " { } " will NEVER run i.e. "image_speed = 0;" will never run.

This is because once the key is pressed, GMS will read through your code within the keyboard pressed event. The first thing it does is sets the sprite, and the image speed to 1. When it sets the sprite, it will also get the image_index (the individual frames within a sprite) from your object's previous sprite, which is most likely 0. Immediately after setting the sprite and image speed (because remember, GMS reads your code like a book), GMS will read
if image_index >= image_number - 1 { image_speed = 0; }
however, image_index is 0 and 0 is not greater than, or equal to (image_number - 1) so long as your sprite has at least 2 images. Since 0 (image_index) is NOT greater than, or equal to a number greater than 0 (image_number - 1) the code { image_speed = 0;} will not run, and {image_speed = 0;} is the code that would stop your animation. And as you remember, keyboard pressed events only run once, and only on the frame they are pressed down, so THE VERY NEXT FRAME GMS will not run any of the code in your keyboard pressed event, unless the key is pressed down the very next frame, which would require the player to press the key at a rate of 60 times per second.

GMS will read through your code in the same way you just read through the above paragraph, and it is impossible to read the above paragraph as image_index being anything other than 0. So the animation will never be stopped, ONLY started in the keyboard pressed event.

EDIT: For completeness and clarity, I will say that
if image_index >= image_number - 1 { image_speed = 0; }
can be true in the keyboard pressed event, but only if your player is mashing the keyboard key, and image_index happens to be >= (image_number - 1) ON THE FRAME that they pressed down on the key. This is highly unlikely to occur, and a strange feature to include in a game.
 
Last edited by a moderator:
S

Sam Atkins

Guest
Thanks Delirious! Sorry to make you explain things in such painful detail, but that does make sense. Due to it's location (where I originally put it in the keypress event) it would have never rolled through the numbers of images to trigger it. As an "Event of its own" (Animation End Event) however, it will always trigger whenever the criteria are met no matter what.

This still makes me feel some helpful pointers to noobs would be.....well.......helpful. My 1st in the list so far is

1-Stop your object's animations with Animation End Events that are standalone events. Don't ask why...just do it. lol.:)
 

TheouAegis

Member
You don't need to use the animation and event to stop an animation, you just need to make sure the proper conditions are met in order to stop your animation. Letting the animation run its full cycle meets the proper condition for the animation end event to trigger at which point you can then use the animation end event to stop the animation. However, the animation and event will only run when the animation has reached the very last frame of your Sprite and rolled over back to the first frame. As such it will not allow you to stop a Sprite mid animation.

If you wanted the Sprite to stop as soon as it rolled over to frame 4, the animation and event would not help you at all if your Sprite has more than five frames. In order to do that, you would need to do your code in the step event or the end step event, and personally I prefer the step event for these things. Checking what image you are on and then checking what image you will be on once the image speed has been added will allow you to stop it at any point. Although, to be fair, this may not work in studio2 since I guess image_speed is now just a modifier for sprite speed or something (i i haven't dicked around with it much).

And as was kind of pointed out, checking what frame the image will be is typically better than checking what frame the image is already on. If the animation speed is too high for some reason, then you may never actually be on the Target frame of the Sprite.
 

Toque

Member
And as was kind of pointed out, checking what frame the image will be is typically better than checking what frame the image is already on. If the animation speed is too high for some reason, then you may never actually be on the Target frame of the Sprite.
Thanks for clarifying that. I suspected that something like that was going on.
 
S

Sam Atkins

Guest
Yes, there do seem to be some significant differences between GMS2 and previous versions. As you recommend Theou, I am delving into the Step Events more to try and clarify what actions to use where. For instance when to use or create what I call a new or Independent event- when to use a Step Event - and when can you simply add elements to a pre existing event as what I call a (sub event). Some general guidelines for these alone would likely help neophytes considerably. I will continue to try and formulate these as I learn. They don't even have to be "universally true".......just more often than not.;)
 
D

Delirious

Guest
There can not really be "general guidelines" on what events to use and when. It is more of an organizational thing, as some people may prefer to have their code broken up akin to organizing files in a file-folder.

The only general guideline I'd give is to know under what conditions an event will run. Because, as was mentioned before, events are triggered based off whether some condition in your game is satisfied e.g. if the animation is ended, run animation end event. And knowing when it will/will not run can prevent you from being confused as to why your code isn't working as expected.

However, the reason there can be no rule of thumb or "maxim" is because as I said, it is more of a matter of preference rather than functionality (except I'd argue some events are less functional than what you could otherwise do in the step event, as Theou pointed out). It is (most often) possible to do all the same things events do, but in the step event, by setting up the appropriate triggers using "if" statements for example. Because of this, it is hard to tell someone to do it a certain way, since the same result can be gotten in various, equally viable ways.

For example, I only use the create event (to initialize variables), the step event (to do pretty much everything), and the draw events (to draw, since step event can't handle this). And I keep myself organized by putting all of my code into scripts, which works well for me.
 
Last edited by a moderator:
S

Sam Atkins

Guest
Yeah that's what I was afraid of......GMS2 tends to be so complex rules of thumb don't really help much as they depend on too many potential variables, dependent as well on what you are trying to accomplish. I want to mess with Step Events more as I think as you mentioned Delirious they can be quite useful and do seem to be more "linearly organized" as well. I feel like at this point my biggest obstacle is knowing what is the best way to try to do a particular thing, so therefore you don't waste a lot of time trying it in a way that was doomed from the start. But it is what it is I guess.

Just so you know I'm not a complete un-creative boob just because I'm fighting the learning curve of GMS2 (I never had this much issue with the earlier versions...lol) here is a cigar box guitar I just finished building. Hopefully one day I will be as good with game design.;)


 
Last edited by a moderator:
S

Sam Atkins

Guest
So......all guitars aside....lol. Can I accomplish the following with Steps or Alarms? In other words, have the keystroke event initiate the animation sequence which then stops on the last frame (thanks to the separate end animation event), then switches that Sprite back to the original object again? And if so, would I place these Steps and or Alarms under/within the Keystroke event, or make them again what I call "unique" events on their own?

ps.....I already have the first part created of course that takes the sequence to the point of the animation ending on the last frame.
That being said I really miss the old "Pause" element that used to exist in older versions of Gamemaker. If I was doing this in the old version I could have strung most of this together under the key-press-initiated the animation....paused it on the last frame and then initiated the change back to the original object. At least that's how simple I remember it being....it's been a while though. o_O
 
Last edited by a moderator:
D

Delirious

Guest
You can do pretty much anything in the step event.
Instead of having a "keyboard button pressed event" and putting code in that, you can put the code
Code:
if keyboard_check_pressed(vk_key) {
    //your code here
}
directly into the step event and it will do the exact same thing, except the step event is called earlier within a given step than the key board events. (Again, highly recommend reading this)

The same goes for pretty much all of the events: the conditions under which an event will run can be replicated within the step event.
Code:
/* pseudo code to generalize the above keyboard_check_pressed example */

If *condition that triggers event* {
    //your code here
}
Edit: of course there are exceptions to this. For example, the step event cannot handle drawing things, so for that you would have to use the draw event. But the above applies to most events.
 
Last edited by a moderator:
Sam, just so you know, 99% of all my code sits in either the Create Event, the Step Event or the Draw Event. I rarely ever use any other basic events (such as keyboard press or mouse check or animation end, etc) unless I'm specifically being lazy. There are people that have created entire games, with menus and options and etc, within a single script that is called in the step event of a single object (so the only code in the entire project sits in a single script that is called repeatedly each step).

You can think of basically any event as already existing within the Step Event (the only real exceptions are asynchronous events, which are kind of their own little thing). So using Mouse Left Button Event is entirely analogous to using the following code in the Step Event:
Code:
if (mouse_check_button(mb_left)) {
  //Run mouse code
}
The two function identically. The Mouse Left Button Event is simply an *easier* way of understanding how to make things happen when you left click. So a beginner can look at it and go "Ok, that event is called Left Button, that's how I make things happen when I click" but an experienced user can more finely tune how they want their left click to function by using the Step Event to accomplish the same thing but with more control over when and where the code is being applied.
 
Top