chapter 7 collision detection asteroids n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Chapter 7 - Collision Detection: Asteroids PowerPoint Presentation
Download Presentation
Chapter 7 - Collision Detection: Asteroids

Loading in 2 Seconds...

play fullscreen
1 / 113

Chapter 7 - Collision Detection: Asteroids - PowerPoint PPT Presentation


  • 273 Views
  • Uploaded on

Chapter 7 - Collision Detection: Asteroids. Bruce Chittenden. 7.1 Investigation: What is There?. 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.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Chapter 7 - Collision Detection: Asteroids' - davis-bishop


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
7 1 investigation what is there
7.1 Investigation: What is There?
  • 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.
exercise 7 2
Exercise 7.2

Controls for the Rocket

Collision Logic

Explosion Logic

ScoreBoard Logic

Implement ProtonWave

exercise 7 3
Exercise 7.3

Spacebar is used to fire a bullet

exercise 7 4
Exercise 7.4

Creates the Explosion Visual and makes and Explosion Sound

exercise 7 5
Exercise 7.5

The visual is Present, But It Does Not Do Anything

7 2 painting stars
7.2 Painting Stars

The Asteroid Scenario does not use an image file for the background. A world that does not have a background image assigned will, by default, get an automatically created background image that is filled with plain white.

exercise 7 6
Exercise 7.6

The Background is Created by These Three Statements

exercise 7 7
Exercise 7.7

Code to Create the Background is Commented Out

exercise 7 8
Exercise 7.8

Draw Oval

Draw Rectangle

Fill Oval

exercise 7 91
Exercise 7.9

13 Defined Constant Fields

exercise 7 10
Exercise 7.10

/*

* Method to create stars. The integer number is how many.

*/

private void createStars(int number)

{

// Need to add code here

}

exercise 7 11
Exercise 7.11

/*

* Method to create stars. The integer number is how many.

*/

exercise 7 111
Exercise 7.11

Create 300 Stars

exercise 7 13
Exercise 7.13

Clean Compile

exercise 7 14
Exercise 7.14

/**

* Add a given number of asteroids to our world. Asteroids are only added into

* the left half of the world.

*/

private void addAsteroids(int count)

{

for(int i = 0; i < count; i++)

{

int x = Greenfoot.getRandomNumber(getWidth()/2);

int y = Greenfoot.getRandomNumber(getHeight()/2);

addObject(new Asteroid(), x, y);

}

}

The addAsteroids creates a count number of asteroids and adds them to the World

exercise 7 15
Exercise 7.15

Initialization

Loop-Condition

Increment

for (int i = 0; i < count; i++)

{

}

exercise 7 16
Exercise 7.16

/*

* Add a given number of asteroids to our world. Asteroids are only added into

* the left half of the world.

*/

private void addAsteroids(int count)

{

int I = o;

while ( i < count)

{

int x = Greenfoot.getRandomNumber(getWidth()/2);

int y = Greenfoot.getRandomNumber(getHeight()/2);

addObject(new Asteroid(), x, y);

i++;

}

}

exercise 7 17
Exercise 7.17

/*

* Add a given number of asteroids to our world. Asteroids are only added into

* the left half of the world.

*/

private void addAsteroids(int count)

{

for ( int i = 0; i < count; i++)

{

int x = Greenfoot.getRandomNumber(getWidth()/2);

int y = Greenfoot.getRandomNumber(getHeight()/2);

addObject(new Asteroid(), x, y);

}

}

exercise 7 18
Exercise 7.18

/*

* 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);

}

}

Generate a random number for x and y and place a star at that location

exercise 7 19
Exercise 7.19

/*

* 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

7 3 turning
7.3 Turning

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

exercise 7 20
Exercise 7.20

/*

* 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

exercise 7 211
Exercise 7.21

if (Greenfoot.isKeyDown("left"))

setRotation(getRotation() - 5);

if (Greenfoot.isKeyDown("right"))

setRotation(getRotation() + 5);

Left Negative Degrees

Right Positive Degrees

exercise 7 212
Exercise 7.21

/*

* 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

exercise 7 22
Exercise 7.22

/*

* 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

7 4 flying forward
7.4 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

exercise 7 23
Exercise 7.23

/*

* 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

exercise 7 231
Exercise 7.23

The rocket does not move because our move vector has not been initialized and contains zero

exercise 7 24
Exercise 7.24

/*

* Initialize this rocket.

*/

