Total Pageviews

Sunday, August 11, 2013

Avoid flickering using Buffered image technique(Java)

In the previous tutorial, there was a little flickering of the image "flyy.jpg" during program execution and obviously the animation was bad. So, in this tutorial i will show you how to avoid the flickering effect through Buffered Image Technique.
The flickering is due to the fact that the "flyy.jpg" is being directly drawn on the graphics context of the Canvas.
                 
         public void draw(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, 800, 600); //clears the previous screen
g.drawImage(fly, x, y, null);
}

Here "g" is the graphics context of the Object Screen(extends Canvas).

So, the steps to avoid this are-

1.Create an object of type "Image".
 
     Image offScreen;
     offScreen = createImage(800,600);

2.Create an object of type "Graphics".
   
    Graphics bufferGraphics;

3.Get the graphics context of  "offScreen" in "bufferGraphics".

    bufferGraphics = offScreen.getGraphics();

4.Now replace the "draw( Graphics)" method with this.

   public void draw(Graphics g){
bufferGraphics.setColor(Color.white);
bufferGraphics.fillRect(0, 0, 800, 600); //clears the previous screen
bufferGraphics.drawImage(fly, x, y, null);
g.drawImage(offScreen, 0, 0, this);
}

Now , you can see that you are actually drawing everything on "offScreen" and at last drawing the "offScreen" on "g".

Now the full updated code is here-

                                                  FULL SOURCE CODE
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class Screen extends Canvas implements Runnable {

static Screen screen = new Screen();
Thread t;
Image fly;
boolean animation = true;
int x=400,y=400,dx=4,dy=4;
Image offScreen;
Graphics bufferGraphics;

public void init(){

try {
fly = ImageIO.read(new File("res/flyy.jpg"));
} catch (IOException e){}

offScreen = createImage(800,600);
bufferGraphics = offScreen.getGraphics();

t = new Thread(this);
t.start();

}

public void run(){

while(animation){

flyMoves(); //checks the fly movement
 
draw(screen.getGraphics()); //draws image on the screen

try{
Thread.sleep(40);
}catch(Exception e){}

}

}

public void flyMoves(){
x += dx;
y += dy;

if(x<0 || x>750)
dx = -dx;
if(y<0 || y>550)
dy = -dy;
}

public void draw(Graphics g){
bufferGraphics.setColor(Color.white);
bufferGraphics.fillRect(0, 0, 800, 600); //clears the previous screen
bufferGraphics.drawImage(fly, x, y, null);
g.drawImage(offScreen, 0, 0, this);
}

public static void main(String[] args) {

JFrame frame = new JFrame();
frame.add(screen);
frame.pack();
frame.setTitle("Simple Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(800, 600);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
screen.init();

}

}

                                                                        SNAPSHOT


Tuesday, August 6, 2013

Simple Animation using Multithreading(Java)

This is the very basic tutorial and very first step in Game Programming using Java. In this tutorial i'll show you how to animate something(in this case flyy.jpg) using Java Multithreading. You have to put flyy.jpg in folder "res". This folder must be included in class folders or must be in the current directory.

Step 1- First of all, i have created a class Screen which extends Canvas. A Canvas component represents a blank rectangular area of the screen onto which the application can draw or from which the application can trap input events from the user. And, i have also created the class skeleton by declaring the methods. Please note, the Screen class implements Runnable interface which has only method  "run( )". when the Thread starts then the "run( )" method of the current object is called.

import java.awt.Canvas;
import java.awt.Graphics;


public class Screen extends Canvas implements Runnable {




public void init(){ }


        public void run(){ }


        public void flyMoves(){ }


        public void draw(Graphics g){ }


        public static void main(String[] args) { }



}


Step 2-  Now i have defined the "init( )" method which only loads the image file in the variable fly and also starts the thread. And, "ImageIO.read(File)" method throws an IOException, thats why, the statement must be in the "try/catch" block in which the method is called.

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;



public class Screen extends Canvas implements Runnable {


Thread t;
Image fly;


public void init(){

try {
fly = ImageIO.read(new File("res/flyy.jpg"));
} catch (IOException e){}

t = new Thread(this);
t.start();

}

public void run(){



}

public void flyMoves(){

}

public void draw(Graphics g){

}

public static void main(String[] args) {



}


}

Step 3- In this step i will define the "run( )" method. This method calls two other methods "flyMoves( )" which is reponsible for the movement of the fly object and "draw( Graphics)" which is for drawing on the graphics context of the Canvas. You can see that i have put the statements of the "run( )" method in an infinite loop in order to tun the thread till the termination of the program. The "sleep( long millisecs)" is used to pause the thread for a certain amount of time specified in the argument. Due to this method the animation is possible using threads.

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;



public class Screen extends Canvas implements Runnable {
static Screen screen = new Screen();
Thread t;
Image fly;
boolean animation = true;
int x=400,y=400,dx=4,dy=4;
public void init(){
try {
fly = ImageIO.read(new File("res/flyy.jpg"));
} catch (IOException e){}
t = new Thread(this);
t.start();
}
public void run(){
while(animation){
flyMoves(); //checks the fly movement
 
draw(screen.getGraphics()); //draws image on the screen
try{
Thread.sleep(40);
}catch(Exception e){}
}
}
public void flyMoves(){
}
public void draw(Graphics g){
}
public static void main(String[] args) {

}

}

Step 4- In this step i will define the "flyMoves( )" method which is responsible for the movements of the fly oblect. The code is such that the cordinates of the fly is always in the region 0<x<750 and 0<y<550.

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;


public class Screen extends Canvas implements Runnable {

static Screen screen = new Screen();
Thread t;
Image fly;
boolean animation = true;
int x=400,y=400,dx=4,dy=4;

public void init(){

try {
fly = ImageIO.read(new File("res/flyy.jpg"));
} catch (IOException e){}

t = new Thread(this);
t.start();

}

public void run(){

while(animation){

flyMoves(); //checks the fly movement

draw(screen.getGraphics()); //draws image on the screen

try{
Thread.sleep(40);
}catch(Exception e){}

}

}

public void flyMoves(){
x += dx;
y += dy;

if(x<0 || x>750)
dx = -dx;
if(y<0 || y>550)
dy = -dy;
}

public void draw(Graphics g){

}

public static void main(String[] args) {



}

}

Step 5- In this step i will define the "draw( Graphics)" method. This method takes argument of type Graphics and therefore the graphics context of the screen object is passed as argument. Remember, screen is an object of Screen class which extends Canvas.The very first thing we have to do here is to clear the previous screen whenever the "draw(Graphics)" method is called. For this, we can simply paint a white(or any color) rectangle which is exact the size of the screen. Everytime the method is called it first paints a rectangle on the screen which clears the screen. Now we paint the fly object.

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class Screen extends Canvas implements Runnable {

static Screen screen = new Screen();
Thread t;
Image fly;
boolean animation = true;
int x=400,y=400,dx=4,dy=4;

public void init(){

try {
fly = ImageIO.read(new File("res/flyy.jpg"));
} catch (IOException e){}

t = new Thread(this);
t.start();

}

public void run(){

while(animation){

flyMoves(); //checks the fly movement

draw(screen.getGraphics()); //draws image on the screen

try{
Thread.sleep(40);
}catch(Exception e){}

}

}

public void flyMoves(){
x += dx;
y += dy;

if(x<0 || x>750)
dx = -dx;
if(y<0 || y>550)
dy = -dy;
}

public void draw(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, 800, 600); //clears the previous screen
g.drawImage(fly, x, y, null);
}

public static void main(String[] args) {



}

}



