Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


problem with java buffered image


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 Donal Byrne   Members   -  Reputation: 150

Like
0Likes
Like

Posted 11 June 2014 - 12:57 PM

I am trying to increase performance with buffered images. I have made a game loop that has increased my fps but i also want buffered images, however these aren't working.

 

its supposed to show a black background and print the amount of ticks and fps in the console

package game3;

import java.awt.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.image.*;
import java.util.logging.*;
import java.util.logging.*;
import javax.swing.*;

/**,
 *
 * @author djb
 */
public class Game extends Canvas implements Runnable{
    
    private boolean running = false;
    private Thread thread;
    
    private BufferedImage image = new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
    
    private synchronized void start()
    {
        if(running)
            return;
        
        running = true;
        thread = new Thread(this);
        thread.start();
    }
    
    private synchronized void stop()
    {
        if(!running)
            return;
        
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.exit(1);
    }
    
    
    
    public void run() 
    { //game loop
        long lastTime = System.nanoTime();
        final double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        int updates = 0;
        int frames = 0;
        long timer = System.currentTimeMillis();
        
        while(running)
        {
            //game loop
          long now = System.nanoTime();
          delta+=(now - lastTime)/ns;
          lastTime = now;
          if(delta >= 1)
          {
              tick();
              updates++;
              delta--;
          }
          render();
          frames++;
          
          if(System.currentTimeMillis() - timer > 1000)
          {
              timer  += 1000;
              System.out.println(updates + "ticks, Fps " + frames);
              updates = 0;
              frames = 0;
          } 
          
        }
        stop();
        
    }
    
    private void tick()
    {
        
    }
    
    private void render()
    {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null)
        {
            createBufferStrategy(3);
            return;
        }
        
        Graphics g = bs.getDrawGraphics();
        //put objects between here and dispose to draw stuff
        
        g.drawImage(image, 0, 0, 630, 480, this);
        
       g.dispose();
        bs.show();
        
        
        
    }
    
    public static void main(String[]args)
    {
        
        Game game = new Game();
        
        JFrame frame = new JFrame();
        frame.pack();
        frame.setSize(640,480);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        game.start();
        
        
    }

    
    
}

could really use some help, thanks



Sponsor:

#2 Avalander   Members   -  Reputation: 1080

Like
1Likes
Like

Posted 11 June 2014 - 01:30 PM

You need to add your canvas object to the JFrame. Just add the following line to your main, after instantiating the JFrame:

frame.add(game);

I don't mean to be rude, but when you ask for help with a crashing program, you should post the error stack trace. And if you had googled for "java canvas java.lang.IllegalStateException: Component must have a valid peer" you wouldn't even had need to ask. I just say so the next time you can solve your problem faster.


Edited by Avalander, 11 June 2014 - 01:36 PM.


#3 Donal Byrne   Members   -  Reputation: 150

Like
0Likes
Like

Posted 11 June 2014 - 01:52 PM

Yeah that sorted it out. Im such a idiot!

 

Yeah that makes sense, sorry about that. won't happen again.

 

Thanks a lot 



#4 Donal Byrne   Members   -  Reputation: 150

Like
0Likes
Like

Posted 11 June 2014 - 03:58 PM

ok so I got the image on the screen and did key inputs, but instead of moving cleanly it leaves behind a trail of the image. 

Its like its just cloning itself instead of moving.

 

It has to be something to do with the loop right?

package game3;

import java.awt.*;
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.*;
import java.io.IOException;
import java.util.logging.*;
import java.util.logging.*;
import javax.swing.*;

/**,
 *
 * @author djb
 */
public class Game extends Canvas implements Runnable{
    
    //Player p;
    
    private boolean running = false;
    private Thread thread;
    
    BufferedImage player = null;
    
    int speed = 2;
    
    private Player p;
    
    public void init() 
    {
        
        BufferedImageLoader loader = new BufferedImageLoader();
        try{
            player = loader.loadImage("/images/p1Up.png");
        }catch(IOException e)
        {
            e.printStackTrace();
        }
        
        addKeyListener(new KeyInput(this));
        this.requestFocus();
        p = new Player(200,200,this);
    }
    
