0

I'm trying to drag and launch a projectile, like Angry Birds. The dragging part works fine, but when I release the touch (i.e ACTION_UP), sometimes the ball instantly ends up at the boundaries while other times, it crashes with StackOverflowError. What should I do to avoid the error and make the movement smooth? Here is my code:

public class BallView extends View{

static Log log;
Bitmap ball;
float xStart;
float yStart;
float xCurrent;
float yCurrent;
int xMax;
int yMax;
float xVector;
float yVector;

public BallView(Context context){
    super(context);
    this.setFocusable(true);
    ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
    xStart = 125;
    yStart = 275;
    xCurrent = xStart;
    yCurrent = yStart;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    xMax = MeasureSpec.getSize(widthMeasureSpec);
    yMax = MeasureSpec.getSize(heightMeasureSpec);
    setMeasuredDimension(xMax, yMax);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(ball, xCurrent, yCurrent, null);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int eventaction = event.getAction();
    int X = (int)event.getX(); 
    int Y = (int)event.getY(); 

    switch (eventaction ) {
    case MotionEvent.ACTION_DOWN:
        break;
    case MotionEvent.ACTION_MOVE:
        xCurrent = X-30;
        yCurrent = Y-30;
        break; 

    case MotionEvent.ACTION_UP:
        Log.d("actionup", "done");
        xCurrent = X-30;
        yCurrent = Y-30;
        xVector = xStart-xCurrent;
        yVector = yStart-yCurrent;
        break;
    } 
    invalidate();
    if (eventaction == MotionEvent.ACTION_UP){
        launch(xVector, yVector);
    }
    return true; 
}

private void launch(float xVector, float yVector) {
    xCurrent = xCurrent + xVector;
    yCurrent = yCurrent + yVector;
    if (xCurrent < 0 || xCurrent > xMax || yCurrent < 0 || yCurrent >yMax){
        return;
    }
    invalidate();
    launch(xVector, yVector);
}
}

Any help is appreciated. Thank you.

2 Answers2

0

Hmm, without specific information from your error trace: a StackOverFlow error often occurs with a runaway recursive function. For you, in launch() if xCurrent = 0, xMax = 1000000 and xVector = .001, you will probably create a stackoverflow. I would start debugging here.

Also you seem to declare variables with the same name inside the same scope (ie, xVector and yVector as class member variables and they are also declared in launch(float xVector, float yVector)). This may confuse you, or anyone else, down the road. Try to use distinct variable names and conventional naming schemes.

Lastly, a useful operator is +=, it takes:

xCurrent = xCurrent + xVector;

and shortens it to:

xCurrent += xVector;

This saves you some unnecessary typing. Good luck!

Sam
  • 86,580
  • 20
  • 181
  • 179
0

Seems that your launch() method is a bad recursive call. See this answer.

private void launch(float xVector, float yVector) {
    new Thread(new Runnable() {

        @Override
        public void run() {
            while (!(xCurrent + xVector < 0 || xCurrent + xVector > xMax || 
                    yCurrent + yVector < 0 || yCurrent + yVector > yMax)){

                xCurrent = xCurrent + xVector;
                yCurrent = yCurrent + yVector;
                try{
                    Thread.sleep(200);
                }catch(Exception e){
                }
                postInvalidate();
            }
        }
    }).start;
}
Community
  • 1
  • 1
Hong Duan
  • 4,234
  • 2
  • 27
  • 50