chapter 7 – collision detection: asteroids. the asteroids game

87
Chapter 7 – Collision Detection: Asteroids

Upload: catherine-powers

Post on 16-Jan-2016

251 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Chapter 7 – Collision Detection:

Asteroids

Page 2: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Asteroids Game

Page 3: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

How Are Bullets Fired?

We handle a “space” input and call the fire()

method.

Page 4: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

How Are Asteroids Created?

We call the addAsteroids() method in

the Space constructor

Page 5: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

What does an Explosion do?

Placing an Explosion object creates the

Explosion Visual and makes an Explosion

Sound.

Page 6: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Placing a ProtonWave

object has no effect except a

ProtonWave visual.

What does a Proton Wave do?

Page 7: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

No effect except a ProtonWave

visual.

What does the Counter do?

Apparently nothing

Page 8: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

What is currently NOT coded?When experimenting with the current scenario, you will notice that some fundamental functionality is missing.

The rocket does not move. It cannot be turned, nor can it be moved forward.

Nothing happens when an asteroid collides with the rocket. It flies straight through it, instead of damaging the rocket.

As a result of this, you cannot lose. The game never ends, and a final score is never displayed.

The ScoreBoard, Explosion, and ProtonWave classes, which we can see in the class diagram, do not seem to feature in the scenario.

Page 9: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

What should be coded?

Controls for the Rocket Collision: Asteroid vs. Rocket Explosion Logic ScoreBoard/Counter Logic ProtonWave Logic

Page 10: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

We want to make the rocket turn left or right using the left and right arrow keys.

Page 11: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Handling Key Presses

/* * Check whether there are any key pressed and react to them. */private void checkKeys() { if (Greenfoot.isKeyDown("space")) { fire(); }}

The method checkKeys

handles keyboard input

Page 12: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Actor Class Methods

Page 13: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

Left: Negative Degrees

Right: Positive Degrees

if (Greenfoot.isKeyDown("left")) setRotation(getRotation() - 5);

if (Greenfoot.isKeyDown("right")) setRotation(getRotation() + 5);

Page 14: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

/* * Check whether there are any key pressed and react to them. */private void checkKeys() { if (Greenfoot.isKeyDown ("space")) { fire(); } if (Greenfoot.isKeyDown ("left")) setRotation (getRotation() - 5);}

If left arrow key is down rotate left 5

degrees

Page 15: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

Page 16: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

/* * Check whether there are any key pressed and react to them. */private void checkKeys() { if (Greenfoot.isKeyDown("space")) { fire(); } if (Greenfoot.isKeyDown ("left")) setRotation (getRotation() - 5);

if (Greenfoot.isKeyDown ("right")) setRotation (getRotation() + 5);}

If right arrow key is down rotate right 5

degrees

Page 17: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Turning the Rocket

Page 18: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

Our Rocket class is a subclass of the SmoothMover class. This means that it holds a movement vector that determines its movement and that it has a move () method that makes it move according to this vector

Page 19: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

The rocket does not move because we did

not specify a movement vector yet.

Page 20: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

/* * Initialize this rocket. */public Rocket(){ reloadDelayCount = 5; addForce ( new Vector (13, 0.3)); //initially slow drifting}

Add an initial movement to the

rocket constructor.

Page 21: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

/* * Do what a rocket's gotta do. (Which is: mostly * flying about, and turning, * accelerating and shooting when the right keys are pressed.) */public void act(){ move (); checkKeys(); reloadDelayCount++;}

Add the move () method

Page 22: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

The rocket drifts slowly toward the right of the

World

Page 23: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Ignite the Engines

Ignite Algorithm1) If “up” arrow key is pressed then

1.1) change image to show engine fire 1.2) add movement

2) If “up” arrow key is released then 2.1) change back to normal rocket image

Page 24: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Ignite the Engines

/* * Go with thrust on */private void ignite (boolean boosterOn){

}

Define a stub method for ignite

Page 25: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Ignite the Engines

/* * Go with thrust on */private void ignite (boolean boosterOn){ if (boosterOn) { setImage (rocketWithThrust); addForce (new Vector (getRotation(), 0.3)); } else { setImage (rocket); }}