public Rocket()

{

reloadDelayCount = 5;

addForce ( new Vector (13, 0.3)); //initially slow drifting

}

Add an initial movement to the rocket constructor.

exercise 7 241
Exercise 7.24

The rocket drifts slowly toward the right of the World

exercise 7 25
Exercise 7.25

/*

* 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

exercise 7 26
Exercise 7.26

Define a stub method for ignite

/*

* Go with thrust on

*/

private void ignite (boolean boosterOn)

{

}

exercise 7 27
Exercise 7.27

Pseudo Code

when “up” arrow key is pressed

change image to show engine fire;

add movement;

when “up” arrow key is released

change back to normal image;

exercise 7 271
Exercise 7.27

The ignite method complete

/*

* Go with thrust on

*/

private void ignite (boolean boosterOn)

{

if (boosterOn)

{

setImage (rocketWithThrust);

addForce (new Vector (getRotation(), 0.3));

}

else

{

setImage (rocket);

}

}

7 5 colliding with asteroids
7.5 Colliding with Asteroids

Pseudo Code

If (we have collided with an asteroid)

{

remove the rocket from the world;

place an explosion into the world;

show final score (game over);

}

exercise 7 28
Exercise 7.28

Define a stub method for checkCollision

/*

* Check for a collision with an Asteroid

*/

private void checkCollision()

{

}

exercise 7 29
Exercise 7.29

/*

* 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

intersecting objects
Intersecting Objects

List getIntersectingObjects (Class cls)

Actor getOneIntersectingObject (Class cls)

Bounding Box

Visible Image

exercise 7 30
Exercise 7.30

/*

* Check for a collision with an Asteroid

*/

private void checkCollision()

{

Actor a = getOneIntersectingObject (Asteroid.class);

if (a != null)

{

}

}

Check for intersecting with an Asteroid

exercise 7 31
Exercise 7.31

Add the code to remove the Rocket from the World and display an Explosion

/*

* 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();

}

}

exercise 7 32
Exercise 7.32

The problem with this code is that we removed the Object and then attempted to use it’s coordinates

/*

* Check for a collision with an Asteroid

*/

private void checkCollision()

{

Actor a = getOneIntersectingObject (Asteroid.class);

if (a != null)

{

World world = getWorld();

world.removeObject (this);

world.addObject (new Explosion(), getX(), getY());

}

}

exercise 7 33
Exercise 7.33

This is a very advanced exercise. A more sophisticated way to show an explosion is introduced in the Greenfoot tutorial videos.

Making Explosions, Part I(length: ~5 min, 11.6 MB)Making Explosions, Part II (length: ~18.5 min, 57.9 MB)Making Explosions, Part III (length: ~15 min, 52.2 MB)

7 6 casting
7.6 Casting

In computer science, type conversion, typecasting, and coercion refers to different ways of, implicitly or explicitly, changing an entity of one data type into another. This is done to take advantage of certain features of type hierarchies or type representations. One example would be small integers, which can be stored in a compact format and converted to a larger representation when used in arithmetic computations. In object-oriented programming, type conversion allows programs to treat objects of one type as one of their ancestor types to simplify interacting with them.

exercise 7 34
Exercise 7.34

Right Click on ScoreBoard then click on new ScoreBoard and drag it into the World

exercise 7 35
Exercise 7.35

/*

* 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 the actual Constructor

exercise 7 36
Exercise 7.36

/*

* Make the score board image.

*/

private void makeImage(String title, String prefix, int score)

{

GreenfootImage image = new GreenfootImage(WIDTH, HEIGHT);

image.setColor(new Color(255,255,255, 128));

image.fillRect(0, 0, WIDTH, HEIGHT);

image.setColor(new Color(255, 0, 0, 128));

image.fillRect(5, 5, WIDTH-10, HEIGHT-10);

Font font = image.getFont();

font = font.deriveFont(ITALIC, FONT_SIZE);

image.setFont(font);

image.setColor(Color.BLUE);

image.drawString(title, 60, 100);

image.drawString(prefix + score, 60, 200);

setImage(image);

}

