Animation
•
To animate our programs, that is, to have real time
interactions where objects move on the screen, we want
to call repaint( ) every few milliseconds
–
how does our program know when a few milliseconds elapse?
–
there is a Timer class available
–
set it for 20 milliseconds and every 20 milliseconds,
the Timer generates an
ActionEvent
•
In Java, we can have our program listen for an
event and when the event arises, have it call a
method
–
in this case, the Timer generates
ActionEvents
which
will then cause a method called
actionPerformed
to
execute
–
so we have to implement the
actionPerformed
method
actionPerformed
•
This method will look like this:
–
public void
actionPerformed
(
ActionEvent
e)
–
{…}
•
What
should our
actionPerformed
method
do?
–
we want to draw something on the Graphics panel and
move it every time the Timer sends out an Event
–
so
actionPerformed
will “move” the object (change its
location) and then call repaint( )
–
repaint calls
paintComponent
–
paintComponent
first erases whatever had been
previously drawn and then draws the object(s) anew,
having possibly been moved
Timer class
•
A Timer object is instantiated by:
–
Timer t = new Timer(duration, handler);
•
duration is the time (in milliseconds) that elapses between Timer
-
generated events, such as 20 or 50
•
handler is the object that handles the Timer
-
generated events
–
we will
use
this
just like we have for our addActionListener statements
–
The steps are to add
•
import java.awt.event.*;
•
“implements ActionListener” to our class header
•
instantiate the Timer as t = new Timer(10, this);
–
but use whatever value you want for the duration, 10 or 20 would be
adequate for most applications
•
start the timer by using t.start( );
–
if we need to stop the timer, we use t.stop( );
–
that’s about all there is to it!
Timer
Skeleton
import javax.swing.*;
import java.awt.event.*;
public class TimerSkeleton implements ActionListener
{
private Timer t;
// other instance data go here as needed
public TimerSkeleton( )
{
t = new Timer(10, this);
t.start( );
// other initialization operations go here as needed
}
// other methods go here as needed
public void actionPerformed(ActionEvent e)
{
// whatever you want to happen when the Timer pulses go here
}
}
What Should actionPerformed Do?
•
This depends on why you are using a Timer
–
to move an object in a Graphics panel (e.g., a ball)
•
alter the x and y coordinates and call repaint( )
–
for a Game:
•
calculate where game objects (say a spacecraft or a missile) have
moved and redraw them
–
this may require the user of an array of x and an array of y values to
store the various objects, or multiple variables such as myX, myY,
yourX, yourY, or both (the arrays might store the X and Y coordinates
of missiles launched from one to the other)
–
for Animation:
•
if our item being drawn is represented by an array of different figures
–
then just increment the array index and repaint( )
–
we will see an example of a StickFigure, but this could also be done by
having a series of jpg or gif files all pre
-
loaded into an array of Images
Moving an Image to Create Motion
•
Imagine that your class draws on a JPanel an ImageIcon
(say of a spaceship)
–
currently, the spaceship is located at coordinates x, y
–
the following actionPerformed method will randomly move
the spaceship on the screen
–
x and y should be class variables so that you could do
g.drawImage(image, x, y, this); in your paintComponent
method
public void actionPerformed(ActionEvent e)
{
int dx = generator.nextInt(2); // generate a # from
-
1 to +1
int dy = generator.nextInt(2); // generate a # from
-
1 to +1
x += dx;
// move the piece in a random x direction
y += dy;
// move the piece in a random y direction
repaint( );
// assume repaint does drawImage at x, y
}
Full Example Code
public TimerExample( )
{
t = new Timer(10, this);
t.start( );
x = 150; y = 150; repaint( );
}
public void actionPerformed(ActionEvent ev)
{
int distanceX = generator.nextInt(2));
int distanceY = generator.nextInt(2));
x += distanceX;
y += distanceY;
repaint( );
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(x, y, 5, 5);
}
At each Timer Event, randomly
move the object (a red circle)
up/down/left/right by 0 or 1 unit
Note: we could make it more
realistic by generating a random
int from 1
-
9 and move it in
one of 8 directions or leave it
stationary
(1 = upper left, or subtract 1 from
x and y, 2 = straight up, etc)
Better Motion
•
The random motion from the previous example
would make the object on the screen look like a bee,
buzzing around
•
What if we wanted a more purposeful movement?
For instance in a straight line?
•
Lets add 2 more variables,
dx
and
dy
–
(delta x means “change in x”, delta y means “change in
y”, we use d because we don’t have the Greek letter
delta)
•
For
actionPerformed
, just do x=
x+dx
; y=
y+dy
;
–
If
dx
=1 and
dy
=2, then our object will move in a
straight line to the right 1 pixel and down 2 pixels at
each movement, or a diagonal downward line
–
If
dx
=0 and
dy
=
-
1, then the object moves straight up
–
We should also make sure that x & y do not “go off”
the screen (if x < 10 make x = 10 and
dx
= 0 to stop the
motion there, or let x = X_SIZE to “wrap around”)
Moving Multiple Items
•
How would a game like Asteroids work?
–
we need to keep track of the <x, y> coordinates of multiple
values, just like we did with our paint program
–
so we create an array of x, y, dx and dy int values
•
private int[ ] x, y, dx, dy;
// dx, dy
–
velocity of x, y
•
private int num;
// number of items in the arrays
–
actionPerformed now manipulates all items in the array and
paintComponent draws them all
public void actionPerformed(ActionEvent e)
{
for(int i=0;i<num;i++) {
x[i]+=dx[i];
y[i]+=dy[i];
}
}
If x[i] or y[i] reaches a
boundary (0 or max X/Y)
then change dx or dy to
be the opposite (multiply
by
-
1)
Enter the password to open this PDF file:
File name:
-
File size:
-
Title:
-
Author:
-
Subject:
-
Keywords:
-
Creation Date:
-
Modification Date:
-
Creator:
-
PDF Producer:
-
PDF Version:
-
Page Count:
-
Preparing document for printing…
0%
Comments 0
Log in to post a comment