Buffering graphics
In animation sequences in java it makes sense to buffer
graphics. This means to draw all objects on a seperate canvas before
displaying that canvas to the screen. This minimizes the flickering
you see in some programs.
The trick to this is to declare your screen as such:
// The object we will use to write with instead
of the standard screen graphics
BufferedImage offScreen;
init() statement
Now we register the bufferGraphics under our init() statement:
// next two line are for our buffer image
offScreen = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
Using your bufferGraphics
Now to use our bufferGraphics canvas, we simply use it as we used
our g graphics screen. Now it is accesible from everywhere.
Graphics oGraphics=offScreen.getGraphics();
oG.setColor(Color.white);
oG.fillRect(0,0,2000,2000);
Putting bufferGraphics on the screen
Under paint() or anywhere we have g the main graphics, we need
to tell our screen to use our bufferGraphics [or offscreen image].
To do so we use:
g.drawImage(offScreen,0,0,this);
Below is sample code of the entire buffer graphics operation.
/*
* Test class to practice mouse movement by drawing a circle where the cursor is.
*
* @author Jeff Borland
* @version 12.14
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
public class StarterCodeBuffering extends JApplet implements MouseListener, MouseMotionListener,ActionListener,KeyListener,Runnable
{
int x=0;
BufferedImage offScreen;
JTextField j=new JTextField(5);
public void init()
{
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setFocusable(true);
Container screen = getContentPane();
screen.setBackground(Color.white);
screen.setLayout (new FlowLayout() );
screen.add(j);
//below is for our offscreen buffer image. Make it as large
offScreen = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
}
public void paint (Graphics g)
{
g.drawImage(offScreen,0,0,this);
}
//Update (the method below) gets called every frame
public void update()
{
x++;
Graphics g=getGraphics();
//uncomment below to show flashing
// g.setColor(Color.green);
// g.fillRect(0,0,500,500);
// g.setColor(Color.black);
// g.fillRect(40+x,50,20,20);
//comment out below to show the flashing when you dont double buffer
Graphics oG=offScreen.getGraphics();
//if you are using gui components (buttons, textfields, etc) uncomment this line and comment out the clear screen below
//super.paint(oG);
oG.setColor(Color.white);
oG.fillRect(0,0,500,500);
oG.setColor(Color.black);
oG.fillRect(40+x,50,20,20);
g.drawImage(offScreen,0,0,this);
}
//This is the method that will be called if a key is pressed
//It is neccessary if you are using getKeyCode()
public void keyPressed(KeyEvent e)
{
char theChar=e.getKeyChar();
int theCode=e.getKeyCode();
}
//This is the method that will be called if a key is released
//It is unneccessary to use this method, but you must include it
public void keyReleased(KeyEvent e)
{
}
//This is the method that will be called if a key is typed, however you cant use getKeyCode, so
// you are better to use keyPressed
public void keyTyped(KeyEvent e)
{
}
//when someone presses the mouse button
public void mousePressed(MouseEvent e)
{
int x=e.getX();
int y=e.getY();
}
//when someone releases the mouse button
public void mouseReleased(MouseEvent e)
{
}
// when the mouse enters the applet
public void mouseEntered(MouseEvent e)
{
}
//when the mouse leaves the applet
public void mouseExited(MouseEvent e)
{
}
//when the mouse button is clicked
public void mouseClicked(MouseEvent e)
{
requestFocus(); //this bring the focus make to the main progra
}
//the mouse button is pressed and the mouse makes a significantly large movement
public void mouseDragged(MouseEvent e)
{
}
//the mouse makes a significantly large movement
public void mouseMoved(MouseEvent e)
{
}
public void actionPerformed(ActionEvent thisEvent)
{
Object source = thisEvent.getSource();
/* Uncomment below for actions
if (source == testButton)
{
}
*/
}
public int findRandom (int start, int end)
{
int multiplier = end-start+1;
int random = (int) (Math.random()*multiplier)+start;
return random;
}
public Color findRandomColor ()
{
int red= (int)(256 * Math.random());
int green= (int)(256 * Math.random());
int blue= (int)(256 * Math.random());
Color randomColor=new Color(red,green,blue);
return randomColor;
}
/*********************************************************************************************/
/* BELOW IS FOR ANIMATION. THE ONLY THING THAT YOU NEED TO CHANGE IS DELAY */
int frame;
int delay=50; // this is the time of the delay in milliseconds.
Thread animator;
/**
* This method is called when the applet becomes visible on
* the screen. Create a thread and start it.
*/
public void start()
{
animator = new Thread(this);
animator.start();
}
/**
* This method is called by the thread that was created in
* the start method. It does the main animation.
*/
public void run()
{
// Remember the starting time
long tm = System.currentTimeMillis();
while (Thread.currentThread() == animator)
{
// Display the next frame of animation.
update();
try
{
tm += delay;
Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
}
catch (InterruptedException e)
{
break;
}
// Advance the frame
frame++;
}
}
/**
* This method is called when the applet is no longer
* visible. Set the animator variable to null so that the
* thread will exit before displaying the next frame.
*/
public void stop()
{
animator = null;
}
}
|