    private synchronized void start()
    {
        if(running)
            return;
        
        running = true;
        thread = new Thread(this);
        thread.start();
    }
    
    private synchronized void stop()
    {
        if(!running)
            return;
        
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.exit(1);
    }
    
    
    
    public void run() 
    { //game loop
        init();
        long lastTime = System.nanoTime();
        final double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        int updates = 0;
        int frames = 0;
        long timer = System.currentTimeMillis();
        
        while(running)
        {
            //game loop
          long now = System.nanoTime();
          delta+=(now - lastTime)/ns;
          lastTime = now;
          if(delta >= 1)
          {
              tick();
              updates++;
              delta--;
          }
          
          render();
          frames++;
         
          
          if(System.currentTimeMillis() - timer > 1000)
          {
              timer  += 1000;
              System.out.println(updates + "ticks, Fps " + frames);
              updates = 0;
              frames = 0;
              
          } 
          
        }
        stop();
        
    }
    
    private void tick()
    {
        p.tick();
        
    }
    
    private void render()
    {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null)
        {
            createBufferStrategy(1);
            return;
        }
        
        Graphics g = bs.getDrawGraphics();
        //put objects between here and dispose to draw stuff
        
        
        
        //g.drawImage(player, 100, 100,32 ,32, this);
        
        p.render(g);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        g.dispose();
        bs.show();      
        
    }
    
     public void keyPressed(KeyEvent e)
     {
         int key = e.getKeyCode();
         
         if(key==KeyEvent.VK_RIGHT){
             
             p.setX(p.getX() + 5*speed);
             
         }else if(key==KeyEvent.VK_LEFT){
             
             p.setX(p.getX() - 5*speed);
             
             
         }else if(key==KeyEvent.VK_UP){
             
             p.setY(p.getY() - 5*speed);
             
         }
         else if(key==KeyEvent.VK_DOWN){
             
            p.setY(p.getY() + 5*speed);
             
         }
     }
      public void keyReleased(KeyEvent e)
      {
          
      }
   
    
    public static void main(String[]args)
    {
        
        Game game = new Game();
        
        JFrame frame = new JFrame();
        frame.pack();
        frame.setSize(640,480);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(game);
        
        game.setFocusable(true);
        
        game.start();
        
        
    }

    

    
    
}



#5 frob   Moderators   -  Reputation: 22779

Like
1Likes
Like

Posted 11 June 2014 - 06:55 PM

Mostly as an FYI before you get too far down this path...


BufferedImage (and several other image classes) have the annoying habit of being really bad for performance in games.

While they are sometimes accelerated, sometimes they are not. Even more annoyingly, the system can spontaneously decide to switch from hardware accelerated to software rendering for reasons your program is not told. Just suddenly *poof*, it changes from a jet flying through the sky in performance to a jet flying through jello, mucking along at a terrible pace.

Some operations are known to cause the problem (such as reading from images) but other times it switches mode from things like windows getting resized (even other windows, necessarily not yours) or from other windows getting rendering contexts, but it also happens for a bunch of reasons that people just guess at.

Google for BufferedImage performance problems. Java's inconsistent use of hardware acceleration for graphics is a big reason for moving to libraries that guarantee hardware acceleration.

If your game doesn't need the performance, that is fine. But if you want to develop something where you need framerate performance counters, better for you to learn up front that the built-in rendering system unfortunately will not cut it.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#6 Avalander   Members   -  Reputation: 1080

Like
1Likes
Like

Posted 12 June 2014 - 04:32 AM

I guess that what you are doing is to draw the player in his actual position every frame, but you are not erasing him from his last position, so you are actually drawing each frame in the top of the previous one. That's why the image is leaving trails.

 

The easiest way to solve this is to redraw the whole background at the begining of the render function, so you'll start each frame with an empty background instead of the previous frame.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS