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]

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)
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?
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.
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
Do you really want to be using Swing for a game?
Well.... yes, why not? I dont see anything wrong with using swing?what would you perfer?
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 >

> 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);
}
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).
continued from above....Now you can use image2 in your draw method WITHOUT reacreating the image every iteration of draw().
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?
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!
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, ****