Multimedia in Java

eyelashesnectarineSoftware and s/w Development

Nov 3, 2013 (4 years and 1 month ago)

95 views

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)