Get an action to wait

I am putting together my character animation controls and I'm having the hardest time defining a waiting time that would stop fight actions from overriding each other, this is a test of the fight part of my input thus far, (with help from the forum search),with the timing code the animation never gets called, if I leave it out the (bolded part) the actions work, but only if u dont click very fast ,



both actions finish cycle in under two seconds



I need to have each fight move finish with a slight pause regardless of the the click rate, but cant figure out what I'm missing, any help would be appreciated

TIA



private int fightmove;
 // time of last update
private float lastUpdate = 0;
private float kicktime;
private float punchtime;


 if( mouseBinding.isValidCommand("fight", false))
{
         
       
            // determines whether model punches or kicks: 1 = punch, 2 = kick
            fightmove = fightmove+1;
           
         
            //animation cycle times
            kicktime = player.getKickAnimator().getMax()+1;
            punchtime = player.getPunchAnimator().getMax()+1;
                      
            if(fightmove == 1 )
            { 
               
                [b]if(lastUpdate + punchtime <= Timer.getTimer().getTimeInSeconds())[/b]{   
                    player.setPunchAnimator();
                   
                }
               
               
            }
          
            if(fightmove == 2  )
            {             
                [b]if(lastUpdate + kicktime <= Timer.getTimer().getTimeInSeconds())[/b]{
                    player.setKickAnimator();
                }
               
                fightmove = 0;
            }
            lastUpdate= Timer.getTimer().getTimeInSeconds();
}

anybody this is really driving me nuts, its seemingly simple, because I've already worked out a decent weapons fire delay that works well and with reload time too, but cant seem to apply the same principles to this situation some how any advice on what I could be missing would be appreciated

hmm…



well, I dont know if this will help you, but I had sort of a similar situation.



I had a character who could jump (with spacebar) and each time it would add like 3 y vector physics force.



But, I could hit the spacebar as much as i wanted and i would fly away! lol



so how I solved this problem.



As an example (these arent the numbers I used, also this is psuedo code)



I made a float at, say = 100. Then I had an if statement in the update which said if float is < 100, add .25 to it. so, until this float was acted upon, it didnt really clog up the update.



so, when the character hit spacebar, an if statement was run to see if the float = 100, if it wasnt, nothing happened. if it was = 100, then it set the float = 0, and performed the action.



At least, that is the way I solved my problem, however, I dont know if it is the most efficient way, or if that is even the same sort of problem you are having.

I'll try it but I think it will lead  similar issues I have now, in fact I already do something like this for my jump action and it works well  8):

//jumping action
        if ((KeyBindingManager.getKeyBindingManager().isValidCommand("jump",false) || mouseBinding.isValidCommand("jump", false)) && lastCollided != null){
            
             Vector3f jforce = new Vector3f(force.x = forceFactor*35f,0,0);
            playerCollider.getPhysicState().addForce(jforce);
            
            lastCollided = null;
            player.setJumpingAnimator();
            
            if(lastCollided == null && player.getJumpingAnimator().getTime() > player.getJumpingAnimator().getAnimation().time(18))
            {
                player.setStandingAnimator();
            }
            
            
            
          
        }





I dont want to "kill" the action trigger that will make  fight controls feel non-responsive.... no :?, I want to queue each call to kick or punch so that if I click the mouse 3 times no matter how fast, I should get "punch......kick.....punch" played sequentially  in there entirety and not the "animation blended confusion" I get now,  hope I'm clearer