exercise 7 361
Exercise 7.36

The information about Fonts is in java.awt.Font

import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot)

import java.awt.Color;

import java.awt.Font;

import java.util.Calendar;

public class ScoreBoard extends Actor

{

public static final float FONT_SIZE = 48.0f;

public static final int ITALIC = 2;

public static final int WIDTH = 400;

public static final int HEIGHT = 300;

exercise 7 37
Exercise 7.37

gameOver Method is a stub

exercise 7 38
Exercise 7.38

/*

* 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);

}

exercise 7 40
Exercise 7.40

To insure that the Score is placed in the of the World, center it at

½ width and ½ height

/*

* 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);

}

exercise 7 41
Exercise 7.41

The error comes from the fact that gameOver () is defined in class Space while getWorld returns a type of World. To solve this problem we tell the compiler explicitly that this world we are getting is actually of type Space.

Space space = (space) getWorld();

code 7 1
Code 7.1

/*

* Check for a collision with an Asteroid

*/

private void checkCollision()

{

Actor a = getOneIntersectingObject (Asteroid.class);

if (a != null)

{

World world = getWorld();

world.addObject (new Explosion(), getX(), getY());

world.removeObject (this);

world.gameOver();

}

}

exercise 7 42
Exercise 7.42

/*

* 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();

}

}

Cast (Space)

exercise 7 43
Exercise 7.43

inconvertible types

7 7 adding fire power the proton wave
7.7 Adding Fire Power: The Proton Wave

The idea is this: Our proton wave, once released, radiates outward from our rocket ship, 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.

exercise 7 44
Exercise 7.44

Does not Move

Does not Disappear

Does not cause Damage

exercise 7 45
Exercise 7.45

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()

{

}

The Constructor and Two Methods

ProtonWave ()

initializeImages ()

act ()

exercise 7 46
Exercise 7.46

/*

* Create a new proton wave.

*/

public ProtonWave()

{

}

/*

* Create the images for expanding the wave.

*/

public static void initializeImages()

{

}

/*

* Act for the proton wave is: grow and check whether we hit anything.

*/

public void act()

{

}

exercise 7 47
Exercise 7.47

/*

* Create the images for expanding the wave.

*/

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++;

}

}

}

exercise 7 471
Exercise 7.47

Pseudo Code

If we have not created the images do so now

get the base Image from the file wave.png

create an array of NUMBER_IMAGES (30) images

while there are still images to initialize

calculate the size of this image to be the width of the image divided by the

number of images multiplied by the index of this image

set the next element in the array of images to the base image scaled to new size

7 8 growing the wave
7.8 Growing the Wave

GreenfootImage [ ]

0 1 2 3 4 29

code 7 2
Code 7.2

/*

* Create the images for expanding the wave.

*/

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++;

}

}

}

exercise 7 48
Exercise 7.48

/*

* Create the images for expanding the wave.

*/

public static void initializeImages()

{

if (images == null)

{

GreenfootImage baseImage = new GreenfootImage("wave.png");

images = new GreenfootImage[NUMBER_IMAGES];

for (int i = 0; i < NUMBER_IMAGES; i++)

{

int size = (i+1) * ( baseImage.getWidth() / NUMBER_IMAGES );

images[i] = new GreenfootImage(baseImage);

images[i].scale(size, size);

}

}

}

for Loop

exercise 7 49
Exercise 7.49

/*

* Create a new proton wave.

*/

public ProtonWave()

{

initializeImages();

setImage(images [0]);

}

exercise 7 50
Exercise 7.50

/*

* Current size of the wave.

*/

private int imageCount = 0;

exercise 7 51
Exercise 7.51

/*

* Grow the wave. If we get to full size remove it.

*/

private void grow ()

{

}

exercise 7 52
Exercise 7.52

