Title: CS2
1CS2
- Module 38
- Category CS Concepts
- Topic Graphics 2
- Objectives
- Simple Animation
- Bouncing ball
- Hypnotic Squares
- Paint/Repaint
2CS 2
- Introduction to
- Object Oriented Programming
- Module 38
- CS Concepts
- Graphics 2
3Basic Animation
- With successive, rapid repaintings, a Java
component may appear to be animated. Other Java
packages support more complex media however, we
can create our own simple animations by timing
calls to repaint(). - Techniques include
- calling repaint() inside the paint() or
paintComponent() methods. This schedules a
prompt call to redraw the object. (Do NOT
recursively call paint again.) - creating a timer to call paint
- can be useful to spawn execution threads to
manage repainting (advanced topic not covered
here.)
4Basic Animation
Our algorithm for painting would include 1)
update the items being animated. (Stateful
changes.) 2) erase the entire drawing area.
(We might later refine this to only erase those
areas that need updating.) 3) draw the
updated items 4) repeat
5import java.awt. import java.awt.event. import
javax.swing. public class Bouncer extends
JPanel implements ActionListener Timer
timer int ballX 50, ballY 50 int dx
1, dy 1 int diameter 50 public
void fire() timer new Timer(5,
this) timer.setCoalesce(true) // combine
queued repaints timer.start() public
void actionPerformed(ActionEvent e)
updateMovements() checkCollisions() repaint
() public void updateMovements() bal
lY dy ballX dx
6public void checkCollisions() if (ballX
diameter gt getSize().width ballX lt 0)
dx-1 if (ballY diameter gt getSize().height
ballY lt 0) dy -1 public void
paint(Graphics g) g.setColor(Color.darkGray)
g.fillRect(0,0, getSize().width,
getSize().height) g.setColor(Color.red)
g.fillOval(ballX, ballY, diameter,
diameter)
To improve performance, investigate clipping
areas java.awt.Graphics.setClip(Rectangle)
7public void pause() timer.stop() public
void resume() timer.restart() public
static void main(String args) JFrame frame
new JFrame("Bounce Test") frame.setSize(400,400)
final Bouncer bounce new Bouncer()
frame.addWindowListener (new WindowAdapter()
public void windowClosing(WindowEvent e)
System.exit(0) public void
windowDeiconified(WindowEvent e)
bounce.resume() public void
windowIconified(WindowEvent e)
bounce.pause() ) frame.getContentPane().
setLayout(new BorderLayout())
frame.getContentPane().add(bounce)
frame.show() bounce.fire() // Bouncer
8The timer allows us to note the passage of time,
and periodically update our objects. We might
also allow for other user driven events, perhaps
to create an interactive real time program.
Beyond simple 2D "pong games," however, we will
need to identify techniques for efficiently
rendering graphics . . .
9Questions?
10Hypnotic Squares Example
import java.awt. import javax.swing. import
java.awt.event. public class Squares extends
JPanel implements ActionListener double p
0.8 double q 0.2 int cellSize
Timer t int maxSquares 15 int
globalCount int delta-1 public Squares
() globalCount maxSquares t
new Timer(50, this) t.start()
public void actionPerformed(ActionEvent e)
globalCountdelta if (globalCount lt
2 globalCount gt maxSquares)
delta-1 repaint()
11private void swapOffsets() double t p
p q q t public void
paintComponent(Graphics g)
g.setColor(Color.white) g.fillRect(0,0,getSiz
e().width, getSize().height)
g.setColor(Color.blue) cellSize Math.min
(getSize().width, getSize().height)/8 for
(int i0 ilt8 i) for (int k0 klt8
k) drawBoxes (g,
icellSize, kcellSize,
icellSizecellSize, kcellSize,
icellSizecellSize, kcellSizecellSize,
icellSize, kcellSizecellSize,
globalCount) swapOffsets()
swapOffsets() public int
iX(double x) return (int)Math.round(x) public
int iY(double y) return (int)Math.round(y)
12public void drawBoxes(Graphics g,
double ax, double ay,
double bx, double by,
double cx, double cy,
double dx, double dy, int count)
if (count!0) Polygon poly new
Polygon() poly.addPoint(iX(ax),
iY(ay)) poly.addPoint(iX(bx),
iX(by)) poly.addPoint(iX(cx),
iX(cy)) poly.addPoint(iX(dx),
iX(dy)) poly.addPoint(iX(ax),
iY(ay)) g.drawPolygon(poly)
drawBoxes(g,
paxqbx, payqby,
pbxqcx, pbyqcy,
pcxqdx, pcyqdy,
pdxqax, pdyqay,
--count)
13public static void main(String args)
JFrame f new JFrame() f.addWindowListener(n
ew WindowAdapter() public void
windowClosing(WindowEvent e)
System.exit(0) ) int w
600, h 600 f.setSize(w,h)
f.getContentPane() .setLayout
(new BorderLayout()) f.getContentPane()
.add(new Squares()) Dimension d
Toolkit .getDefaultToolkit()
.getScreenSize() f.setLocation (
(d.width -w)/2, (d.height-h)/2)
f.show() // Squares
14Java Graphics -- paint(Graphics g)
15Java Graphics paint(Graphics g)
- The repaint method
- Java provides programmer support via the
repaint() method to handle this for you. - The repaint() method accomplishes three things
- 1. It locates the information needed by
paint() (so you dont have to). - 2. It calls update(Graphics g), which writes
over the old drawing in background color
(thus erasing it). - 3. It then calls paint(Graphics g) to do the
drawing.
16Java Graphics paint(Graphics g)
- Thus, you may often have reason to override
paint(Graphics g) or paintComponent(Graphics g).
But how does this method get called? - But, the best way to see to it that
paint(Graphics g) is called is not by calling it
directly. Instead, call repaint(). - This saves you much needless grief, and triggers
a bit of Java "magic" whereby the language
itself sees to it that - needed info is obtained for paint(Graphics g)
- the old item is erased (via repaint( )s call to
update(Graphics g)) - paint(Graphics g) itself is then called by
repaint().
17Java Graphics paint(Graphics g)
18Dealing with Flicker
- A call to repaint( ) will deliver as promised,
but will not necessarily do so immediately.
(In Java, Graphics have their own thread.) - Furthermore, total processing load may slow
things to the point where the user sees video
flicker. - Culprit by default, Java erases the component
to be painted first -- "white washes" in the
update() method, and then paints. This can
cause flicker. - Solution to minimize flicker we can override
update( ) and to have it make a direct call
to paint( ). public void
update(Graphics g)
paint(g) // update - Another means double buffering.
- Done automatically by Swing
- Can be done in AWT but you have to do it!
19Questions?
20(No Transcript)