0

The way I have set up my code is I have 3 white rectangles that are as tall as the screen and each 1/9 of the screen wide. Each are equally spaced out accross the screen. I also have 3 other black rectangles, 1 on top of each white...same left and right as the white rectangles so to the user it looks like there is a gap in the white rectangle when in reality it is just a black rectangle of lesser height over a white rectangle as tall as the screen. Anyway, the player has to pass a ball through this "gap" in the white rectangle as the rectangles move across the screen. I was wondering how I would detect collision with the "only white region". By that I mean have code where the ball is safe if it is touching both the black and white rectangle but not safe if the player doesn't hit both the black and white rectangle (If I said not safe if it only hit the white rectangle the player would die every time since like I said the white rectangle is as tall as the screen overlapped by a shorter black rectangle). Here is the code for my mainactivity:

public class GameScreen extends ActionBarActivity {
public static final String TAG = "BallActivity";
BallView mBallView = null;

Rectangle rectWhite1 = null
        , rectBlack1= null
        , rectWhite2 = null
        , rectBlack2= null
        , rectWhite3 = null
        , rectBlack3= null
        ,collisionRectangle = null;
int mPointMargin = 5; //specifies width of point adding zone when ball passes rectangle's right side

Handler RedrawHandler = new Handler(); //so redraw occurs in main thread
Handler RedrawHandler2 = new Handler();
Timer mTmr , mTmr2 = null;
TimerTask mTsk , mTsk2 = null;
int mScrWidth, mScrHeight;
int mRectSpeed = 7; //Game max speed should be 12!!!
int mBallSpeed = 15;
Scoreboard mScoreboard = new Scoreboard();
android.graphics.PointF mBallPos, mBallSpd;
//Going to be used to check if ball hits only white rectangle...use intersects method
Rect rectObject;



@Override
protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE); //hide title bar
    //set app to full screen and keep screen on
    getWindow().setFlags(0xFFFFFFFF, LayoutParams.FLAG_FULLSCREEN | LayoutParams.FLAG_KEEP_SCREEN_ON);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game_screen);
    //create pointer to main screen
    final FrameLayout mainView = (FrameLayout) findViewById(R.id.main_view);

    //get screen dimensions
    Display display = getWindowManager().getDefaultDisplay();
    mScrWidth = display.getWidth();
    mScrHeight = display.getHeight();
    mBallPos = new PointF();
    mBallSpd = new PointF();




    //create variables for ball position and speed
    mBallPos.x = mScrWidth / 7;
    mBallPos.y = mScrHeight / 2;
    mBallSpd.x = 0;
    mBallSpd.y = 0;

    //create initial ball

    mBallView = new BallView(this, mBallPos.x, mBallPos.y, mScrWidth/30);


    //**************Create initial 6 rectangles****************
    rectWhite1 = new Rectangle(this, ((mScrWidth/9) * 8) + mScrWidth, 0 , ((mScrWidth/9) * 9) + mScrWidth, mScrHeight, 0xFFFFFFFF);
    rectBlack1 = new Rectangle(this,  ((mScrWidth/9) * 8) + mScrWidth, (mScrHeight/10) * 4 ,((mScrWidth/9) * 9) + mScrWidth ,(mScrHeight/10) * 6, 0xFFFFFF00);
    rectWhite2 = new Rectangle(this, ((mScrWidth/9) * 5) + mScrWidth, 0, ((mScrWidth/9) * 6) + mScrWidth, mScrHeight,0xFFFFFFFF);
    rectBlack2 = new Rectangle(this, ((mScrWidth/9) * 5) + mScrWidth, (mScrHeight/10) * 4, ((mScrWidth/9) * 6) + mScrWidth, (mScrHeight/10) * 6, 0xFFFFFF00);
    rectWhite3 = new Rectangle(this, ((mScrWidth/18) * 3) + mScrWidth, 0, ((mScrWidth/18) * 5) + mScrWidth, mScrHeight, 0xFFFFFFFF);
    rectBlack3 = new Rectangle(this, ((mScrWidth/18) * 3) + mScrWidth, (mScrHeight/10) * 4, ((mScrWidth/18) * 5) + mScrWidth, (mScrHeight/10) * 6 , 0xFFFFFF00);



    //Add to view

    mainView.addView(rectWhite1);
    rectWhite1.invalidate();

    mainView.addView(rectWhite2);
    rectWhite2.invalidate();

    mainView.addView(rectWhite3);
    rectWhite3.invalidate();

    mainView.addView(rectBlack1);
    rectBlack1.invalidate();

    mainView.addView(rectBlack2);
    rectBlack2.invalidate();

    mainView.addView(rectBlack3);
    rectBlack3.invalidate();


    mainView.addView(mBallView); //add ball to main screen
    mBallView.invalidate(); //call onDraw in BallView



    //listener for accelerometer, use anonymous class for simplicity
    ((SensorManager) getSystemService(Context.SENSOR_SERVICE)).registerListener(
            new SensorEventListener() {
                @Override
                public void onSensorChanged(SensorEvent event) {
                    //set ball speed based on phone tilt (ignore Z axis)
                    mBallSpd.x = -event.values[0] * mBallSpeed;
                    mBallSpd.y = event.values[1] * mBallSpeed;
                    //timer event will redraw ball
                }

                @Override
                public void onAccuracyChanged(Sensor sensor, int accuracy) {
                } //ignore
            },
            ((SensorManager) getSystemService(Context.SENSOR_SERVICE))
                    .getSensorList(Sensor.TYPE_ACCELEROMETER).get(0),
            SensorManager.SENSOR_DELAY_NORMAL);


} //OnCreate(mScrWidth/10) * 6

