Search code examples
javaandroidonflingbreakout

Java: Breakout game, move player as I swipe?


I'm making a simple Breakout game, and so far I have created the ball and the player. I made the ball so that it moves to the position you touch, but I'd rather have it moving towards the direction I swipe. As in, the player moves along with my finger. Here's the code I have in my MainActivity:

package com.example.breakout;

import android.os.Bundle;
import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class MainActivity extends Activity implements OnTouchListener, OnGestureListener{

    BreakoutView bv;
    GestureDetector gs;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bv = new BreakoutView(this);
        setContentView(bv);
        bv.setOnTouchListener(this);


        gs = new GestureDetector(MainActivity.this, this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);

        return true;
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        /*if(arg1.getY()<600){
            bv.p1.x = arg1.getX();
            bv.p1.y = 600;
        }*/
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent me){
        return gs.onTouchEvent(me);
    }

    @Override
    public boolean onDown(MotionEvent arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        /*if(e2.getX()>e1.getX()){
            //Move right
            bv.p1.x = e2.getX();

        }*/

        return false;
    }

    @Override
    public void onLongPress(MotionEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
            float arg3) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onShowPress(MotionEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onSingleTapUp(MotionEvent arg0) {
        // TODO Auto-generated method stub
        return false;
    }

}

So, the two methods I have tried are the onTouch and the onFling ones. The onTouch "teleports" my player where I touch, which isn't what I want. The onFling only moves my player when I'm done swiping, so that doesnt work either. My question is, how can I make it move as I swipe my finger? Do I use onDown? Any help is appreciated.

Thanks!


Solution

  • Assuming you have some sort of game loop set up where the UI is updated on intervals:

    /**
     * Onclick event for Touch Screen
     */
    @Override
    public boolean onTouchEvent(MotionEvent input) {
        if (input.getAction() == MotionEvent.ACTION_MOVE) {
            float currX = input.getX();
            float currY = input.getY();
    
            if (!swiping) {
                swiping = true;
                swipeStartY = currY;
                swipeStartX = currX;
            }
    
            if (swiping) {          
                double newDirection = Math.atan2((currY-ball.getY()),currX-ball.getX());
                ball.setDirection(newDirection);
            }
    
        } else if (input.getAction() == MotionEvent.ACTION_UP) {
            if (swiping) {
                swiping = false;
            }
        }
    }
    

    This way the ball's direction is updated on each tick of the game thread and moves towards your finger (the touch event X/Y location). I'm not sure how you have set up your drawing/physics/etc. so I can't provide meaningful function calls here. If you need to modify it so it swipes in a straight line after you lift your finger then store the initial X/Y point (swipeStartX/swipeStartY in this case) and only set the new direction after you stop swiping.

    EDIT:

    I should mention, my class definition that contains this code is as follows:

    public class GameView extends SurfaceView implements SurfaceHolder.Callback {
      ....
    }