Skip to content

Instantly share code, notes, and snippets.

@robsbots robsbots/TheGame.java
Last active Aug 29, 2015

Embed
What would you like to do?
Game file as of week 5. Sounds, lives, ball speed up on score
package uk.ac.reading.sis05kol.mooc;
//Other parts of the android libraries that we use
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.media.AudioManager;
import android.media.SoundPool;
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;
//Create a Soundpool object and load each sound for the game
private SoundPool mSoundPool;
private int mSoundBounce;
private int mSoundLose;
private int mSoundLoseLife;
private int mSoundScore;
private int mSoundPaddle;
private int mSoundNewgame;
//Create a variable to hold the count of lives
private byte mLives;
//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);
// Load sound clip for each sound event
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
//this.getApplicationContext()
mSoundBounce = mSoundPool.load(mContext, R.raw.click, 1);
mSoundLose = mSoundPool.load(mContext, R.raw.sadtrombone, 1);
mSoundScore = mSoundPool.load(mContext, R.raw.score, 1);
mSoundPaddle = mSoundPool.load(mContext, R.raw.bounce, 1);
mSoundNewgame = mSoundPool.load(mContext, R.raw.start, 1);
mSoundLoseLife = mSoundPool.load(mContext, R.raw.clang, 1);
}
//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);
// Play a sound when the game starts
mSoundPool.play(mSoundNewgame, 100, 100, 1, 0, 1.0f);
// Set number of lives to 3
mLives=3;
}
@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);
}
// for each life we currently have draw a red ball in the top left of the screen
for(int i = 0; i < mLives; i++) {
canvas.drawBitmap(mBall, (i*30)+5, 20, 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;
//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;
// Play sound when paddle hit
mSoundPool.play(mSoundPaddle, 100, 100, 1, 0, 1.0f);
}
}
//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;
// Play sound when ball hits left or right side of screen
mSoundPool.play(mSoundBounce, 100, 100, 1, 0, 1.0f);
}
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;
// Speed up ball by 5% on every score
mBallSpeedX = mBallSpeedX * 1.05f;
mBallSpeedY = mBallSpeedY * 1.05f;
// Play sound when ball hits target
mSoundPool.play(mSoundScore, 100, 100, 1, 0, 1.0f);
//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;
mSoundPool.play(mSoundPaddle, 100, 100, 1, 0, 1.0f);
}
}
//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;
// Play sound when ball hits top of screen
mSoundPool.play(mSoundBounce, 100, 100, 1, 0, 1.0f);
}
//If the ball goes out of the bottom of the screen => lose the game
if(mBallY >= mCanvasHeight) {
// Play sound when paddle misses ball
mSoundPool.play(mSoundLoseLife, 100, 100, 1, 0, 1.0f);
// Decrease count of lives by one
mLives--;
// Have we run out of lives
if(mLives==0) {
// We are out of lives. Play sad sound and end game
mSoundPool.play(mSoundLose, 100, 100, 1, 0, 1.0f);
setState(GameThread.STATE_LOSE);
}
else {
// We still have some lives left. Pause the game
setState(GameThread.STATE_PAUSE);
//Place the ball in the middle of the screen.
mBallX = mCanvasWidth / 2;
mBallY = mCanvasHeight / 2;
//Reset ball speed to starting speed
mBallSpeedX = mCanvasWidth / 3;
mBallSpeedY = mCanvasHeight / 3;
}
}
}
}
// This file is part of the course "Begin Programming: Build your first mobile game" from futurelearn.com
// Copyright: University of Reading and Karsten Lundqvist
// It is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// It is is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with it. If not, see <http://www.gnu.org/licenses/>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.