CS 1121: INTRODUCTION TO COMPUTER SCIENCE I

Lab 5 Preparation

The focus of this prep is to give you more experience writing interacting objects, and to include a click listener in the animation.

The program we will write produces an animation with a space ship and an asteroid. The ship can shoot rockets at the asteroid, and if a rocket hits the asteroid, the asteroid disappears.

Click here to try it out. You can move the blue ship with the arrow keys, and you can shoot a rocket at the asteroid by clicking somewhere in the window - the rocket will start at the middle of the ship and move toward the position of the click. You can have as many rockets as you like. Try to hit the asteroid!

To get started, create a new project in Eclipse called "prep5". Then create a new classes called "Prep5", "Ship", "Asteroid" and "Rocket". Make sure they all have the right imports and they all extend Animated.

Before starting it is a good idea to think about what each object is going to do. Clearly the Ship class will draw the ship, the Asteroid class will draw the asteroid, and the Rocket class will draw the rockets. It makes sense that the Prep5 class will create the Ship and the Rocket objects, since they are needed as soon as the animation starts up.

But where should the Rocket objects be created? Again, it seems to make sense that they be created by the Ship. This, of course, implies that the best place to react to clicks is in the Ship class - when a click happens the Ship will find out about it and create a Rocket object (and include it in the animation).

When the animation starts up we will have a Ship and an Asteroid object, and when a click happens we will get a Rocket object. Now we have to decide where the code that detects when the rocket hits the asteroid is going to be. Wherever it is, the code will have to know the position and radius of both the rocket and the asteroid. If we put that code in the Asteroid class, then the Asteroid class would have to know about every Rocket object, and we haven't covered how to do that in Java yet. Instead we will put the code to detect a hit in the Rocket class, and this means that the rocket will have be able to get the position of the asteroid, which means that the Rocket class will have to contain a reference to the Asteroid object. But then since the Ship class creates the Rocket objects, it will have to give the Rocket objects a reference to the Asteroid object, which implies that the Ship object will also have to contain a reference to the Asteroid object.

So to summarize:

So let's get started with the Prep5 class.

Now let's get a start on the asteroid class. All we'll do right now is get it to move, which is nothing you haven't done already:

Next comes the Ship class. First let's just get it to move according to the arrow keys and to save a reference to the Asteroid object (via the constructor):

You should run this and make sure that the asteroid and ship move correctly.

Now lets modify the Ship class to react to clicks. To do this, we need to make the Ship class "implement ClickListener" and have a "public void click(int x, int y)" method:

We also need to modify the Prep5 class to tell the animator which object is the click listener. All that is needed is to add the line:

to the end of the startup method.

Now we need to add code to the click method to create a Rocket and give it a reference to the Asteroid object. Creating the object is easy, but we also need to tell it where to start and in what direction to move (i.e., toward the click). This takes a little trig, show I'll just show you the code and you can figure it out.

Note that the code uses variables "savex" and "savey". These are the coordinates of the center of the ship, and need to be saved by the draw method in new instance variables. I'll leave it as an exercise to put these in.

Here's the beginnings of the Rocket class:

Notice that we are keeping track of the position of the rocket using double's instead of int's. This is because the distance being moved on each tick could be less than 1 but not 0. For example, suppose it moves 0.5 in the x-direction on each tick. Then over several ticks the x-coordinate should change from 0.0 to 0.5 to 1.0 to 1.5 to 2.0, etc. If we used an int to keep track of the x-coordinate, then if we add 0.5 to it each time it will never change since we always have to truncate back to an int and the 0.5 goes away.

Now try this out and see if it works. You should now be able to click on the screen and have a rocket appear and start moving toward the click.

Finally we have to make the asteroid disappear when a rocket hits it. For this to happen the Rocket class needs to have code that checks for the hit, first getting the position and radius of the asteroid. Here's the new draw method in the Rocket class:

And the following methods are added to the Asteroid class:

All that needs to be done now is to add an instance variable to the Asteroid class:

and modify the draw method in the Asteroid class to only draw the asteroid if "alive" is true:

This should be all that is needed. Try it out and see if it works. If not, see if you can fix it. If you can't, get some help.

For practice before your lab, try make the changes necessary to:

That's it for this preparation. Good luck in your next lab.

DON'T FORGET:
  1. EXIT ECLIPSE
  2. LOG OUT