Game Familiarisation

105 views 9:58 am 0 Comments June 26, 2023

Assignment brief

In this part of the assignment you are required to complete 4 requirements. Each of these requirements is based on extending a provided framework designed to support the development of a mobile game. This part of the assignment will help you develop your ability to understand third party code, follow instructions and undertake design work.

Game Familiarisation

MainMenu class

The starting point to run this game (or other games). It can also send and display game configuration information such as the highest score and difficulty level.

GameActivity class

This is the activity class for the game. It receives and sends data to the MainMenu and creates the custom view (GameView) object, passing any necessary parameters.

GameLoopThread class

This is the driver to make the game run at a particular speed.

How many Frames Per Second is the game set to…………..

What is the time period for each Frame …………………..

Identify where the game is updated, prior to drawing

GameView class

In what method is the GameLoopThread object created and set running

In what method is the GameeLoopThread stopped (running set to false)?

What calls the doDraw() method

Sprite class

Class for the objects to be drawn and moved around the screen.

Requirement 1: Basic Game Creation (15 marks)

1) Create a background

Find, or create, a background image for your application and add it to the res/drawable-mdpi folder.

Open the GameView class and notice the reference to the background image –

private Bitmap mBackgroundImage;

In GameView constructor method, generate the background bitmap by adding and amending the code below:

mBackgroundImage = BitmapFactory.decodeResource(this.getResources(),

R.drawable.yourBackgroundImage);

(note: you may need to import the BitmapFactory class in the source code)

In the surfaceCreated method, scale the background image to the screen size by putting the following code at as the first line in the method.

mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, getWidth(), getHeight(), true);

In the doDraw() method, draw the background by putting the code below as the first line in the method.

canvas.drawBitmap(mBackgroundImage, 0, 0, null);

Drawing the background image first has the effect of clearing the screen.

Run and test.

2) Draw a Sprite

In the project you will find a Sprite class. Open the GameView class and create a reference to the Sprite object by adding the line below to the member fields of the class;

private Sprite sprite;

In GameView resetGame() method, instantiate a new Sprite object;

sprite = new Sprite(this);

Add the following line to the doDraw() method of the GameView class to draw the sprite.

sprite.draw(canvas);

Find, or create, a more appropriate sprite image to your game. This should be about 50px by 50px. Change the image of the Sprite.

Run and test.

3) Configure the Sprite

Make the sprite move by adding adding sprite.update() to the update() method of the GameView class, as in the code below. Find where this method is called by the GameLoopThread class

public void update() {

sprite.update();

}

Change the horizontal speed of the sprite.

Introduce a vertical component to speed (un-comment the line of code in the update() method).

Use the random object to introduce some randomness. For example, generate a random Y coordinate as the sprite is created and/or leaves the screen and is wrapped around.

Run and test.

4) Respond to OnTouch Events

Many things could happen when the sprite is touched. It will be up to you to decide. For now let us just increment a hitCount and display the number of hits.

In GameView class, create a member field which references a hitCount variable.

private int hitCount;

Initialise hitCount to 0 in the resetGame() method.

Replace the text displayed on the screen, with an appropriate message to display the number of hits.

Add the following wasItTouched() method to the Sprite class. This checks to see if the touch event was in the boundaries of the Sprite image.

/* Checks if the Sprite was touched. */

public boolean wasItTouched(float ex, float ey){

boolean touched = false;

if ((x <= ex) && (ex < x + bmp_width) &&

(y <= ey) && (ey < y + bmp_height)) {

touched = true;

}

return touched;

}//End of wasItTouched

In the GameView class, amend the onTouchEvent() method to that below. This will renew the Sprite and increment the hitCount.

//To be used if we need to find where screen was touched

public boolean onTouchEvent(MotionEvent event) {

if (sprite.wasItTouched(event.getX(), event.getY())){

/* For now, just renew the Sprite */

sprite = new Sprite(this);

hitCount++;

}

return true;

}

5) CountDown Timer

We can create a countdown timer for the game after which the game could end.

Add the following member fields to the GameView class to be used by the countdown timer

/* For the countdown timer */

private long startTime ; //Timer to count down from

private final long interval = 1 * 1000; //1 sec interval

private CountDownTimer countDownTimer; //Reference to class

private boolean timerRunning = false;

private String displayTime; //To display time on the screen

Add the following private MyCountDownTimer class to the GameView class.

/* Countdown Timer – private class */

private class MyCountDownTimer extends CountDownTimer {

public MyCountDownTimer(long startTime, long interval) {

super(startTime, interval);

}

public void onFinish() {

displayTime = “Times Over!”;

timerRunning = false;

countDownTimer.cancel();

}

public void onTick(long millisUntilFinished) {

displayTime = ” “ + millisUntilFinished / 1000;

}

}//End of MyCountDownTimer

In the ResetGame() method of the GameView class create and initialise the CountdownTimer object

//Set timer

startTime = 10;//Start at 10s to count down

//Create new object – convert startTime to milliseconds

countDownTimer=new MyCountDownTimer(startTime*1000,interval);

countDownTimer.start();//Start it running

timerRunning = true;

Display an appropriate message on the screen showing time remaining.

Run and test.

6) End Game

In the gameView class, create a Boolean type member field to track if game is over.

private boolean gameOver;

In the ResetGame() method of the GameView class initialise this to false.

There will be many ways for the game to end – it will be up to you to decide. For now set gameOver to true when in the finish method of the countdown timer. You will need to adjust code in the doDraw() method to display appropriate text if gameOver is true. You may also need to amend the update method, so the game is only updated if the game is not over.

Display an appropriate message to inform the user that the game is over and that the user can return to the main menu by pressing the back key.