A boolean parameter

Page 26: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Ignite the Engines

/* * Check whether there are any key pressed and react to them. */private void checkKeys() { if (Greenfoot.isKeyDown("space")) fire(); ignite (Greenfoot.isKeyDown ("up"));

if (Greenfoot.isKeyDown("left")) setRotation(getRotation() - 5);

if (Greenfoot.isKeyDown("right")) setRotation(getRotation() + 5}

Add a call to ignite

Page 27: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Flying Forward

Page 28: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

1) If we have collided with an asteroid then 1.1) remove the rocket from the world 1.2) place an explosion into the world 1.3) show final score (game over)

Colliding Algorithm

Page 29: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

/* * Check for a collision with an Asteroid */private void checkCollision(){

}

Define a stub method for checkCollision

Page 30: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

/* * Do what a rocket's gotta do. (Which is: mostly flying about, and turning, * accelerating and shooting when the right keys are pressed.) */public void act(){ move (); checkKeys(); checkCollision(); reloadDelayCount++;}

Make a call to checkCollision from

the Rocket Act method

Page 31: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Intersecting Objects

Bounding Box

Visible Image

Intersection

Page 32: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Intersecting Objects Methods

Bounding Boxes

Visible Image

List getIntersectingObjects (Class cls)

Actor getOneIntersectingObject (Class cls)

Intersection

Page 33: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

getOneIntersectingObject()

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class);

}

Even though we can specify what class we are looking for, the

method always returns an Actor object

Page 34: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

getOneIntersectingObject()

/* * Check for a collision with an Asteroid */private void checkCollision(){ Asteroid a = (Asteroid) getOneIntersectingObject (Asteroid.class);

}

However, we can re-interpret the returned Actor to a more specific

class via a process called “Casting”.

More on that later.

Page 35: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

getOneIntersectingObject()

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) {

}}

We have a collision if: a is not “null”, meaning if

the getOneIntersectingObject has returned something

Page 36: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) { World space = getWorld();

space.removeObject (this); space.addObject (new Explosion(), getX(), getY()); }}

Adding the Explosion and removing the Rocket has to be done via World-

methods.

Page 37: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) { World space = getWorld();

space.addObject (new Explosion(), getX(), getY()); space.removeObject (this); }}

The sequence of commands is very important when

removing objects!

Page 38: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids

Page 39: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Game Over

After a collision, we want to show a ScoreBoard object in

the middle of the Level

Page 40: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Game Over Method in the Space class

/* * This method is called when the game is over to display the final score. */public void gameOver() { // TODO: show the score board here. Currently missing.}

Page 41: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

ScoreBoard

/* * Create a score board with dummy result for testing. */public ScoreBoard(){ this(100);}

/* * Create a score board for the final result. */public ScoreBoard(int score){ makeImage("Game Over", "Score: ", score);}

The ScoreBoard class has two constructors, a Default Constructor and a second Constructor with parameters

Page 42: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Game Over

/* * This method is called when the game is over to display the final score. */public void gameOver() { addObject(new ScoreBoard(999), getWidth()/2, getHeight()/2);}

Making sure that the Game Over screen appears right in the middle of the screen.

Page 43: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Game Over

Page 44: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids II

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) { World space = getWorld();

space.addObject (new Explosion(), getX(), getY()); space.removeObject (this);

space.gameOver(); }}

Why does this code produce an error?

Page 45: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids II

/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) { World space = getWorld();

space.addObject (new Explosion(), getX(), getY()); space.removeObject (this);

space.gameOver(); }} The gameOver() method is

a method of the Space class. Our Compiler cannot find it in the World class. Thus, we cannot call it from objects of type World!

Page 46: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Colliding with Asteroids II/* * Check for a collision with an Asteroid */private void checkCollision(){ Actor a = getOneIntersectingObject (Asteroid.class); if (a != null) { Space space = (Space) getWorld();

space.addObject (new Explosion(), getX(), getY()); space.removeObject (this);

space.gameOver(); }}We can use Casting to specify that the object

returned by the getWorld() method is not only a World object, but actually an object of the more

specific Subclass Space.This does NOT change the actual type of the object,

