Better than thread.sleep

Whats a good way to get nice FPS, my images are skipping, not sliding like they should

import java.awt.event.*;

import javax.swing.*;

import java.awt.*;

import java.awt.image.BufferStrategy;

public class TitleScreen extends JFrame implements Runnable, KeyListener {

Toolkit tk = Toolkit.getDefaultToolkit();

MediaTracker mt = new MediaTracker(this);

Dimension d = tk.getScreenSize();

BufferStrategy strategy;

Image Title = tk.getImage("images/TitleScreen/Title.png");

Image Title2 = tk.getImage("images/TitleScreen/Title2.png");

Image chris = tk.getImage("images/chris/battle.png");

Image backbuff, backbuff2;

Thread t = new Thread(this);

boolean running;

int X = getX(1280), Y = getY(600), tX = -500, tY;

public TitleScreen(){

setTitle("Title");

setSize(d.width, d.height);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

addKeyListener(this);

strategy = getBufferStrategy();

createBufferStrategy(2);

mt.addImage(chris, 0);

mt.addImage(Title, 0);

mt.addImage(Title2, 0);

try{

mt.waitForAll();

}catch(InterruptedException e){}

t.start();

draw();

}

public void draw(){

running = true;

while(running){

backbuff = createImage(d.width, d.height);

Graphics g = strategy.getDrawGraphics();

Graphics2D g2 = (Graphics2D)backbuff.getGraphics();

g2.setColor(Color.black);

g2.fillRect(0, 0, d.width, d.height);

g2.drawImage(Title, tX, 0, d.width, d.height, this);

g2.drawImage(chris, X, Y, getX(chris.getWidth(this)), getY(chris.getHeight(this)), this );

g.drawImage(backbuff, 0, 0, this);

g.dispose();

strategy.show();}

}

public void run() {

for(int num = 0; num <= 250; num++){

try{

X -= 5;

if(tX != 0){

tX += 5;}

t.sleep(5);

}catch(InterruptedException e){} }

}

int getX(int X){

return X * d.width / 1280;}

int getY(int Y){

return Y * d.height / 1024;}

public void keyPressed(KeyEvent e){

if(e.getKeyCode() == KeyEvent.VK_ENTER){

Title = Title2;}

if(e.getKeyCode() == KeyEvent.VK_RIGHT){

X += 1;}

}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

public static void main(String args[]){

new TitleScreen();}

}

any help?

[2544 byte] By [slickida] at [2007-9-29 7:04:29]
# 1
i don't think Thread.sleep is the problem, but shouldn't your call to draw() be in your run method rather than getting called only onceAnd btw, please post code in [ code] and [ /code] brackets (without the spaces)
Seekelya at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 2
But the draw is in a while loop, so it keeps drawing to the screen.Its faster when i put it that way, putting the draw() in the run() method. I cant find a way to get SMOOTH graphics. Its always choppy the way i do it. You think you could show me a way to get smooth animation?
slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 3
I did what you said, it stopped the skipping lol, but its way slow.I kno javas slow but come on, theres got to be a way.
slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 4

OMG its so increditbly SLOW!!

look at this code:

[

import java.awt.event.*;

import javax.swing.*;

import java.awt.*;

import java.awt.image.BufferStrategy;

public class TitleScreen extends JFrame implements Runnable, KeyListener {

Toolkit tk = Toolkit.getDefaultToolkit();

MediaTracker mt = new MediaTracker(this);

Dimension d = tk.getScreenSize();

BufferStrategy strategy;

Image Title = tk.getImage("images/TitleScreen/Title.png");

Image Title2 = tk.getImage("images/TitleScreen/Title2.png");

Image chris = tk.getImage("images/chris/battle.png");

Image backbuff, backbuff2;

Thread t = new Thread(this);

boolean running;

int X = getX(1280), Y = getY(600), tX = -500, tY;

public TitleScreen(){

setTitle("Title");

setSize(d.width, d.height);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

addKeyListener(this);

strategy = getBufferStrategy();

createBufferStrategy(2);

mt.addImage(chris, 0);

mt.addImage(Title, 0);

mt.addImage(Title2, 0);

try{

mt.waitForAll();

}catch(InterruptedException e){}

start();

}

public void draw(){

running = true;

backbuff = createImage(d.width, d.height);

Graphics g = strategy.getDrawGraphics();

Graphics2D g2 = (Graphics2D)backbuff.getGraphics();

g2.setColor(Color.black);

g2.fillRect(0, 0, d.width, d.height);

g2.drawImage(Title, tX, 0, d.width, d.height, this);

g2.drawImage(chris, X, Y, getX(chris.getWidth(this)), getY(chris.getHeight(this)), this );

g.drawImage(backbuff, 0, 0, this);

g.dispose();

strategy.show();

}

public void run(){}

public void start() {

while(true){

X -= 1;// even when i change this to a higher number it is slow

tX += 1;

draw();

}

}

int getX(int X){

return X * d.width / 1280;}

int getY(int Y){

return Y * d.height / 1024;}

public void keyPressed(KeyEvent e){

if(e.getKeyCode() == KeyEvent.VK_ENTER){

Title = Title2;}

if(e.getKeyCode() == KeyEvent.VK_RIGHT){

X += 1;}

}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

public static void main(String args[]){

new TitleScreen();}

}

\]