/*

* 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 ()

{

}

exercise 7 53
Exercise 7.53

Pseudo Code

if (our index has exceed the number of images)

remove the wave from the world;

else

set the next image in the array and

increment the index;

exercise 7 531
Exercise 7.53

/*

* 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++]);

}

exercise 7 54
Exercise 7.54

Right Click on ProtonWave

Click on new ProtonWave()

Drag into the World

Click >Act to watch the wave grow

exercise 7 55
Exercise 7.55

/*

* Create a new proton wave.

*/

public ProtonWave()

{

initializeImages();

setImage(images [0]);

Greenfoot.playSound ("proton.wav");

}

Add Sound

exercise7 56
Exercise7.56

/*

* Release a proton wave (if it is loaded).

*/

private void startProtonWave()

{

}

Does Not Need Any Parameters and Does Not Return Anything

exercise 7 57
Exercise 7.57

/*

* Release a proton wave (if it is loaded).

*/

private void startProtonWave()

{

ProtonWave wave = new ProtonWave();

getWorld().addObject (wave, getX(), getY());

}

exercise 7 58
Exercise 7.58

/*

* 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);

}

exercise 7 59
Exercise 7.59

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

exercise 7 591
Exercise 7.59

private static final int gunReloadTime = 5; // The minimum delay between firing the gun.

private static final int protonReloadTime = 100; // The minimum delay between proton wave bursts.

private int reloadDelayCount; // How long ago we fired the gun the last time.

private int protonDelayCount; // How long ago we fired the proton wave the last time.

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

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

A Delay Count of 100 Seems More Reasonable Than 500

exercise 7 592
Exercise 7.59

/*

* 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++;

}

exercise 7 593
Exercise 7.59

/*

* 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;

}

}

7 9 interacting with objects in range
7.9 Interacting with Objects in Range

List getObjectsInRange (int radius, Class cls)

exercise 7 60
Exercise 7.60

/*

* 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()

{

}

exercise 7 61
Exercise 7.61

/*

* 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()

{

}

exercise 7 62
Exercise 7.62

/*

* Explode all intersecting asteroids.

*/

private void checkCollision()

{

int range = getImage().getWidth() / 2;

}

exercise 7 63
Exercise 7.63

import 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);

}

exercise 7 64
Exercise 7.64

Parameter is the Level of Damage

/*

* Hit this asteroid dealing the given amount of damage.

*/

public void hit(int damage)

{

stability = stability - damage;

if(stability <= 0)

breakUp ();

}

Before We Make Changes to the Method checkCollision (),

Lets Look at the Hit Method

exercise 7 65
Exercise 7.65

/* The damage this wave will deal */

private static final int DAMAGE = 30;

exercise 7 66
Exercise 7.66

/*

* 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);

}

7 10 further development
7.10 Further Development

The following are some suggestions for future work, in the form of exercises. Many of them are independent of each other – they do not need to be done in this particular order. Pick those first that interest you most, and come up with some extension of your own.

exercise 7 67
Exercise 7.67

/*

* Keep track of the score.

*/

public void countScore (int count)

{

scoreCounter.add(count);

}

exercise 7 671
Exercise 7.67

private void breakUp()

{

Space space = (Space) getWorld();

Greenfoot.playSound("Explosion.wav");

if(size <= 16) // Removing an Asteroid is worth 25 points

{

getWorld().removeObject(this);

space.countScore(25);

}

else // Splitting an Asteroid is worth 10 points

{

int r = getMovement().getDirection() + Greenfoot.getRandomNumber(45);

double l = getMovement().getLength();

Vector speed1 = new Vector(r + 60, l * 1.2);

Vector speed2 = new Vector(r - 60, l * 1.2);

Asteroid a1 = new Asteroid(size/2, speed1);

Asteroid a2 = new Asteroid(size/2, speed2);

getWorld().addObject(a1, getX(), getY());

getWorld().addObject(a2, getX(), getY());

a1.move();

a2.move();

getWorld().removeObject(this);

space.countScore(10);

}

}

7 11 summary of programming techniques
7.11 Summary of Programming Techniques

Understanding lists and loops is initially quite difficult, but very important in programming, so you should carefully review these aspects of your code if you are not yet comfortable in using them. The more practice you get, the easier it becomes. After using them for a while, you will be surprised that you found them so difficult at first.