it only changes the information available to our program.

Page 47: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars

The Asteroid Scenario does not use an image file for the background. Instead, the background image is generated directly in the Constructor.

Page 48: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars

The Background is Created by These Three Statements.

Page 49: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars

Code to Create the Background is

Commented Out

Page 50: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

No Background

Page 51: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The GreenfootImage Class

Draw Rectangle

Draw Oval

Fill Oval

Draw Line

Page 52: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Each point of a World object can be identified using a Cartesian coordinate system

The origin of the coordinate system (i.e. the point (0,0) ) is in the top-left corner

Point Coordinates in Greenfoot

Page 53: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Drawing A Line

drawLine(10, 20, 150, 45); ordrawLine(150, 45, 10, 20);

Page 54: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Drawing A Rectangle

drawRect (50, 20, 100, 40);

Page 55: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Drawing An Oval

drawOval (175, 20, 50, 80);

Page 56: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Filling an Oval

fillOval (175, 20, 50, 80);

Page 57: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Method to create stars

/* * Method to create stars. The integer number is how many. */private void createStars(int number) { GreenfootImage background = getBackground(); for (int i = 0; i < number; i++) {

}}

We want to draw a set amount of stars. This means that our new methods

requires a parameter.

Page 58: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Method to create stars

/* * Method to create stars. The integer number is how many. */private void createStars(int number) { GreenfootImage background = getBackground(); for (int i = 0; i < number; i++) { int x = Greenfoot.getRandomNumber( getWidth() ); int y = Greenfoot.getRandomNumber( getHeight() ); background.setColor (new Color(255, 255, 255)); background.fillOval(x, y, 2, 2); }}

Note the sequencing: We first specify the color, then what we want to draw in

said color.

Also note how we apply the operations to a specific image, using dot notation.

Page 59: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Calling the createStars methods in the Space

constructor

Painting Stars

Page 60: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars

Page 61: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars With Random Brightness

/* * Method to create stars. The integer number is how many. */private void createStars(int number) { GreenfootImage background = getBackground(); for (int i = 0; i < number; i++) { int x = Greenfoot.getRandomNumber( getWidth() ); int y = Greenfoot.getRandomNumber( getHeight() ); int color = Greenfoot.getRandomNumber (256); background.setColor(new Color(color, color, color)); background.fillOval(x, y, 2, 2); }}

Generate a random number for color in the range 0 to 255

Will be more or less bright, but always on

the white-black spectrum

Page 62: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Painting Stars With Random Brightness

Page 63: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Adding Fire Power: The Proton Wave

The idea is this: Our proton wave, once released, radiates outward from our rocket, damaging or destroying every asteroid in its path. Since it works in all directions simultaneously, it is a much more powerful weapon than our bullets.

Page 64: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

Does not MoveDoes not DisappearDoes not cause Damage

Page 65: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

public ProtonWave() { initializeImages();} public static void initializeImages() { if(images == null) { GreenfootImage baseImage = new GreenfootImage("wave.png"); images = new GreenfootImage[NUMBER_IMAGES]; int i = 0; while (i < NUMBER_IMAGES) { int size = (i+1) * ( baseImage.getWidth() / NUMBER_IMAGES ); images[i] = new GreenfootImage(baseImage); images[i].scale(size, size); i++; } }} public void act(){ }

Already implemented code:ConstructorinitializeImages ()act ()

Page 66: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

initializeImages() creates an Array of Growing Images

GreenfootImage [ ] images 0 1 2 3 4 29

Page 67: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Setting up The Proton Wave

/* * Index of the currently used image. */private int imageCount = 0;

/* * Create a new proton wave. */public ProtonWave() { initializeImages(); setImage(images [0]); Greenfoot.playSound ("proton.wav");}

Page 68: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

Page 69: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

/* * Act for the proton wave is: grow and check whether we hit anything. */public void act(){ grow();}

/* * Grow the wave. If we get to full size remove it. */private void grow (){}

Page 70: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

1) If our index has exceed the number of images then 1.1) Remove the wave from the world

2) Otherwise 2.1) set the next image in the array 2.2) increment the index

Grow Algorithm

Page 71: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