(did i do that [ \] thingy right?)

Now this doesnt even have the sleep pause, its just plain while loop

and it doesnt skip buts its slow, VERY even i put its on X += 50 and its slow. Im clueless on how to fix this problem

slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 5
Do you really want to be using Swing for a game?
paulcwa at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 6
Well.... yes, why not? I dont see anything wrong with using swing?what would you perfer?
slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 7

public void draw(){

running = true;

backbuff = createImage(d.width, d.height);

Graphics g = strategy.getDrawGraphics();

Graphics2D g2 = (Graphics2D)backbuff.getGraphics();

g2.setColor(Color.black);

g2.fillRect(0, 0, d.width, d.height);

g2.drawImage(Title, tX, 0, d.width, d.height, this);

g2.drawImage(chris, X, Y, getX(chris.getWidth(this)), getY(chris.getHeight(this)), this );

g.drawImage(backbuff, 0, 0, this);

g.dispose();

strategy.show();

}

you are using a back buffer AND bufferstrategy? why?!?!?!?

and you are recreating the back buffer every frame? why?!?!?!?

Abusea at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 8

> Well.... yes, why not? I dont see anything wrong with

> using swing?

> what would you perfer?

GUI toolkits = teh slow

lookee:

Image buf;

Graphics g;

void run() {

while(true) {

doInputAndLogic();

repaint();

Thread.sleep(1000/FPS);

}

}

void update(Graphics gtop) {

paint(gtop); // overwrite update - the default is slow

}

void paint(Graphics gtop) {

if(buf == null) {

buf = createImage(width, height);

g = buf.getGraphics();

}

// graphics stuff here, use g.drawThing(), not gtop.drawThing()

// g is buffered, gtop is top level

gtop.drawImage(buf, 0, 0, this);

}

shishthemoomina at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 9

