Search code examples
javaandroidanimationgesturedetectoronfling

onFling() 2D Animation Issue


I'm trying to run a very simple 2D animation when I fling an image view. I have 2 activities involved in this.

The GameCanvas

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY)
    {           
        if(GameWindow.getContext() == null)
            return false;

        if((e1.getY() >= GameWindow.getHeight()) && (e1.getY() <= GameWindow.getBottom()))
        {               
            try
            {                
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
                    return false;               
                // right to left slap               
                if((e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE) && (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY))
                {                                   
                    slappingLeft = true;

                    //Animate Slap                  
                    GameWindow.update();                

                    if(!running)
                        running = true;


                }  
                else if ((e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE) && (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY))              
                {       
                    slappingRight = true;

                    //Animate Slap
                    GameWindow.update();

                    if(!running )
                        running = true;
                }
            }                
            catch (Exception e)                 
            {                                   
                //nothing                                   
            }               
        }

        slappingLeft = slappingRight = running = false;
        return true;            
    }       

And the GameWindow

private RefreshHandler mRedrawHandler = new RefreshHandler();

class RefreshHandler extends Handler
{
    @Override
    public void handleMessage(Message msg) {
        GameWindow.this.update(); 
        GameWindow.this.invalidate();
    }

    public void sleep(long delayMillis) {
        this.removeMessages(0);
        sendMessageDelayed(obtainMessage(0), delayMillis);
    }
};

public void update() 
{
    //animate slap                  
    if(GameCanvas.slappingLeft)
    {           
        for(int i = 0; i < 500; i+=100)
        {
            GameCanvas.SlapLeft();              
            mRedrawHandler.sleep(100);              
        }
        GameCanvas.SetImage();
        //this.invalidate();
    }
    else if(GameCanvas.slappingRight)                           
    {           
        for(int i = 0; i < 500; i+=100)
        {
            GameCanvas.SlapImage();
            mRedrawHandler.sleep(100);
        }       
        GameCanvas.SetImage();
        //this.invalidate();
    }

}

I would greatly appreciate if anyone helps me figure this problem out. I have tried many different approaches to this problem.

I just want to show the SlapImage for half a second, then revert back to the normal image till onFling is called again.

If you would like to see SetImage(), SlapLeft(), and SetImage(), let me know!

Thanks very much in advance!

EDIT

GameCanvas is not a Canvas obj. Its an activity that setsContentView(R.layout.game_canvas)

GameWindow is a custom ImageView


Solution

  • After some consideration, i decided to implement this solution. I think it works fairly well.

    I'm still not sure why my previous way didn't work. If anyone would still like to elaborate I would appreciate.

    GameCanvas. I created this thread.

    resetSlap = new Thread()
    {
            public void run()
            {           
                while(true)
                {
                    try 
                    {
                        Thread.sleep(500);
                        GameWindow.post(new Runnable()
                        {
                            public void run()
                            {                           
                                GameWindow.setImageBitmap(images[0]);
                                GameWindow.postInvalidate();
                            }
                    });
                    } catch (InterruptedException e)
                    {                               
                        e.printStackTrace();
                    }                                   
                }
            }
        };          
    

    Baiscally, every half-second I want to reset the image back to normal

    Then in the OnFling I wrote

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY)
        {           
            if(GameWindow.getContext() == null)
                return false;
    
            if((e1.getY() >= GameWindow.getHeight()) && (e1.getY() <= GameWindow.getBottom()))
            {       
    
                try
                {                
                    if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
                        return false;               
    
                    // right to left slap               
                    if((e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE) && 
                            (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY))
                    {                                   
                        slappingLeft = true;
    
                        //Animate Slap  
                        SlapLeft();
                        SlapSound();
                        if(voice.nextInt(10) < 3)
                        {
                            Voice.start();
                        }
    
                    }  
                    // left to right slap
                    else if ((e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE) && 
                            (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY))               
                    {       
                        slappingRight = true;
    
                        //Animate Slap
                        SlapImage();
                        SlapSound();
                        if(voice.nextInt(10) < 3)
                        {
                            Voice.start();
                        }
                    }
                }                
                catch (Exception e)                 
                {                                   
                    //nothing                                   
                }               
            }
    
            slappingLeft = slappingRight  = false;
            return true;            
        }
    

    Basically, if I was slapping left I would call Slap left and wait for the thread to reset and if i was slapping right I would call Slap Right and wait for the thread to reset.

    This answer works well for my situation.. I hope this helps :D

    Thank you all for your help.