Rick Posted June 4, 2010 Share Posted June 4, 2010 I like using the fmodf like the documentation does for animations. It's simple. My question would be is there a way to tell if the animation has played once using the fmodf way though? Seems like it wraps around, which means simply checking if the frame is >= end doesn't work. I can't really think of a way to handle this using the fmodf way. _frame = AppTime() / 30.0; _frame = fmodf(_frame, end - start) + start; Animate(_entity, _frame); // doesn't work because _frame ends up wrapping and never seems to actually go past the end frame if(_frame >= end) _playerState = PlayerState::Idle; Quote Link to comment Share on other sites More sharing options...
ZioRed Posted June 4, 2010 Share Posted June 4, 2010 You can use a variable to hold the last frame and check it against the current one: TMesh _entity = LoadMesh("abstract::crawler.gmf"); float start = 131, end = 171; float startIdle = 0, endIdle = 69; float _frame = 0, _lastFrame = 0; int _playerState = 0; // Game loop while( !KeyHit() && !AppTerminate() ) { if (KeyHit(KEY_W)) { _playerState = 1; } if (_playerState) { _frame = AppTime() / 30.0; _frame = fmodf(_frame, end - start) + start; Animate(_entity, _frame); if (_lastFrame > _frame) { _playerState = 0; _lastFrame = 0; } else _lastFrame = _frame; } else { _frame = AppTime() / 30.0; _frame = fmodf(_frame, endIdle - startIdle) + startIdle; Animate(_entity, _frame); } UpdateAppTime(); UpdateWorld(); SetBuffer(buffer); RenderWorld(); SetBuffer(BackBuffer()); RenderLights(buffer); DrawText(0, 20, "Frame: %f", _frame); DrawText(0, 40, "Last: %f", _lastFrame); // Send to screen Flip(); } Quote ?? FRANCESCO CROCETTI ?? http://skaredcreations.com Link to comment Share on other sites More sharing options...
Rick Posted June 4, 2010 Author Share Posted June 4, 2010 So that works, but I'm trying to figure out why sometimes when I hit a button (like R for reload state) it doesn't play the animation either at all or not all the way through, but sometimes it does. Here is the code that handles the states. If I hit R it should set _lastFrame to 0.0 which should make the animation play all the way, but it doesn't all the time. if(KeyHit(KEY_R)) { // can't move to reload _move = 0.0; _lastFrame = 0.0; _playerState = PlayerState::Reload; } // handle animations based on state float start, end; switch(_playerState) { case PlayerState::Idle: start = 0.0; end = 200.0; break; case PlayerState::Walk: start = 201.0; end = 321.0; break; case PlayerState::Run: start = 322.0; end = 341.0; break; case PlayerState::RunShoot: start = 411.0; end = 430.0; break; case PlayerState::StandShoot: start = 431; end = 446; break; case PlayerState::Reload: start = 447; end = 489; // reloading is just a one shot, so change the state back to idle once we are finished if(_lastFrame > _frame) { _lastFrame = 0.0; _playerState = PlayerState::Idle; } else _lastFrame = _frame; break; } _frame = AppTime() / 30.0; _frame = fmodf(_frame, end - start) + start; Animate(_entity, _frame); Quote Link to comment Share on other sites More sharing options...
ZioRed Posted June 4, 2010 Share Posted June 4, 2010 The _lastFrame set inside the Reload case switch is not setting the real LAST frame since _frame is changing after few lines. I think you should move the _lastFrame check after the Animate call (however it will affect the next cycle and not the current one). Quote ?? FRANCESCO CROCETTI ?? http://skaredcreations.com Link to comment Share on other sites More sharing options...
Rick Posted June 4, 2010 Author Share Posted June 4, 2010 Oh yeah I see what you mean now. I'm just trying to avoid having multiple frame calcs and Animate() methods called. I'll see what I can do. Thanks! Quote Link to comment Share on other sites More sharing options...
ZioRed Posted June 4, 2010 Share Posted June 4, 2010 May be you can check the lastFrame just before Animate call: _frame = AppTime() / 30.0; _frame = fmodf(_frame, end - start) + start; if(_lastFrame > _frame) { _lastFrame = 0.0; _playerState = PlayerState::Idle; _frame = 0; } else _lastFrame = _frame; Animate(_entity, _frame); Quote ?? FRANCESCO CROCETTI ?? http://skaredcreations.com Link to comment Share on other sites More sharing options...
Rick Posted June 4, 2010 Author Share Posted June 4, 2010 I'm not at home so I can't test, but I was thinking about doing it after Animate(), and just let every animation run the code. If it's a looping animation it should be fine because for stuff like moving I use KeyDown(). So if it hits the last frame of the run animation, it'll set the state back to Idle, but at the top of the next cycle, it'll see that the move key is still down and change the state back to walk. But for things like reload I use KeyHit(). So having the code after the Animate() should only affect the one time animations and not the looping animations. I'll see if that's actually the case when i get home I guess Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.