1) Like Abuse has mentioned, use MANAGED images (ie: don't just use

Image image = tk.getImage("image_Name");

as the main image. Make it a managed image like so: BufferedImage image2 = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().

getDefaultConfiguration().createCompatibleImage(image.getWidth(this),image.

getHeight(this), Transparency.TRANSLUCENT);

image2.createGraphics().drawImage(image, 0, 0, null);

Now, you have image2 which is a managed image (which will definately boost your fps).

afarmanda at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 10
continued from above....Now you can use image2 in your draw method WITHOUT reacreating the image every iteration of draw().
afarmanda at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 11

Thanks, now look at my code:

import java.awt.event.*;

import javax.swing.*;

import java.awt.*;

import java.awt.image.*;

public class TitleScreen extends JFrame implements KeyListener, Runnable {

Toolkit tk = Toolkit.getDefaultToolkit();

MediaTracker mt = new MediaTracker(this);

Dimension d = tk.getScreenSize();

Image backbuff;

Graphics g, g2;

int X[] = new int[]{0, 550, 1500, 1700, 1900};

int Y[] = new int[] {0, -300, 0, 0, 0};

Image sonic_left = tk.getImage("images/sonic_left.png");

Image sonic_right = tk.getImage("images/sonic_right.png");

Image fox_left = tk.getImage("images/fox_left.png");

Image fox_right = tk.getImage("images/fox_right.png");

Image mario_left = tk.getImage("images/mario_left.png");

Image mario_right = tk.getImage("images/mario_right.png");

Image toad_left = tk.getImage("images/toad_left.png");

Image toad_right = tk.getImage("images/toad_right.png");

Image Title = tk.getImage("images/TitleScreen/Title.png");

Thread t = new Thread(this);

public TitleScreen(){

setTitle("Title");

setSize(d.width, d.height);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

addKeyListener(this);

mt.addImage(sonic_left, 0);

mt.addImage(sonic_right, 0);

mt.addImage(fox_left, 0);

mt.addImage(fox_right, 0);

mt.addImage(mario_left, 0);

mt.addImage(mario_right, 0);

mt.addImage(toad_left, 0);

mt.addImage(toad_right, 0);

mt.addImage(Title, 0);

try{

mt.waitForAll();

}catch(InterruptedException e){}

t.start();

}

public void run(){

while(true){

try{

X[2] -= 5;

repaint();

t.sleep(1000/ 100);

}catch(InterruptedException e ){} }

}

public void update(Graphics gtop){

paint(gtop);}

public void paint(Graphics gtop){

if(backbuff == null){

backbuff = createImage(d.width, d.height);

g = backbuff.getGraphics();}

g.setColor(Color.black);

g.fillRect(0, 0, d.width, d.height);

g.drawImage(mario_left, X[2], 795, this);

gtop.drawImage(backbuff, 0, 0, this);

}

int getX(int X){

return X * d.width / 1280;}

int getY(int Y){

return Y * d.height / 1024;}

public void keyPressed(KeyEvent e){}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

public static void main(String args[]){

new TitleScreen();}

}

The animation is smooth, but it sometimes moves a bit faster and you can see the lines being drawn. I tried the managed image but i didnt understand it and how to use it. But is there something im missing that is making the image jump a bit in its smooth animation?

slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 12

Wait!, I got it!! this way i dont even need a thread YAY! look:

import java.awt.event.*;

import javax.swing.*;

import java.awt.*;

import java.awt.image.*;

public class TitleScreen extends JFrame implements KeyListener {

Toolkit tk = Toolkit.getDefaultToolkit();

MediaTracker mt = new MediaTracker(this);

Dimension d = tk.getScreenSize();

Image backbuff;

Graphics g, g2;

int X[] = new int[]{0, 550, 1500, 1700, 1900};

int Y[] = new int[] {0, -300, 0, 0, 0};

Image sonic_left = tk.getImage("images/sonic_left.png");

Image sonic_right = tk.getImage("images/sonic_right.png");

Image fox_left = tk.getImage("images/fox_left.png");

Image fox_right = tk.getImage("images/fox_right.png");

Image mario_left = tk.getImage("images/mario_left.png");

Image mario_right = tk.getImage("images/mario_right.png");

Image toad_left = tk.getImage("images/toad_left.png");

Image toad_right = tk.getImage("images/toad_right.png");

Image Title = tk.getImage("images/TitleScreen/Title.png");

public TitleScreen(){

setTitle("Title");

setSize(d.width, d.height);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

addKeyListener(this);

mt.addImage(sonic_left, 0);

mt.addImage(sonic_right, 0);

mt.addImage(fox_left, 0);

mt.addImage(fox_right, 0);

mt.addImage(mario_left, 0);

mt.addImage(mario_right, 0);

mt.addImage(toad_left, 0);

mt.addImage(toad_right, 0);

mt.addImage(Title, 0);

try{

mt.waitForAll();

}catch(InterruptedException e){}

animation();

}

//// LOOK NO THREAD!!!!!!

public void animation(){

while(true){

X[2] -= 10; // the animation goes by the frame rate of how ever fast the computer is, (correct me if im wrong please :))

draw();}

}

// And no worry about update, my own method

public void draw(){

if(backbuff == null){

backbuff = createImage(d.width, d.height);

g = backbuff.getGraphics();

g2 = getGraphics();}

g.setColor(Color.black);

g.fillRect(0, 0, d.width, d.height);

g.drawImage(mario_left, X[2], 795, this);

g2.drawImage(backbuff, 0, 0, this);

}

int getX(int X){

return X * d.width / 1280;}

int getY(int Y){

return Y * d.height / 1024;}

public void keyPressed(KeyEvent e){}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

public static void main(String args[]){

new TitleScreen();}

}

WOW thanks guys i really aprceate it!

slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...
# 13
Aww ****, I just discovered that the more images i draw at one time the slower and crapper the animation gets. i got 2 images being drawn and the smoothness just went back to jerky, ****
slickida at 2007-7-14 21:02:09 > top of Java-index,Other Topics,Java Game Development...