onFling() 2D 动画问题

发布于 2025-01-02 21:15:15 字数 3186 浏览 1 评论 0原文

当我抛出图像视图时,我试图运行一个非常简单的 2D 动画。我有两项活动涉及此。

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;            
    }       

和 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();
    }

}

如果有人帮助我解决这个问题,我将不胜感激。我尝试了许多不同的方法来解决这个问题。

我只想显示 SlapImage 半秒钟,然后恢复到正常图像,直到再次调用 onFling。

如果您想查看 SetImage()、SlapLeft() 和 SetImage(),请告诉我!

预先非常感谢!

编辑

GameCanvas 不是 Canvas 对象。它的活动设置ContentView(R.layout.game_canvas)

GameWindow是自定义ImageView

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盛夏尉蓝 2025-01-09 21:15:15

我在你的代码中发现了问题。也许这对结果有影响,但我不确定。问题是您应该在 if 语句中使用括号,因为运算符 &&具有比比较运算符更高的优先级。所以你的代码应该如下所示:

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;

                    slappingLeft = false;
                }  
                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;

                    slappingRight = false;

                }
            }                
            catch (Exception e)                 
            {                                   
                //nothing                                   
            }               
        }
        running = false;
        return false;           
    }

我不知道这是否会影响你的代码的逻辑,但在我看来是的。

I've found the problem in your code. Maybe it is influence on the result but I'm not sure. The problem is that you should use brackets in your if statements because operator && has higher priority then comparison operators. So your code should look in the following way:

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;

                    slappingLeft = false;
                }  
                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;

                    slappingRight = false;

                }
            }                
            catch (Exception e)                 
            {                                   
                //nothing                                   
            }               
        }
        running = false;
        return false;           
    }

I don't know if this influence on the logic of your code but it seems to me that yes.

羁绊已千年 2025-01-09 21:15:15

经过一番考虑,我决定实施这个解决方案。我认为效果相当好。

我仍然不确定为什么我之前的方法不起作用。如果有人仍然想详细说明,我将不胜感激。

游戏画布。我创建了这个线程。

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();
                }                                   
            }
        }
    };          

基本上,每半秒我想将图像重置回正常

然后在 OnFling 中我写

@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;            
    }

基本上,如果我向左拍打,我会调用 Slap left 并等待线程重置,如果我向右侧拍打,我会调用 Slap正确并等待线程重置。

这个答案很适合我的情况。我希望这有帮助:D

谢谢大家的帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文