/* * Grow the wave. If we get to full size remove it. */private void grow (){ if (imageCount >= NUMBER_IMAGES) getWorld().removeObject (this); else setImage(images[imageCount++]);}

Page 72: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

The Proton Wave

Create a new ProtonWave by hand

Click “> Act” to watch the wave grow

sequentially

Page 73: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Create ProtonWave from Rocket

/* * Release a proton wave (if it is loaded). */private void startProtonWave(){ ProtonWave wave = new ProtonWave(); getWorld().addObject (wave, getX(), getY());}

Page 74: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

/* * Check whether there are any key pressed and react to them. */private void checkKeys() { if (Greenfoot.isKeyDown("space")) fire(); if (Greenfoot.isKeyDown("z")) startProtonWave(); ignite (Greenfoot.isKeyDown ("up"));

if (Greenfoot.isKeyDown("left")) setRotation(getRotation() - 5); if (Greenfoot.isKeyDown("right")) setRotation(getRotation() + 5);}

Create ProtonWave from Rocket

Page 75: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Test It

Page 76: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Test It

Proton Wave Can Be Released Too Fast by Holding Down the z Key

Page 77: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Managing Delays

private static final int gunReloadTime = 5; // Minimum delay in firing gun.private static final int protonReloadTime = 200; // Minimum delay in proton wave bursts. private int reloadDelayCount; // How long ago we fired gun the last time.private int protonDelayCount; // How long ago we fired proton wave the last time.

private GreenfootImage rocket = new GreenfootImage("rocket.png"); private GreenfootImage rocketWithThrust = new GreenfootImage("rocketWithThrust.png");

A Delay Count of 200 Seems Reasonable

Page 78: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Managing Delays

/* * Do what a rocket's gotta do. (Which is: mostly flying about, and turning, * accelerating and shooting when the right keys are pressed.) */public void act(){ move (); checkKeys(); checkCollision(); reloadDelayCount++; protonDelayCount++;}

Page 79: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Managing Delays

/* * Release a proton wave (if it is loaded). */private void startProtonWave(){ if (protonDelayCount >= protonReloadTime) { ProtonWave wave = new ProtonWave(); getWorld().addObject (wave, getX(), getY()); protonDelayCount = 0; }}

The method only produces a new Proton Wave if sufficient time

as passed since the last one

Page 80: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Test It

Page 81: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Interacting with Objects in Range

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

List getObjectsInRange (int radius, Class cls)

Page 82: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Check for ProtonWave Collisions

/* * Act for the proton wave is: grow and check whether we hit anything. */public void act(){ checkCollision(); grow();}

/* * Explode all intersecting asteroids. */private void checkCollision(){}

Page 83: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

ProtonWave Collisionsimport greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot)import java.util.List;………/* * Explode all intersecting asteroids. */private void checkCollision(){ int range = getImage().getWidth() / 2; List<Asteroid> asteroids = getObjectsInRange (range, Asteroid.class); for (Asteroid a : asteroids) { }}

Page 84: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Asteroid Hit Method

/* * Hit this asteroid dealing the given amount of damage. */public void hit(int damage) { stability = stability - damage; if(stability <= 0) breakUp (); }

Every Asteroid has “hit points” in the form of an integer variable called stability. An

Asteroid breaks up if the variable reaches 0 or less.

Parameter to determine the

amount of damage

Page 85: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

ProtonWave Collissions

/* * Explode all intersecting asteroids. */private void checkCollision(){ int range = getImage().getWidth() / 2; List<Asteroid> asteroids = getObjectsInRange(range, Asteroid.class); for (Asteroid a : asteroids) { a.hit (DAMAGE); }}

/* The damage this wave will deal */ private static final int DAMAGE = 30;………

Page 86: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Extra: Hit Invincibility

The ProtonWave currently completely destroys all

Asteroids it comes in contact with. Meaning it

destroys both the Asteroids it hits and the

Asteroids that are then spawned.

Depending on how we want our game to

function, this might not be desirable.

How can we make sure that the ProtonWave does

not destroy the new Asteroids?

Page 87: Chapter 7 – Collision Detection: Asteroids. The Asteroids Game

Summary of Programming Techniques