Search code examples
javaandroidcollision-detectioncollision

how to make score go up after first collision


how to make score go up after first collision

Currently my score keeps increasing as objects are colliding, I want my score to go up by only one point after the first collision. How do I accomplish this and delete an imageview off the screen on collision? I think this is happening because thread.sleep is updating every 30 millis and increasing the score by 1 every 30 millis if collision is happening, but I dont know how to check and stop after the first collision.

  //collision bool and variables
  public boolean Collision(ImageView net, ImageView ball)
{
    Rect BallRect = new Rect();
    ball.getHitRect(BallRect);
    Rect NetRect = new Rect();
    net.getHitRect(NetRect);
    return BallRect.intersect(NetRect);
}

updating and checking collision

//increasing score  
Thread t = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(30);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run(){Render();}});}
            }catch (InterruptedException e) {}}};

    t.start();

 }

 public void Render()
 {
    changePos();
    if(Collision(net, ball))
    {
        points += 1;//POINT INCREASE
        this.score.setText("Score: " + points);
    }
 }

ALL MAIN.JAVA CODE TOGETHER:

public class MainActivity extends AppCompatActivity
{
//Layout
private RelativeLayout myLayout = null;

//Screen Size
private int screenWidth;
private int screenHeight;

//Position
private float ballDownY;
private float ballDownX;

//Initialize Class
private Handler handler = new Handler();
private Timer timer = new Timer();

//Images
private ImageView net = null;
private ImageView ball = null;

//score
private TextView score = null;

//for net movement along x-axis
public float x = 0;
public float y = 0;

//points
private int points = 0;


 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
    super.onCreate(savedInstanceState);

    this.setContentView(R.layout.activity_main);
    this.myLayout = (RelativeLayout) findViewById(R.id.myLayout);

    this.score = (TextView) findViewById(R.id.score);

    //net & ball imgs
    this.net = (ImageView) findViewById(R.id.net);
    this.ball = (ImageView) findViewById(R.id.ball);

    //retrieving screen size
    WindowManager wm = getWindowManager();
    Display disp = wm.getDefaultDisplay();
    Point size = new Point();
    disp.getSize(size);
    screenWidth = size.x;
    screenHeight = size.y;

    //move to out of screen
    this.ball.setX(-80.0f);
    this.ball.setY(screenHeight + 80.0f);


    Thread t = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(30);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run(){Render();}});}
            }catch (InterruptedException e) {}}};

    t.start();

}

public void Render()
{
    changePos();
    if(Collision(net, ball))
    {
        points += 1;//POINT INCREASE
        this.score.setText("Score: " + points);
    }
}


//changes position of ball along top x-axis
public void changePos() {

    //ball falls downwards
    ballDownY += 20;
    if (ball.getY() > screenHeight) {
        ballDownX = (float) Math.floor((Math.random() * (screenWidth - 
 ball.getWidth())));
        ballDownY = -100.0f;

    }
    ball.setY(ballDownY);
    ball.setX(ballDownX);

    //make net follow finger, along x and y axis
    myLayout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            x = event.getX();
            y = event.getY();

            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                net.setX(x);
                net.setY(y);
            }
            return true;
        }

    });
}
//collision method and variables
public boolean Collision(ImageView net, ImageView ball)
{
    Rect BallRect = new Rect();
    ball.getHitRect(BallRect);
    Rect NetRect = new Rect();
    net.getHitRect(NetRect);
    return BallRect.intersect(NetRect);
 }
}

Solution

  • why not use a boolean to indicate first collision?

    //points
    private int points = 0;
    
    //indicate first collision
    private boolean isCollide = false; //set default to false
    

    and then in Render() change that boolean

    if(Collision(net, ball))
    {
        isCollide = true; //first collision occur
        points += 1;//POINT INCREASE
        this.score.setText("Score: " + points);
    }
    

    last, stop and make view gone

    Thread t = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(30);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run(){
                            if (isCollide) {
                                net.setVisibility(View.GONE);
                                ball.setVisibility(View.GONE);
                            } else {
                                Render();
                            }
                        }
                    });
    
                    if (isCollide) Thread.currentThread().interrupt(); // stop the thread
                }
            }catch (InterruptedException e) {}}};
    
    t.start();