At last, we define a JFrame object and add the screen object to it by using "frame.add(screen)" and call the "init( )" method in order to start the thread.

 public static void main(String[] args) {

JFrame frame = new JFrame();
frame.add(screen);
frame.pack();
frame.setTitle("Simple Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(800, 600);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
screen.init();

}


                                                               FULL SOURCE CODE

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class Screen extends Canvas implements Runnable {

static Screen screen = new Screen();
Thread t;
Image fly;
boolean animation = true;
int x=400,y=400,dx=4,dy=4;

public void init(){

try {
fly = ImageIO.read(new File("res/flyy.jpg"));
           // load the image file present in the "res" folder in the same directory                                                            
  } catch (IOException e){}

t = new Thread(this);
t.start();

}

public void run(){

while(animation){

flyMoves(); //checks the fly movement
 
draw(screen.getGraphics()); //draws image on the screen

try{
Thread.sleep(40);
}catch(Exception e){}

}

}

public void flyMoves(){
x += dx;
y += dy;

if(x<0 || x>750)
dx = -dx;
if(y<0 || y>550)
dy = -dy;
}

public void draw(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, 800, 600); //clears the previous screen
g.drawImage(fly, x, y, null);
}

public static void main(String[] args) {

JFrame frame = new JFrame();
frame.add(screen);
frame.pack();
frame.setTitle("Simple Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(800, 600);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
screen.init();

}

}

                                                                    SCREENSHOT