Prac 16 – Timers

advertisement
Practical Exercise 16 – Timers
This prac demonstrates how a Timer object can be used to create a simple animation or game
involving a ball moving around the screen.
C Standard
Copy the following code into a Java applet and run it. You should see a green ball bouncing
around inside a rectangle – but something is wrong!
Examine the code carefully and make the following changes:

fix the program so that the ball bounces off all the walls correctly

double the size of the bouncing ball

change the colour of the ball to blue

start the ball in the bottom right corner of the square

change the speed of the ball
import
import
import
import
java.awt.*;
java.applet.*;
java.util.Timer;
java.util.TimerTask;
public class Prac16_Timers_C extends Applet
{
Timer timer1;
int refreshRate = 25;
// in milliseconds
int[] rectangle =
{5,5,300,200};
// left, top, right, bottom
int[] position =
{10,10};
// ball position x,y
int[] velocity =
{1, 3};
// ball velocity x,y
int ballSize = 20;
public void init()
{
setSize(310,210);
timer1 = new Timer();
// the first number is initial delay, second number is refresh rate
timer1.schedule(new AnimationTask(), 0, refreshRate);
}
private class AnimationTask extends TimerTask
{
public void run()
// the code that you want to run repeatedly
{
ballBounce();
repaint();
}
}
public void paint(Graphics g)
{
g.setColor(Color.black);
g.drawRect(rectangle[0], rectangle[1], rectangle[2]-rectangle[0],
rectangle[3]-rectangle[1]);
g.setColor(Color.green);
g.fillOval(position[0], position[1], ballSize, ballSize);
}
public void ballBounce()
{
//move the ball according to its velocity
Claremont College 2015, adapted from Rosny College 2009
Page 1 of 8
position[0] += velocity[0];
position[1] += velocity[1];
//if the ball hits any side of the rectangle, change its direction
if(position[0]<=rectangle[0] || position[0]>=rectangle[2])
{
velocity[0]= -velocity[0];
}
if(position[1]<=rectangle[1] || position[1]>=rectangle[3])
{
velocity[1]= -velocity[1];
}
}
}
B Standard
The following example should do the same as the first example but the mouseListener and
mouseMotionListener methods have been added. Copy this code then follow the steps below to
add a swatter controlled by the mouse that can swat the bouncing ball.
import
import
import
import
import
java.awt.*;
java.applet.*;
java.util.Timer;
java.util.TimerTask;
java.awt.event.*;
public class Prac16_Timers_B extends Applet implements MouseListener,
MouseMotionListener
{
Timer timer1;
int refreshRate = 25;
// in milliseconds
int[] rectangle =
{5,5,300,200};
// left, top, right, bottom
int[] position =
{10,10};
// ball position x,y
int[] velocity =
{1, 3};
// ball velocity x,y
int ballSize = 20;
int paddleSize = 15;
int[] mouse={0,0};
boolean hit=false;
public void init()
{
setSize(310,210);
addMouseListener(this);
addMouseMotionListener(this);
timer1 = new Timer();
timer1.schedule(new AnimationTask(), 0, refreshRate);
}
private class AnimationTask extends TimerTask
{
public void run()
{
ballBounce();
repaint();
}
}
public void paint(Graphics g)
{
//Draw the rectangle/game frame
g.setColor(Color.black);
g.drawRect(rectangle[0], rectangle[1], rectangle[2]-rectangle[0],
rectangle[3]-rectangle[1]);
//Draw the bouncing ball
g.setColor(Color.green);
Claremont College 2015, adapted from Rosny College 2009
Page 2 of 8
g.fillOval(position[0], position[1], ballSize, ballSize);
//Draw the paddle
g.setColor(Color.red);
g.fillRect(mouse[0], mouse[1],
paddleSize, paddleSize);
}
public void ballBounce()
{
//move the ball according to its velocity
position[0] += velocity[0];
position[1] += velocity[1];
//If the ball hits any sides of the rectangle, change its direction
if(position[0]<=rectangle[0] || position[0]>=rectangle[2]-ballSize)
{
velocity[0]= -velocity[0];
}
if(position[1]<=rectangle[1] || position[1]>=rectangle[3]-ballSize)
{
velocity[1]= -velocity[1];
}
}
public boolean checkHit()
{
Boolean result = false;
//Write method body here
return result;
}
public void mouseDragged(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
}
Claremont College 2015, adapted from Rosny College 2009
Page 3 of 8
To make the swatter move, add the following code to the mouseMoved method:
mouse[0]=e.getX();
mouse[1]=e.getY();
repaint();
Add the following code to the mouseClicked method:
mouse[0]=e.getX();
mouse[1]=e.getY();
if (checkHit())
{
timer.cancel();
}
repaint();
Edit the checkHit method to set the variable result to true when the swatter has ‘hit’ the
bouncing ball.
This should now allow you to swat the ball (i.e. freeze it). Run the applet and check.
B+ Standard
How close do you have to be to swat it? How could this be adjusted?
The mouse has to be still when you click on it. Why? How would you fix this?
A Standard
Copy and paste the following object code into a new class called Ball in the same project folder.
public class Ball
{
int x, y, x_velocity, y_velocity, size;
public Ball(int x, int y, int x_velocity, int y_velocity, int size)
{
this.x=x;
this.y=y;
this.x_velocity = x_velocity;
this.x_velocity = x_velocity;
this.size=size;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
Claremont College 2015, adapted from Rosny College 2009
Page 4 of 8
this.y = y;
}
public int getX_velocity()
{
return x_velocity;
}
public void setX_velocity(int x_velocity)
{
this.x_velocity = x_velocity;
}
public int getY_velocity()
{
return y_velocity;
}
public void setY_velocity(int y_velocity)
{
this.y_velocity = y_velocity;
}
public int getSize()
{
return size;
}
public void setSize(int size)
{
this.size = size;
}
public void move()
{
//move the ball according to its velocity
x += x_velocity;
y += y_velocity;
}
public void x_reverse()
{
x_velocity = -x_velocity;
}
public void y_reverse()
{
y_velocity = -y_velocity;
}
}
Copy your code from Prac16_Timers_B and copy it into a new class called Prac16_Timers_A.
Edit this code to use the Ball object, rather than using the position and velocity variables.
Create a second timer and a second ball object – use these to enable two balls to bounce around
the frame and be independently stopped with the one swatter
Claremont College 2015, adapted from Rosny College 2009
Page 5 of 8
Extension Task 1
Create a version of pong.
You will need to incorporate your knowledge
of the keyboard listener to get this working.
1. Create an applet and draw the pong
board:

a rectangle

two ‘gutters’

a centre line
2. Make sure the left and right gutters are
stored as variables.
3. Incorporate your bouncing ball code, make sure it bounces off the gutters, not the
rectangle.
4. Draw two paddles – left and right.

Make sure their x- and y-values and their height are stored in variables.

You may choose to create a Paddle object OR code them into the main class – it is
your choice.
5. Incorporate the KeyListener.

Control the left paddles up movement with the ‘w’ key and down movement with the
‘s’ key.

Control the right paddle with the up and down arrow keys.
6. Make sure that the paddles do not go past the top or bottom edges of the rectangle.
7. Write code to allow the ball to bounce off the paddle, but stop if it hits the gutter.

Get collisions happening for the left
paddle first, before moving on to the
right paddle.

See diagram.

You need to test if the ball is between
the top of the paddle and the bottom of
the paddle, but you cannot test against
the Y co-ordinate of the ball, you must
test against the middle of the ball.

Eg.
if (ball_y + (ball_size/2) >= paddle_y)
// the ball hit below the top edge
// of the paddle
Claremont College 2015, adapted from Rosny College 2009
Page 6 of 8
8. Once the ball correctly stops when it hits either gutter, comment out the line that stops
the ball, and add in a line that incorporates scoring and re-spawns the ball from the
centre of the game.
9. If the ball hits the right gutter, the left player should win a point and the ball should
spawn in a way that will make it move upwards and to the left.
If the ball hits the left gutter, the right player should win a point and the ball should
spawn in a way that will make it move upwards and to the right.
10. Write code to display these scores on
the applet (see image).
11. If you want to add in an additional level
of difficulty, add code to increase the
ball speed with each hit of the paddle.
Claremont College 2015, adapted from Rosny College 2009
1
2
Page 7 of 8
Extension Task 2
To avoid a possible problem with flickering, you can use something called Double Buffering.
In the top of the class, paste the follow lines of code:
private Image dbImage;
//double buffering
private Graphics dbg; //double buffering
After the init() method, paste in the following method:
//Double Buffering Method
public void update (Graphics g)
{
if (dbImage == null)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics();
}
dbg.setColor (getBackground ());
dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
dbg.setColor (getForeground());
paint(dbg);
g.drawImage(dbImage, 0, 0, this);
}
Claremont College 2015, adapted from Rosny College 2009
Page 8 of 8
Download