Back to project page BallDemo.
The source code is released under:
GNU General Public License
If you think the Android project BallDemo listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package uk.ac.reading.sis05kol.mooc; /*w ww . ja v a2s . co m*/ //Other parts of the android libraries that we use import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; public class TheGame extends GameThread{ //Will store the image of a ball private Bitmap mBall; //The X and Y position of the ball on the screen //The point is the top left corner, not middle, of the ball //Initially at -100 to avoid them being drawn in 0,0 of the screen private float mBallX = -100; private float mBallY = -100; //The speed (pixel/second) of the ball in direction X and Y private float mBallSpeedX = 0; private float mBallSpeedY = 0; //Will store the image of the Paddle used to hit the ball private Bitmap mPaddle; //Paddle's x position. Y will always be the bottom of the screen private float mPaddleX = 0; //Will store the image of the smiley ball (score ball) private Bitmap mSmileyBall; //The X and Y position of the ball on the screen //The point is the top left corner, not middle, of the ball //Initially at -100 to avoid them being drawn in 0,0 of the screen private float mSmileyBallX = -100; private float mSmileyBallY = -100; //Will store the image of the smiley ball (score ball) private Bitmap mSadBall; //The X and Y position of the SadBalls on the screen //The point is the top left corner, not middle, of the balls //Initially at -100 to avoid them being drawn in 0,0 of the screen private float[] mSadBallX = {-100,-100,-100}; private float[] mSadBallY = new float[3]; //This will store the min distance allowed between a big ball and the small red ball //This is used to check collisions private float mMinDistanceBetweenRedBallAndBigBall = 0; //This is run before anything else, so we can prepare things here public TheGame(GameView gameView) { //House keeping super(gameView); //Prepare the image so we can draw it on the screen (using a canvas) mBall = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.small_red_ball); //Prepare the image of the paddle so we can draw it on the screen (using a canvas) mPaddle = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.yellow_ball); //Prepare the image of the SmileyBall so we can draw it on the screen (using a canvas) mSmileyBall = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.smiley_ball); //Prepare the image of the SadBall(s) so we can draw it on the screen (using a canvas) mSadBall = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.sad_ball); } //This is run before a new game (also after an old game) @Override public void setupBeginning() { //Initialise speeds //mCanvasWidth and mCanvasHeight are declared and managed elsewhere mBallSpeedX = mCanvasWidth / 3; mBallSpeedY = mCanvasHeight / 3; //Place the ball in the middle of the screen. //mBall.Width() and mBall.getHeigh() gives us the height and width of the image of the ball mBallX = mCanvasWidth / 2; mBallY = mCanvasHeight / 2; //Place Paddle in the middle of the screen mPaddleX = mCanvasWidth / 2; //Place SmileyBall in the top middle of the screen mSmileyBallX = mCanvasWidth / 2; mSmileyBallY = mSmileyBall.getHeight()/2; //Place all SadBalls forming a pyramid underneath the SmileyBall mSadBallX[0] = mCanvasWidth / 3; mSadBallY[0] = mCanvasHeight / 3; mSadBallX[1] = mCanvasWidth - mCanvasWidth / 3; mSadBallY[1] = mCanvasHeight / 3; mSadBallX[2] = mCanvasWidth / 2; mSadBallY[2] = mCanvasHeight / 5; //Get the minimum distance between a small ball and a bigball //We leave out the square root to limit the calculations of the program //Remember to do that when testing the distance as well mMinDistanceBetweenRedBallAndBigBall = (mPaddle.getWidth() / 2 + mBall.getWidth() / 2) * (mPaddle.getWidth() / 2 + mBall.getWidth() / 2); } @Override protected void doDraw(Canvas canvas) { //If there isn't a canvas to do nothing //It is ok not understanding what is happening here if(canvas == null) return; //House keeping super.doDraw(canvas); //canvas.drawBitmap(bitmap, x, y, paint) uses top/left corner of bitmap as 0,0 //we use 0,0 in the middle of the bitmap, so negate half of the width and height of the ball to draw the ball as expected //A paint of null means that we will use the image without any extra features (called Paint) //draw the image of the ball using the X and Y of the ball canvas.drawBitmap(mBall, mBallX - mBall.getWidth() / 2, mBallY - mBall.getHeight() / 2, null); //Draw Paddle using X of paddle and the bottom of the screen (top/left is 0,0) canvas.drawBitmap(mPaddle, mPaddleX - mPaddle.getWidth() / 2, mCanvasHeight - mPaddle.getHeight() / 2, null); //Draw SmileyBall canvas.drawBitmap(mSmileyBall, mSmileyBallX - mSmileyBall.getWidth() / 2, mSmileyBallY - mSmileyBall.getHeight() / 2, null); //Loop through all SadBall for(int i = 0; i < mSadBallX.length; i++) { //Draw SadBall in position i canvas.drawBitmap(mSadBall, mSadBallX[i] - mSadBall.getWidth() / 2, mSadBallY[i] - mSadBall.getHeight() / 2, null); } } //This is run whenever the phone is touched by the user @Override protected void actionOnTouch(float x, float y) { //Increase/decrease the speed of the ball making the ball move towards the touch mPaddleX = x - mPaddle.getWidth() / 2; } //This is run whenever the phone moves around its axises @Override protected void actionWhenPhoneMoved(float xDirection, float yDirection, float zDirection) { //Ensure the paddle stays on the screen if(mPaddleX >= 0 && mPaddleX <= mCanvasWidth) { //Change the X value according to the x direction of the phone mPaddleX = mPaddleX - xDirection; //after movement ensure it is still on the screen if(mPaddleX < 0) mPaddleX = 0; if(mPaddleX > mCanvasWidth) mPaddleX = mCanvasWidth; } } //This is run just before the game "scenario" is printed on the screen @Override protected void updateGame(float secondsElapsed) { float distanceBetweenBallAndPaddle; //If the ball moves down on the screen perform potential paddle collision if(mBallSpeedY > 0) { //Get actual distance (without square root - remember?) between the mBall and the ball being checked distanceBetweenBallAndPaddle = (mPaddleX - mBallX) * (mPaddleX - mBallX) + (mCanvasHeight - mBallY) *(mCanvasHeight - mBallY); //Check if the actual distance is lower than the allowed => collision if(mMinDistanceBetweenRedBallAndBigBall >= distanceBetweenBallAndPaddle) { //Get the present velocity (this should also be the velocity going away after the collision) float velocityOfBall = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //Change the direction of the ball mBallSpeedX = mBallX - mPaddleX; mBallSpeedY = mBallY - mCanvasHeight; //Get the velocity after the collision float newVelocity = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //using the fraction between the original velocity and present velocity to calculate the needed //speeds in X and Y to get the original velocity but with the new angle. mBallSpeedX = mBallSpeedX * velocityOfBall / newVelocity; mBallSpeedY = mBallSpeedY * velocityOfBall / newVelocity; } } //Move the ball's X and Y using the speed (pixel/sec) mBallX = mBallX + secondsElapsed * mBallSpeedX; mBallY = mBallY + secondsElapsed * mBallSpeedY; //Check if the ball hits either the left side or the right side of the screen //But only do something if the ball is moving towards that side of the screen //If it does that => change the direction of the ball in the X direction if((mBallX <= mBall.getWidth() / 2 && mBallSpeedX < 0) || (mBallX >= mCanvasWidth - mBall.getWidth() / 2 && mBallSpeedX > 0) ) { mBallSpeedX = -mBallSpeedX; } distanceBetweenBallAndPaddle = (mSmileyBallX - mBallX) * (mSmileyBallX - mBallX) + (mSmileyBallY - mBallY) *(mSmileyBallY - mBallY); //Check if the actual distance is lower than the allowed => collision if(mMinDistanceBetweenRedBallAndBigBall >= distanceBetweenBallAndPaddle) { //Get the present velocity (this should also be the velocity going away after the collision) float velocityOfBall = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //Change the direction of the ball mBallSpeedX = mBallX - mSmileyBallX; mBallSpeedY = mBallY - mSmileyBallY; //Get the velocity after the collision float newVelocity = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //using the fraction between the original velocity and present velocity to calculate the needed //speeds in X and Y to get the original velocity but with the new angle. mBallSpeedX = mBallSpeedX * velocityOfBall / newVelocity; mBallSpeedY = mBallSpeedY * velocityOfBall / newVelocity; //Increase score updateScore(1); } //Loop through all SadBalls for(int i = 0; i < mSadBallX.length; i++) { //Perform collisions (if necessary) between SadBall in position i and the red ball //Get actual distance (without square root - remember?) between the mBall and the ball being checked distanceBetweenBallAndPaddle = (mSadBallX[i] - mBallX) * (mSadBallX[i] - mBallX) + (mSadBallY[i] - mBallY) *(mSadBallY[i] - mBallY); //Check if the actual distance is lower than the allowed => collision if(mMinDistanceBetweenRedBallAndBigBall >= distanceBetweenBallAndPaddle) { //Get the present velocity (this should also be the velocity going away after the collision) float velocityOfBall = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //Change the direction of the ball mBallSpeedX = mBallX - mSadBallX[i]; mBallSpeedY = mBallY - mSadBallY[i]; //Get the velocity after the collision float newVelocity = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY); //using the fraction between the original velocity and present velocity to calculate the needed //speeds in X and Y to get the original velocity but with the new angle. mBallSpeedX = mBallSpeedX * velocityOfBall / newVelocity; mBallSpeedY = mBallSpeedY * velocityOfBall / newVelocity; } } //If the ball goes out of the top of the screen and moves towards the top of the screen => //change the direction of the ball in the Y direction if(mBallY <= mBall.getWidth() / 2 && mBallSpeedY < 0) { mBallSpeedY = -mBallSpeedY; } //If the ball goes out of the bottom of the screen => lose the game if(mBallY >= mCanvasHeight) { setState(GameThread.STATE_LOSE); } } }