this is how I set it up now but still no go :? :? :( it still only work when I control how fast I click

if( mouseBinding.isValidCommand("firebullet", false))
        {
          
          
            // determine whether model punches "1" or kicks "2"
            fightmove = fightmove+1;
            System.out.println(fightmove);
          
            
            
                      
            if(fightmove == 1 && kicktime <=0)
            {  
                //player.isKicking = false;
                if(!player.isKicking){
                    punchtime = player.getPunchAnimator().getMax()*1.5f;
                    System.out.println(punchtime);
                    player.setPunchAnimator();
                    while(punchtime>0){
                        punchtime -= tpf;
                        player.isKicking = false;
                        fightmove=1;
                      
                    }
                      
                  
                    if (punchtime <= 0) {
                       player.isKicking = true;
                       player.isPunching = false;
                      
                    }
                }
                    
            }
            
            if(fightmove == 2 && punchtime <= 0 )
            {  
                //player.isPunching = false;
                if(!player.isPunching){
                    kicktime = player.getKickAnimator().getMax()*1.5f;
                    System.out.println(kicktime);
                    player.setKickAnimator();
                    while(kicktime>0){
                        kicktime -= tpf;
                        player.isPunching = false;
                        fightmove=2;
                      
                    }
                      
                  
                    if (kicktime <= 0) {
                       player.isKicking = false;
                       player.isPunching = true;
                      
                    }
                }
               fightmove =0;    
            }
            

I also have an isStanding boolean that I have not used yet, I can listen for that as my end state variable, but the timing code may still be an issue, will test it, still though, ideas would be cool thanks

How about implementing a class, that stores all the action information

and then implement a queue (or just use a LinkedList)



if "kick" or "punch" is pressed simple

linkedList.add(new Action("kick"));



and then later in the update check:

if(!linkedList.isEmpty() ) {

    linkedList.pop().performAction();

}



or something similiar…



you could also use an integer keeping track of how many "fight"-actions should be performed,

(it won't be very extendible, but a bunch faster…)

so your code would be:


private int fightmove;
 // times to fight
private int fightsLeft;


 if( mouseBinding.isValidCommand("fight", false))
{
    fightsLeft++;
}
if( fightsLeft > 0)
{
       
            // determines whether model punches or kicks: 1 = punch, 2 = kick
            fightmove = fightmove+1;
           
         
            //animation cycle times
            kicktime = player.getKickAnimator().getMax()+1;
            punchtime = player.getPunchAnimator().getMax()+1;
                      
            if(fightmove == 1 )
            { 
               
                [b]if(lastUpdate + punchtime <= Timer.getTimer().getTimeInSeconds())[/b]{   
                    player.setPunchAnimator();
                   
                }
               
               
            }
          
            if(fightmove == 2  )
            {             
                [b]if(lastUpdate + kicktime <= Timer.getTimer().getTimeInSeconds())[/b]{
                    player.setKickAnimator();
                }
               
                fightmove = 0;
            }
            fightsLeft--;
}


@tim8dev



just got back to this your linkedList idea worked a bit after I reorganized my code some



the animations dont get smushed together anymore :smiley: but click speed causes fightmoves to get missed some how, especially if more than 2 clicks are queued, see attached text file for console output, can u notice anything I might be doing wrong.



TIA



the move identifier



private LinkedList<Integer> fightQ = new LinkedList<Integer>();
private String moveName;
private int fightmove;

 public void update(float tpf) {
        super.update(tpf);
        pHandler.useCursor("default");
        input.update(tpf);
  
      if( mouseBinding.isValidCommand("firebullet", false))
      {
          
            // determine whether model punches or kicks
            fightmove++;
              
          
            if(fightmove == 1)
            { 
                moveName = "punch";
                fightQ.addLast(fightmove);
                System.out.println("move fired: " + moveName);
            }
           
            if(fightmove == 2)
            { 
                moveName = "kick";
                fightQ.addLast(fightmove);
                System.out.println("move fired: " + moveName);
                fightmove =0;    
               
            }
     }
}



The actually animation triggering via the listeners in md5Reader


public void notify(Animator animator, int type, Object userObject)
    {
        if (type==IAnimationListener.ANIMATION_CYCLE_ENDED && (animator == player.getPunchAnimator() || animator == player.getKickAnimator()))
        {
            player.isPunching = false;          
            player.isKicking = false;    
            animator.fadeOut(0.1f, false);
           
            if(fightQ.size()>0)
            {
                System.out.println("No. of moves queued: "+ fightQ.size());
               
                if(!fightQ.isEmpty() && fightQ.getFirst()==1){
                    player.setPunchAnimator();
                   if(!fightQ.isEmpty()&& player.isPunching){
                        fightQ.removeFirst();
                    }
                  
                }
                if(!fightQ.isEmpty() && fightQ.getFirst()==2){
                    player.setKickAnimator();
                    if(!fightQ.isEmpty()&& player.isKicking){
                        fightQ.removeFirst();
                    }
                  
                }
                System.out.println("No. of moves Left: "+ fightQ.size());
                System.out.println("______________________________________________");
            }
            else{
               
                player.getCurrentAnimator();
                animator=null;
            }
           
           
        }
           
       
                                   
    }

 

What frame rate are you getting during your animations? Sometimes inputs can get ignored if the entire click happens between updates.

Well, I don't get your problem… At least not out of your code and ouput ("data.txt").



Just some additional advice,

consider using enums instead of ints and/or Strings.



So you could extend it better.

some moves fired dont get animated, but as despotes suggests it might be getting ignored by the updates, sounds plausible but is there a way to get arround this, and my framerate is controlled, I set the max at 85 but the fps count stays arround 57fps with this enabled



@tim8dev enums huh…more reading to do then, but what can be done …if anything to reduce commands getting lost :?  despite what the console spits out every first fight animation (punch) gets ignored i.e if I press six times quickly I only get the kicks and a punch at the end it its last in the queue.

You'll definitely want to go with a queuing system, as was suggested.  I have used this sort of thing to queue up special effects and Fire them off in succession or to test if any effects are still active before moving onto the next thing.  For the "actions getting skipped" issue, have you confirmed this by message/log output or are you just not seeing them?  If they are truly being skipped then obviously you will have to hunt down the bug or condition that causes it to not be fully processed.

ashtonv said:

You'll definitely want to go with a queuing system, as was suggested.  I have used this sort of thing to queue up special effects and Fire them off in succession or to test if any effects are still active before moving onto the next thing.  For the "actions getting skipped" issue, have you confirmed this by message/log output or are you just not seeing them?  If they are truly being skipped then obviously you will have to hunt down the bug or condition that causes it to not be fully processed.


I dont suppose u have an example laying around you are willing to share, I am queuing the extremely simple trigger(see above) I know....I know.... not extensible but.................

Well… I could dig something up, but I'm not sure how useful it would be… seeing as my system was not real-time but turn-based and so I didn't have to contend with a user who might click/punch, click/kick, click/punch, click/kick, etc., all day long.  However, my second thought about this, now that I've read into the code a bit more, is that the problem might be that there's  a problem with removing the moves from the LinkedList while new moves are being added.  Have you considered using a simple ArrayList and just using add(move) and remove(0) to handle the queue? 



Btw, I wasn't able to make much sense of the log that you posted.  Maybe a script telling what you did to view along with the log would be helpful and where the problem occured.

ashtonv said:

Well... I could dig something up, but I'm not sure how useful it would be... seeing as my system was not real-time but turn-based and so I didn't have to contend with a user who might click/punch, click/kick, click/punch, click/kick, etc., all day long.  However, my second thought about this, now that I've read into the code a bit more, is that the problem might be that there's  a problem with removing the moves from the LinkedList while new moves are being added.  Have you considered using a simple ArrayList and just using add(move) and remove(0) to handle the queue?  

Btw, I wasn't able to make much sense of the log that you posted.  Maybe a script telling what you did to view along with the log would be helpful and where the problem occured.


thank for the idea will give that a run, as for the log sorry for the vagueness but the basic idea is, depending on the "timing" some animations don't happen, mostly the punches

clicking just fast enough for 1 to be queued and removed
move fired: punch
No. of moves queued: 1
punching <- animates
No. of moves Left: 0


more than one queued
move fired: punch
move fired: kick
move fired: punch
No. of moves queued: 3
punching <-never animates
kicking
No. of moves Left: 1

o.k finally got it working, apparently I needed to add a couple more conditions…in case u are wondering the goal of all this was to have animation not to errr shallow each other when those damned button smashers :smiley: get going, there will be max queue size thank for the help guy, bits and pieces of your advice got me there. :wink:



the Listener code now…doubt my shit code will be use to anybody, but ya nevva know :smiley:

 public void notify(Animator animator, int type, Object userObject)
    {
        if (type==IAnimationListener.ANIMATION_CYCLE_ENDED && (animator == player.getPunchAnimator() || animator == player.getKickAnimator()))
        {
            player.isPunching = false;          
            player.isKicking = false;    
            animator.fadeOut(0.1f, false);
           
            if(fightQ.size()>0)
            {
                System.out.println("No. of moves queued: "+ fightQ.size());
               
                if((!fightQ.isEmpty() &&  fightQ.getFirst()==1) && (animator == player.getKickAnimator() && type==IAnimationListener.ANIMATION_CYCLE_ENDED)){
                    player.setPunchAnimator();
                   if(!fightQ.isEmpty()&& player.isPunching){
                        fightQ.removeFirst();
                    }
                  
                }
                if((!fightQ.isEmpty() && fightQ.getFirst()==2)&& (animator == player.getPunchAnimator() && type==IAnimationListener.ANIMATION_CYCLE_ENDED)){
                    player.setKickAnimator();
                    if(!fightQ.isEmpty()&& player.isKicking){
                        fightQ.removeFirst();
                    }
                  
                }
                System.out.println("No. of moves Left: "+ fightQ.size());
                System.out.println("______________________________________________");
            }
            else{
               
                player.getCurrentAnimator();
                animator=null;
            }
           
           
        }
           
       
                                   
    }