//For state flow see http://developer.android.com/reference/android/app/Activity.html
@Override
public void onPause() //app moved to background, stop background threads
{
    mTmr.cancel(); //kill\release timer (our only background thread)
    mTmr = null;
    mTsk = null;
    mTmr2.cancel();
    mTmr2 = null;
    mTsk2 = null;
    super.onPause();
}


@Override
public void onResume() //app moved to foreground (also occurs at app startup)
{
    final TextView scoreTextView = (TextView)findViewById(R.id.scoreTextView);

    final int[] blackRectangleTopHeights = {0, (mScrHeight/10) * 1, (mScrHeight/10) * 2,(mScrHeight/10) * 3,
                                               (mScrHeight/10) * 4,(mScrHeight/10) * 5,(mScrHeight/10) * 6,
                                               (mScrHeight/10) * 7};

    final int[] blackRectangleBottomHeights = {(mScrHeight/10) * 3,(mScrHeight/10) * 4,(mScrHeight/10) * 5,
                                              (mScrHeight/10) * 6, (mScrHeight/10) * 7,(mScrHeight/10) * 8,
                                              (mScrHeight/10) * 9,mScrHeight};
    final Random randomGenerator = new Random();


    runCircle();

    //************Set up rectangle moving mechanism and Logic*********************

    mTmr2 = new Timer();
    mTsk2 = new TimerTask() {
        @Override
        public void run() {

            int randomNumber = randomGenerator.nextInt(blackRectangleTopHeights.length);
            int topBlackRectHeight = blackRectangleTopHeights[randomNumber];
            int bottomBlackRectHeight = blackRectangleBottomHeights[randomNumber];

            //Moves rectangles left across the screen
            int rectWhite1Left = rectWhite1.getTheLeft() - mRectSpeed;
            int rectWhite1Right = rectWhite1.getTheRight() - mRectSpeed;
            rectWhite1.setX(rectWhite1Left, rectWhite1Right);

            int rectBlack1Left = rectBlack1.getTheLeft() - mRectSpeed;
            int rectBlack1Right = rectBlack1.getTheRight() - mRectSpeed;
            rectBlack1.setX(rectBlack1Left, rectBlack1Right);

            int rectWhite2Left = rectWhite2.getTheLeft() - mRectSpeed;
            int rectWhite2Right = rectWhite2.getTheRight() - mRectSpeed;
            rectWhite2.setX(rectWhite2Left, rectWhite2Right);

            int rectBlack2Left = rectBlack2.getTheLeft() - mRectSpeed;
            int rectBlack2Right = rectBlack2.getTheRight() - mRectSpeed;
            rectBlack2.setX(rectBlack2Left, rectBlack2Right);

            int rectWhite3Left = rectWhite3.getTheLeft() - mRectSpeed;
            int rectWhite3Right = rectWhite3.getTheRight() - mRectSpeed;
            rectWhite3.setX(rectWhite3Left, rectWhite3Right);

            int rectBlack3Left = rectBlack3.getTheLeft() - mRectSpeed;
            int rectBlack3Right = rectBlack3.getTheRight() - mRectSpeed;
            rectBlack3.setX(rectBlack3Left, rectBlack3Right);

            //Cycles rectangles when they hit left side of the screen
            // Randomizes where middle rectangle will be postitoned vertically
            if (rectWhite1.getTheRight() > 0 && rectWhite1.getTheRight() < 20) {
                rectWhite1.setX(mScrWidth, rectWhite1.getRectWidth() + mScrWidth);
            }

            if (rectBlack1.getTheRight() > 0 && rectBlack1.getTheRight() < 20) {
                rectBlack1.setX(mScrWidth, rectBlack1.getRectWidth() + mScrWidth);
                rectBlack1.setY(topBlackRectHeight, bottomBlackRectHeight);
            }

            if (rectWhite2.getTheRight() > 0 && rectWhite2.getTheRight() < 20) {
                rectWhite2.setX(mScrWidth, rectWhite2.getRectWidth() + mScrWidth);
            }

            if (rectBlack2.getTheRight() > 0 && rectBlack2.getTheRight() < 20) {
                rectBlack2.setX(mScrWidth, rectBlack2.getRectWidth() + mScrWidth);
                rectBlack2.setY(topBlackRectHeight, bottomBlackRectHeight);
            }

            if (rectWhite3.getTheRight() > 0 && rectWhite3.getTheRight() < 20) {
                rectWhite3.setX(mScrWidth, rectWhite3.getRectWidth() + mScrWidth);
            }

            if (rectBlack3.getTheRight() > 0 && rectBlack3.getTheRight() < 20) {
                rectBlack3.setX(mScrWidth, rectBlack3.getRectWidth() + mScrWidth);
                rectBlack3.setY(topBlackRectHeight, bottomBlackRectHeight);
            }

            //*********Keeps track of score and update TextView with score*************
            if (rectWhite1.getTheRight() > Math.round(mBallPos.x) - 5 && rectWhite1.getTheRight() < Math.round(mBallPos.x) + 5) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });

            }

            if (rectWhite2.getTheRight() > Math.round(mBallPos.x) - mPointMargin && rectWhite2.getTheRight() < Math.round(mBallPos.x) + mPointMargin) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });


            }

            if (rectWhite3.getTheRight() > Math.round(mBallPos.x) - mPointMargin && rectWhite3.getTheRight() < Math.round(mBallPos.x) + mPointMargin) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });

            }

            //Speeds up game correspondingly to the score
            if (mScoreboard.getScore() == 10) {
                mRectSpeed = 8;
                mBallSpeed = 16;
            }
            if (mScoreboard.getScore() == 20) {
                mRectSpeed = 9;
                mBallSpeed = 17;
            }
            if (mScoreboard.getScore() == 30) {
                mRectSpeed = 10;
                mBallSpeed = 18;
            }
            if (mScoreboard.getScore() == 40) {
                mRectSpeed = 11;
                mBallSpeed = 19;
            }
            if (mScoreboard.getScore() == 50) {
                mRectSpeed = 12;
                mBallSpeed = 20;
            }
            if (mScoreboard.getScore() == 60) {
                mRectSpeed = 13;
                mBallSpeed = 21;
            }
            if (mScoreboard.getScore() == 70) {
                mRectSpeed = 14;
                mBallSpeed = 22;
            }
            if (mScoreboard.getScore() == 80) {
                mRectSpeed = 15;
                mBallSpeed = 23;
            }
            if (mScoreboard.getScore() == 90) {
                mBallSpeed = 24;
            }
            if (mScoreboard.getScore() == 100) {
                mBallSpeed = 25;
            }




            RedrawHandler2.post(new Runnable() {
                public void run() {
                    rectWhite1.invalidate();
                    rectWhite2.invalidate();
                    rectWhite3.invalidate();
                    rectBlack1.invalidate();
                    rectBlack2.invalidate();
                    rectBlack3.invalidate();

                }
            });



        }
    };
    mTmr2.schedule(mTsk2, 10, 10); //start timer (Timer 2)


    super.onResume();
} // onResume