( the gameLoopThread will stopped as the surfaceDestroyed() method is automatically called)

7) Return Game Score

In the GameActivity class, complete the finish() method so that the number of hits(score) can be returned to the MainMenu class. For the code below to work, you will need to create a getHitCount() method in the GameView class to return the hitCount.

public void finish(){

Intent returnIntent = new Intent();

returnIntent.putExtra(“GAME_SCORE”,gameView.getHitCount());

setResult(RESULT_OK, returnIntent);

super.finish();

}

Check that the game score is displayed on by MainMenu class

Run and test.

Requirement 2: Extend The Game (15 marks)

Display Highest Score

The score displayed by the MainMenu should be the highest score of any game played whilst the app is running. This high score should be passed (via Bundle extras) from the MainMenu to the GameActivity and displayed on the screen as the ‘Score to Beat’ (or something equivalent). If the current game exceeds that high score then a new high score should be returned and displayed by the MainMenu.

You should refer the Unit on Menus and Intents

Amend Sprite Motion

Further change the motion of the Sprite. For example:

Introduce a change of direction as the Sprite bounces back off sides or bottom

Sprites appear in random positions on the screen

Sprites are initialised with random direction.

3) Work with Sprite Collections

Instead of just one sprite we could add several sprites and manage the collection of sprites with an ArrayList. Documentation below.

http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html

In the GameView class, create a reference to an ArrayList of sprites: for example

private ArrayList<Sprite> spritesArrayList;

Initialise this object in the GameView constructor.

spritesArrayList= new ArrayList<Sprite>();

Now amend you code to work with a collection of sprites. Start by adding a creating a member field in the GameView class to specify the number of Sprites.

Use a ‘for’ loop to add new Sprites to the collection using the add method (of the spritesArrayList).

You will also need ‘for’ loops in the update() and doDraw() methods to iterate over the spritesArrayList using the get method to retrieve each sprite before updating or drawing it.

Similarly to remove an individual sprite when hit, you would use iterate over the collection use the get method to retrieve the sprite from the collection at a particular index and test if it had been hit.

Sprite Animation

Animation can be achieved by using an image comprised of frames as below:

Each frame needs to be isolated and the frame advanced at the speed of the game canvas is drawn.

Find/create an animated image, similar to that above. In this case the top row was ‘flipped’ and joined to the top row to produce 2 rows representing the bird flying in different directions (could also do up/down). You will need to use graphics packages like Gimp or Paint.

Make the sprite have a transparent background for greater effect (search on how to do this in Gimp).

In the Sprite class create to constants to represent the number of rows and columns (2 by 14 in the above case), i.e.

private static final int ANIMATION_ROWS = 2;

private static final int ANIMATION_COLUMNS = 14;

In the member fields of the Sprite class, create and initialise a variable to track the frame count. i.e. private int currentFrame = 0;

In the constructor method of the Sprite class, change the sprite image to the animation image (birdanimation in the code below) and divide the image up into rows and columns.

Spritebmp = BitmapFactory.decodeResource(gameView.getResources(),

R.drawable.birdanimation);

this.bmp_width = spritebmp.getWidth()/ANIMATION_COLUMNS;

this.bmp_height= spritebmp.getHeight()/ANIMATION_ROWS;

We can animate the image by creating a rectangle object around the part of the image we wish to display, then advancing the image with each draw() of the canvas; using the code below:

public void draw(Canvas canvas) {

int srcX = currentFrame * bmp_width;//frame – x direction

int srcY; //row

if (xSpeed > 0){//Sprite going right; row = 0

srcY = 0 * bmp_height;

}

else { //Going left; row = 1

srcY = 1 * bmp_height;

}

//Create Rect around the source image to be drawn

Rect src = new Rect(srcX, srcY, srcX+bmp_width, srcY + bmp_height);

//Rect for destination image

Rect dst = new Rect(x, y, x + bmp_width, y + bmp_height);

//draw the image frame

canvas.drawBitmap(spritebmp, src, dst, null);

}

An explanation of how this works follows:

Consider the bird flying to the left (2nd row) and the currentFrame is 3

bmp_width

Source (Src) to Destination (dst)

The line below would create a rectangle (Rect) around the image indicated

Rect src = new Rect(srcX,srcY,srcX+bmp_width,srcY+bmp_height);

(in this case, srcX = 3 * bmp_width and srcY = 1 * bmp_height)

The line below would define the destination rectangle (Rect) of the bitmap to be drawn and would automatically scale and translate the above rectangle/image to fill the destination rectangle

Rect dst = new Rect(x, y, x + bmp_width, y + bmp_height);

4) Saving Data

In the MainMenu class, find a way to save the highest score. This should be retrieved and displayed when the game if restarted (from the device being shut down)

Add a button next to the highest score that will clear the score and the saved data.

Requirement 3: Advanced Features (30 marks)

The final programming requirement is to add some advanced features to your game. You should start with the following two additional features, after that however you have a certain degree of freedom to expand the game in any way you wish. Some hints of typical features which may be desirable are also given. However you are free to be imaginative also!

The game should play background music.

From the main menu, set the difficulty level of the game (for example, by using the Options menu). The difficulty level should affect the number of sprites created and a property of the sprites (e.g. Sprite speed)

Other possible enhancements include –

Make sound when a sprite is hit, or cause the device to vibrate.

Add another type of sprite (e.g. weapon/treasure/bullets) – Check for collisions, create an event on collision (e.g. points scored or removal/renewal of sprite)

Save Instance data when change in orientation

Send score data and name via to HTTP to website.

Enhance the User Interface of the MainMenu e.g. colour, graphics, instructions

Any other mobile features to impress?

Tags: , , , , , , , , , , ,