I'm using the following code to try to print out an array and move a BufferedPicture ( test ) through the variables of xaxis and yaxis.
There is an additional class called "Screen", but it should be irrelevant to this problem.
package main.main.start;
import javax.swing.JTextField;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import main.main.start.graphics.Screen;
public class start extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
public static int width = 320;
public static int height = width / 16 * 9;
public static int scale = 3;
public boolean up,left,right,down;
public BufferedImage keine,floor,wall,test;
public int xaxis,yaxis;{
xaxis = 50;
yaxis = 50;
}
private Thread thread;
private JFrame frame;
private BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB );
private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
private boolean running = false;
private Screen screen;
public start (){
Dimension size = new Dimension(width*scale,height*scale);
setPreferredSize (size);
screen = new Screen(width, height);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop(){
running = false;
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run(){
while(running == true){
//rendering&updating
//System.out.println("running...");
update();
render();
}
}
public void update() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if(bs == null){
createBufferStrategy(3);
return;
}
screen.clear();
screen.render();
for(int i = 0; i < pixels.length; i++){
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLUE);
g.fillRect(0,0,getWidth(), getHeight() );
g.drawImage(image, 0, 0, getWidth(),getHeight(),null);
//playercontrollerstart
//playercontrollerend
//map
int[][] map=
{
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10},
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10}
};
int rows = 20;
int cols = 20;
int i, j;
try {
keine = ImageIO.read(new File("keine.png"));
floor = ImageIO.read(new File("floor.png"));
wall = ImageIO.read(new File("wall.png"));
test = ImageIO.read(new File("test.png"));
} catch (IOException e) {
e.printStackTrace();
}
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if(map[i][j] == 10){
g.drawImage(keine,i*32,j*32,this);
}
if(map[i][j] == 11){
g.drawImage(wall,i*32,j*32,this);
}
if(map[i][j] == 12){
g.drawImage(floor,i*32,j*32,this);
}
}
g.drawImage(test,xaxis,yaxis,this);
}
//mapend
g.dispose();
bs.show();
}
public static void main(String[] args) {
start game = new start();
game.frame.setResizable(false);
game.frame.setTitle("TestWindowName");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
Then the problem code (there is NO break in the code from } to //StartController
//StartController
public void keyPressed(KeyEvent q) {
if(q.getKeyCode() ==37){
left = true;
}
if(q.getKeyCode() ==38){
up = true;
}
if(q.getKeyCode() ==39){
right = true;
}
if(q.getKeyCode() ==40){
down = true;
}
}
public void keyReleased(KeyEvent q) {
if(q.getKeyCode() == 37){
left = false;
}
if(q.getKeyCode() == 38){
up = false;
}
if(q.getKeyCode() == 39){
right = false;
}
if(q.getKeyCode() == 40){
down = false;
}
}
//EndController
}
What I believe to be the problem is that you have not implemented or added a KeyListener to your application. You must implement KeyListener, and inherit all methods.
Like so:
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* Simple Canvas with KeyListener
*/
public class TestCanvas extends Canvas implements KeyListener, Runnable {
public TestCanvas() {
addKeyListener(this);
}
#Override
public void keyTyped(KeyEvent e) {
//Do Stuff
}
#Override
public void keyPressed(KeyEvent e) {
//Do Stuff
}
#Override
public void keyReleased(KeyEvent e) {
//Do Stuff
}
}
Secondly, I would recommend using KeyEvent.VK_(some key) to compare key code values, this way you aren't relying on the assumption that your constants are always true for every keyboard.
Okay, so my friend and I are making are a game that requires some pixel analysis for the rectangles, and I wrote the code to analyze the rectangles, and It works swimmingly, However, when I try to draw the bufferedImage it doesn't show up. The main issue is that my java class has never taught us how to use Jframes, and I don't want to change my code to accommodate:
// Threaded Applet Template that works with Macs
// Import section
// Use this section to add additional libaries for use in your program.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.awt.Toolkit;
import javax.imageio.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.*;
// This begins the class definition.
// Notice that this is a "world". You can tell since it extends Applet.
// It also implement Runnable which allows it to be and use threads.
public class PixelAnalyzetest extends Applet implements Runnable
{
//variable declaration section
// public datatype variablename
public int xTitle;
public int yTitle;
public Analyzer analyzer;
public BufferedImage test;
public Image itest;
public boolean analyzeonce=true;
//declare your Hero object here
//Sets up a Thread called thread
Thread thread;
// Method definition section
// init() is the first method an Applet runs when started
public void init()
{
//Initialize variables
xTitle=10;
yTitle=10;
BufferedImage test = new BufferedImage(1200,1200, BufferedImage.TYPE_INT_ARGB);
//test = getImage(getDocumentBase(),"test.png");
System.out.println("the width of the image is: "+test.getWidth(this));
try{
test = ImageIO.read(new File("test.png"));
} catch(IOException e) {};
//itest=test.getAsBufferedImage();
analyzer = new Analyzer(test, 5);
//construct objects
//construct your hero here!
//Set up the thread
//These should be the LAST lines in your init( ) method.
thread = new Thread(this); //constructs a new thread
thread.start(); //starts the thread
}//init()
// paint() is used to display things on the screen
public void paint(Graphics g)
{
setSize(1200,1200);
//Put the title on the screen.
/*for(int x=0;x<test.getWidth();x++)
{
for(int y=0;y<test.getHeight();y++)
{
BufferedImage.setRGB(x,y,analyzer.pictureRGB[x][y]);
}
}*/
g.drawImage(test,0,0,1200,1200,this);
//draw your hero's name here using g.drawString( )
}// paint()
// every thread needs a run method
// this is what the thread will do
public void run() {
// this thread loop forever and runs the paint method and then sleeps.
while(true)
{
//put what you want your program to do here.
//move your hero here by calling its move() method.
if(analyzeonce==true)
{
analyzer.analyzelines();
analyzeonce=false;
}
repaint(); // run the paint method.
//sleep
try {
thread.sleep(100);
}
catch (Exception e){ }
}//while
}// run()
}
Now my analyzer class:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.awt.Toolkit;
public class Analyzer
{
public int[][] pictureRGB;
//VARIABLE DECLARATION SECTION
//Here's where you state which variables you are going to use.
public String name; //use this format public datatype variablename;
public boolean isAlive;
public int health;
public int strength;
public String theGlove;
public int dx, dy;
public BufferedImage analyzing, bgrab;
public int imagewidth, imageheight;
public int linecounter = 0;
public int boxcounter = 0;
public boolean endline = false;
public Line lines[];
public Box boxes[];
public int totalboxes;
public boolean donean = false;
// METHOD DEFINITION SECTION
// Constructor Definition
// A constructor "builds" the object when called and give the variable initial values.
// This constructor build Heroes with all the same initial values.
public Analyzer(BufferedImage grab, int xtotalboxes)
{
//BufferedImage bgrab = (BufferedImage) grab;
//bgrab = new BufferedImage(1200,1200, BufferedImage.TYPE_INT_ARGB);
//bgrab.getGraphics().drawImage(grab,0,0,bgrab.getWidth(),bgrab.getHeight(),null);
analyzing = grab;
totalboxes = xtotalboxes;
imagewidth=analyzing.getWidth();
System.out.println(imagewidth+" Is the image's Width");
imageheight=analyzing.getHeight();
System.out.println(imagewidth+" Is the image's Height");
pictureRGB= new int[imagewidth] [imageheight];
lines = new Line[10];
boxes = new Box[20];
isAlive = true;
health = 200;
strength = 20;
for(int xpos = 1; xpos<imagewidth-1;xpos++)
{
for(int ypos = 1; ypos<imageheight-1; ypos++)
{
pictureRGB[xpos][ypos]=analyzing.getRGB(xpos,ypos);
//System.out.println(pictureRGB[xpos][ypos]);
}
}
}
public void analyzelines()
{
for(boxcounter=0; boxcounter<boxes.length; boxcounter++)
{
int tempx = 0;
int tempy = 0;
int tempw = 0;
int temph = 0;
//int pxpos = 0;
//int pypos = 0;
boolean startline=false;
boolean foundw = false;
boolean foundh = false;
if(donean==false)
{
for(int ypos = 1; ypos<imageheight-1; ypos++)
{
for(int xpos = 1; xpos<imagewidth-1;xpos++)
{
if(boxcounter>0)
{
if(pictureRGB[xpos][ypos]==-3584 && startline==false && boxes[boxcounter-1].rect.contains(new Point(xpos,ypos))==false && boxes[boxcounter-1].rect.intersects(new Rectangle(xpos-2,ypos-2,4,4))==false && isEqual(new Rectangle(xpos-2,ypos-2,4,4))==false)
{
System.out.println("--------------------------------START BOX --------------");
System.out.println("The top left corner of the box is: ("+xpos+","+ypos+")");
startline=true;
tempx=xpos;
tempy=ypos;
//System.out.println(tempx+"<<TEMPX TEMPY>>"+tempy);
}
if(startline==true && pictureRGB[xpos+1][ypos]!=pictureRGB[xpos][ypos] && foundw==false && foundh==false && boxes[boxcounter-1].rect.contains(new Point(xpos,ypos))==false && isEqual(new Rectangle(xpos-2,ypos-2,4,4))==false)
{
tempw=xpos-tempx;
System.out.println("XPOS EQ = "+xpos+" - "+tempx+" = "+ tempw);
foundw = true;
//System.out.println(tempw+"<<TEMPw TEMPx>>"+tempx+"<<<<XPOS>>>>>>>>>>>>>"+xpos);
}
if(startline==true && pictureRGB[xpos][ypos+1]!=pictureRGB[xpos][ypos] && foundh==false && foundw==true && boxes[boxcounter-1].rect.contains(new Point(xpos,ypos))==false && pictureRGB[xpos-1][ypos]==pictureRGB[xpos][ypos] && pictureRGB[xpos+1][ypos]!=pictureRGB[xpos][ypos] && isEqual(new Rectangle(xpos-2,ypos-2,4,4))==false)
{
temph=ypos-tempy;
System.out.println("YPOS EQ = "+ypos+" - "+tempy+" = "+ temph);
foundh=true;
System.out.println("The Width is: "+tempw+" The height is: "+temph+" boxcounter="+boxcounter);
boxes[boxcounter]= new Box(tempx, tempy, tempw, temph);
System.out.println("--------------------------------NEXT BOX ---------------");
//System.out.println("BOX WIDTH"+boxes[boxcounter].width + "BOX COUNTER=="+boxcounter);
}
}
if(boxcounter==0)
{
if(pictureRGB[xpos][ypos]==-3584 && startline==false)
{
System.out.println("The top left corner of the box is: ("+xpos+","+ypos+")");
startline=true;
tempx=xpos;
tempy=ypos;
}
if(startline==true && pictureRGB[xpos+1][ypos]!=pictureRGB[xpos][ypos] && foundw==false && foundh==false)
{
tempw=xpos-tempx;
foundw = true;
}
if(startline==true && pictureRGB[xpos][ypos+1]!=pictureRGB[xpos][ypos] && foundh==false && foundw==true)
{
temph=ypos-tempy;
foundh=true;
System.out.println("The Width is: "+tempw+" The height is: "+temph+" boxcounter="+boxcounter);
boxes[boxcounter]= new Box(tempx, tempy, tempw, temph);
//System.out.println("BOX WIDTH"+boxes[boxcounter].width);
}
}
}
}
if(boxcounter>=(totalboxes))
{
donean=true;
}
}
//System.out.println("The black lines width is: "+(lines[linecounter].endx-lines[linecounter].startx));
}
}
public boolean isEqual(Rectangle c1)
{
boolean returned = false;
for(int i = 0; i<boxcounter; i++)
{
if(c1.intersects(boxes[i].rect) || boxes[i].rect.contains(new Point(c1.x, c1.y)))
{
returned=true;
}
}
return(returned);
}
/*
public static BufferedImage toBufferedImage(Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
*/
public void move()
{
}
//Other methods
//You can define what this type of object can do here.
}
my line and box classes are very straight forward just some classes i made with xposes and yposes, width's and heights
i'm trying to create a game. And almost everytime I move, it's leaving a trail
Code:
package lt.mchackers.gametest.main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import lt.mchackers.gametest.handlers.InputHandler;
/**
* Main class for the game
*/
public class Main extends JFrame
{
private static final long serialVersionUID = -828018325337767157L;
boolean isRunning = true;
int fps = 30;
int windowWidth = 320;
int windowHeight = 320;
int speed;
BufferedImage backBuffer;
Insets insets;
InputHandler input;
int x = 0;
int y = 0;
int xa = 0;
int ya = 0;
Coordinates coords = new Coordinates(0, 0);
public static void main(String[] args)
{ Main game = new Main();
game.run();
System.exit(0);
}
/**
* This method starts the game and runs it in a loop
*/
public void run()
{
initialize();
while(isRunning)
{
long time = System.currentTimeMillis();
update();
draw();
// delay for each frame - time it took for one frame
time = (1000 / fps) - (System.currentTimeMillis() - time);
if (time > 0)
{
try
{
Thread.sleep(time);
}
catch(Exception e){}
}
}
setVisible(false);
}
/**
* This method will set up everything need for the game to run
*/
void initialize()
{
setTitle("Game Tutorial");
setSize(windowWidth, windowHeight);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
insets = getInsets();
setSize(insets.left + windowWidth + insets.right,
insets.top + windowHeight + insets.bottom);
backBuffer = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB);
input = new InputHandler(this);
Graphics bbg = backBuffer.getGraphics();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("map"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String line = null;
try {
BufferedImage gray = ImageIO.read(new File("gray.png"));
BufferedImage black = ImageIO.read(new File("black.png"));
while ((line = reader.readLine()) != null) {
for(String s : line.split(""))
{
if (s.contains("*"))
{
bbg.drawImage(gray, xa-32, ya, null);
}
else if (s.contains("#"))
{
bbg.drawImage(black, xa-32, ya, null);
}
if (xa < 320)
{
xa += 32;
}
else
{
ya += 32;
xa = 0;
}
System.out.println(xa);
System.out.println(ya);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This method will check for input, move things
* around and check for win conditions, etc
*/
void update()
{
if (input.isKeyDown(KeyEvent.VK_NUMPAD0))
{
speed -= 1;
}
if (input.isKeyDown(KeyEvent.VK_NUMPAD1))
{
speed += 1;
}
if (input.isKeyDown(KeyEvent.VK_RIGHT))
{
coords.setCoords(coords.getX() + 32, coords.getY());
}
if (input.isKeyDown(KeyEvent.VK_LEFT))
{
coords.setCoords(coords.getX() - 32, coords.getY());
}
if (input.isKeyDown(KeyEvent.VK_UP))
{
coords.setCoords(coords.getX(), coords.getY() - 32);
}
if (input.isKeyDown(KeyEvent.VK_DOWN))
{
coords.setCoords(coords.getX(), coords.getY() + 32);
}
//System.out.println(x);
//System.out.println(y);
//System.out.println(speed);
if (coords.getY() < 0)
{
coords.setCoords(coords.getX(), 0);
}
if (coords.getX() < 0)
{
coords.setCoords(0, coords.getY());
}
if (coords.getX() > windowWidth - 32)
{
coords.setCoords(windowWidth - 32, coords.getY());
}
if (coords.getY() > windowHeight - 32)
{
coords.setCoords(coords.getX(), windowHeight - 32);
// y = windowHeight - 32;
}
}
/**
* This method will draw everything
*/
void draw()
{
Graphics g = getGraphics();
//this.setBackground(Color.BLACK);
//super.paintComponents(g);
backBuffer.setRGB(x, y, Color.BLACK.getRGB());
Graphics bbg = backBuffer.getGraphics();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("map"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String line = null;
try {
BufferedImage gray = ImageIO.read(new File("gray.png"));
BufferedImage black = ImageIO.read(new File("black.png"));
while ((line = reader.readLine()) != null) {
for(String s : line.split(""))
{
if (s.contains("*") && xa + 32!= coords.getX() && ya - 32 != coords.getY())
{
bbg.drawImage(gray, xa-32, ya, null);
}
else if (s.contains("#") && xa + 32 != coords.getX() && ya - 32 != coords.getY())
{
bbg.drawImage(black, xa-32, ya, null);
}
if (xa < 320)
{
xa += 32;
}
else
{
ya += 32;
xa = 0;
}
//System.out.println(xa);
//System.out.println(ya);
}
}
} catch (IOException e) {
e.printStackTrace();
}
bbg.setColor(Color.WHITE);
xa = 0;
ya = 0;
System.out.println(coords.getX());
bbg.setColor(Color.WHITE);
bbg.fillRect(coords.getX(),coords.getY(), 32,32);
System.out.println(coords.getY());
//bbg.setColor(Color.BLACK);
//bbg.drawOval(x, y, 20, 20);
g.drawImage(backBuffer, insets.left, insets.top, this);
}
}
Thanks for help.
Check out my code from here, to get a hint as to how to paint stuff in a game loop properly.
Basically what you need to take care of is double buffering to prevent any flickering and also repainting the background so that you don't leave out any trail of rectangles.
You can also check out the Killer Game Programming in Java online book, which can help you learn the game programming concepts and their implementation.
The concept of double buffering is simple. Since painting on the screen takes more time than updating the states of the objects in the gameplay, we use two canvas to prevent any flickering issues which arise when objects are painted directly on the screen.
When the object states are updated in the game loop, it is rendered in a background canvas. The background canvas is then copied to the screen which takes less time compared to painting directly on the screen. And while this copying is happening, the object states are updated again and they are rendered on the background canvas again, which is then copied to the screen. Repeat this over and over, and you get the double buffering.
Basically you keep a buffer of screen which is to be painted and your game renders objects in the buffer which is then copied to the screen.
Here's a code which I think might help you understand the concept:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GamePanel extends JPanel implements Runnable
{
private static final long serialVersionUID = 6892533030374996243L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
private Thread animator;
private volatile boolean running = false;
private volatile boolean isGameOver = false;
private volatile boolean isUserPaused = false;
private volatile boolean isWindowPaused = false;
private Graphics dbg;
private Image dbImage = null;
private static final int NO_DELAYS_PER_YIELD = 16;
private static final int MAX_FRAME_SKIPS = 5;
private static final Color backgroundColor = new Color(245, 245, 245);
private static long fps = 30;
private static long period = 1000000L * (long) 1000.0 / fps;
private static volatile boolean isPainted = false;
public GamePanel()
{
setBackground(backgroundColor);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
readyForPause();
// Add key listeners here...
}
public void addNotify()
{
super.addNotify();
startGame();
}
void startGame()
{
if (animator == null || !running)
{
animator = new Thread(this);
animator.start();
}
}
void stopGame()
{
running = false;
}
private void readyForPause()
{
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if ((keyCode == KeyEvent.VK_ESCAPE) || (keyCode == KeyEvent.VK_Q)
|| (keyCode == KeyEvent.VK_END) || (keyCode == KeyEvent.VK_P)
|| ((keyCode == KeyEvent.VK_C) && e.isControlDown()))
{
if (!isUserPaused)
setUserPaused(true);
else
setUserPaused(false);
}
}
});
}
// This is the game loop. You can copy-paste it even in your own code if you want to.
public void run()
{
long beforeTime, afterTime, timeDiff, sleepTime;
long overSleepTime = 0L;
int noDelays = 0;
long excess = 0L;
beforeTime = System.nanoTime();
running = true;
while (running)
{
requestFocus();
gameUpdate();
gameRender();
paintScreen();
afterTime = System.nanoTime();
timeDiff = afterTime - beforeTime;
sleepTime = (period - timeDiff) - overSleepTime;
if (sleepTime > 0)
{
try
{
Thread.sleep(sleepTime / 1000000L);
}
catch (InterruptedException e)
{
}
overSleepTime = (System.nanoTime() - afterTime - sleepTime);
}
else
{
excess -= sleepTime;
overSleepTime = 0L;
if (++noDelays >= NO_DELAYS_PER_YIELD)
{
Thread.yield();
noDelays = 0;
}
}
beforeTime = System.nanoTime();
int skips = 0;
while ((excess > period) && (skips < MAX_FRAME_SKIPS))
{
excess -= period;
gameUpdate();
skips++;
}
isPainted = true;
}
System.exit(0);
}
private void gameUpdate()
{
if (!isUserPaused && !isWindowPaused && !isGameOver)
{
// Update the state of your game objects here...
}
}
private void gameRender()
{
if (dbImage == null)
{
dbImage = createImage(WIDTH, HEIGHT);
if (dbImage == null)
{
System.out.println("Image is null.");
return;
}
else
dbg = dbImage.getGraphics();
}
dbg.setColor(backgroundColor);
dbg.fillRect(0, 0, WIDTH, HEIGHT);
// Render your game objects here....
// like: xyzObject.draw(dbg);
// or dbg.drawOval(...);
if (isGameOver)
gameOverMessage(dbg);
}
private void gameOverMessage(Graphics g)
{
// Paint a game over message here..
}
private void paintScreen()
{
Graphics g;
try
{
g = this.getGraphics();
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
catch (Exception e)
{
System.out.println("Graphics context error : " + e);
}
}
public void setWindowPaused(boolean isPaused)
{
isWindowPaused = isPaused;
}
public void setUserPaused(boolean isPaused)
{
isUserPaused = isPaused;
}
}
Then you can simply add your game panel to your JFrame like following:
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class GameFrame extends JFrame
{
private static final long serialVersionUID = -1624735497099558420L;
private GameFrame gamePanel = new GamePanel();
public GameFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Game");
addWindowListener(new FrameListener());
getContentPane().setLayout(new GridBagLayout());
getContentPane().add(gamePanel);
pack();
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public class FrameListener extends WindowAdapter
{
public void windowActivated(WindowEvent we)
{
gamePanel.setWindowPaused(false);
}
public void windowDeactivated(WindowEvent we)
{
gamePanel.setWindowPaused(true);
}
public void windowDeiconified(WindowEvent we)
{
gamePanel.setWindowPaused(false);
}
public void windowIconified(WindowEvent we)
{
gamePanel.setWindowPaused(true);
}
public void windowClosing(WindowEvent we)
{
gamePanel.stopGame();
}
}
public static void main(String args[])
{
new GameFrame();
}
}