private void runCircle() {

    //create timer to move ball to new position
    mTmr = new Timer();
    mTsk = new TimerTask() {
        public void run() {

    //move ball based on current speed
            mBallPos.x += mBallSpd.y;
            mBallPos.y += -mBallSpd.x;

            //if ball goes off screen, reposition to opposite side of screen
            if (mBallPos.x > mScrWidth) mBallPos.x = 0;
            if (mBallPos.y > mScrHeight) mBallPos.y = 0;
            if (mBallPos.x < 0) mBallPos.x = mScrWidth;
            if (mBallPos.y < 0) mBallPos.y = mScrHeight;

            //update ball class instance
            mBallView.x = mBallPos.x;
            mBallView.y = mBallPos.y;

        //redraw ball. Must run in background thread to prevent thread lock.
            RedrawHandler.post(new Runnable() {
                public void run() {
                    mBallView.invalidate();
                }
            });

      //If ball hits sides it goes to the redirect screen, YOU LOSE!
            if (mBallPos.y  == mScrHeight || mBallPos.y == 0 || mBallPos.x == mScrWidth|| mBallPos.x == 0 ) {

              goToRedirectScreen();
            }




        } //run
    }; // TimerTask

    mTmr.schedule(mTsk, 10, 10); //start timer (Timer)
}


@Override
public void onDestroy() //main thread stopped
{
    super.onDestroy();
    //wait for threads to exit before clearing app
    System.runFinalizersOnExit(true);
    //remove app from memory
    android.os.Process.killProcess(android.os.Process.myPid());
}

public void goToRedirectScreen()
{
    Intent intent = new Intent(this, Redirect.class);
    startActivity(intent);
}



}

I need a method that will check if mBallView is only touching the white rectangle and not both the black and white. Or if you have any other solutions I am open to all approaches. Thank you in advance.

I have already referenced:

How to fix circle and rectangle overlap in collision response

and

Circle-Rectangle collision detection

But I did not see how I could apply them to my particular case.

Community
  • 1
  • 1
Benyam Ephrem
  • 448
  • 6
  • 20
  • why do you think the linked methods dont apply? – Calum Feb 27 '15 at 03:20
  • @Calum All the solutions are very complicated and I have no idea how to use them for my purposes. I just need a simple method that'll detect when the ball is intersecting one of the rectangles. The ball view moves fairly quickly and I've tried the other answers and they don't work for a fast, dynamic game. – Benyam Ephrem Feb 27 '15 at 04:29

0 Answers0