1
\$\begingroup\$

I'm currently working on a 2D Java Game. When I start the game everything works fine with a constant framerate. When I'm using normal graphics methods to draw shapes nothing happens. But as soon as I draw images (BufferedImages) they start to randomly flashing white.

I've already removed every single line of my code that might have cause any performance issues. All that I'm currently using is:

Launcher (main) class:

public class Launcher 
{
    public static void main(String[] args)
    {
        new Engine().run();
    }
}

Engine class:

public class Engine implements Runnable
{
    private static final String TITLE = "My Game";
    private static final int WIDTH = 1280;
    private static final int HEIGHT = WIDTH / 16 * 9;

    private static final int MAX_BUFFER_STRATEGY = 3;

    private static Engine instance;

    private static boolean isRunning;
    private Thread thread;

    private BufferedImage image1 = Utils.Images.load("/symbol1.png");
    private BufferedImage image2 = Utils.Images.load("/symbol2.png");

    public Engine()
    {
        instance = this;

        new Display(TITLE, WIDTH, HEIGHT);

        run();
    }

    private void tick()
    {

    }

    private void draw()
    {
        BufferStrategy strategy = Display.get().getCanvas().getBufferStrategy();

        if(strategy == null)
        {
            Display.get().getCanvas().createBufferStrategy(MAX_BUFFER_STRATEGY);
            return;
        }

        Graphics graphics = strategy.getDrawGraphics();

        graphics.clearRect(0, 0, Display.get().getWidth(), Display.get().getHeight());

//      graphics.drawImage(image1, 100, 100, 200, 200, null);
//      graphics.drawImage(image2, 200, 200, 200, 200, null);

        strategy.show();

        graphics.dispose();
    }

    @Override
    public void run() 
    {
        start();

        while(isRunning)
        {   
            Time.calculate();

            try
            {
                Thread.sleep(20);
            }
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }

            while(Time.tick())
            {
                tick();
            }

            while(Time.draw())
            {
                draw();
            }
        }
    }

    public synchronized void start()
    {
        if(!isRunning)
        {
            isRunning = true;

            thread = new Thread(this);
            thread.start();
        }
    }

    public synchronized void stop()
    {
        if(isRunning)
        {
            isRunning = false;

            try
            {
                thread.join();
            }
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
    }

    public static void destroy()
    {
        instance.stop();

        try
        {
            Thread.sleep(250);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        System.exit(-1);
    }
}

Display class:

public class Display extends Canvas
{
    private static final long serialVersionUID = 1L;

    private static Display instance;

    private JFrame jFrame;

    public Display(String title, int w, int h)
    {
        defaults(title, new Dimension(w, h));

        instance = this;
    }

    private void defaults(String title, Dimension dimension)
    {   
        setPreferredSize(dimension);
        setMinimumSize(dimension);
        setMaximumSize(dimension);

        jFrame = new JFrame();

        jFrame.setTitle(title);
        jFrame.setSize(dimension);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setResizable(false);
        jFrame.setLocationRelativeTo(null);
        jFrame.setIgnoreRepaint(true);

        jFrame.setVisible(true);

        jFrame.add(this);
        jFrame.pack();
    }

    public Canvas getCanvas()
    {
        return this;
    }

    public JFrame getJFrame()
    {
        return jFrame;
    }

    public static Display get()
    {
        return instance;
    }
}

Time class:

public class Time 
{
    private static final int TIME_COUNTS = 2;

    private static final int FPS = 60;
    private static final double TIME_PER_TICK = 1000000000 / FPS;

    private static double[] lastTime = new double[TIME_COUNTS];
    private static double[] deltaTime = new double[TIME_COUNTS];
    private static double[] time = new double[TIME_COUNTS];

    public static void init()
    {
        lastTime[0] = System.nanoTime();
        lastTime[1] = System.nanoTime();
    }

    public static void calculate()
    {
        for(int i = 0; i < TIME_COUNTS; i++)
        {
            time[i] = System.nanoTime();
            deltaTime[i] += (time[i] - lastTime[i]) / TIME_PER_TICK;
            lastTime[i] = time[i];
        }
    }

    public static boolean tick()
    {
        if(deltaTime[0] >= 1)
        {
            deltaTime[0]--;
            return true;
        }
        return false;
    }

    public static boolean draw()
    {
        if(deltaTime[1] >= 1)
        {
            deltaTime[1]--;
            return true;
        }
        return false;
    }
}

Utils class:

public class Utils 
{
    public static class Images
    {
        public static BufferedImage load(String path)
        {
            try 
            {
                return ImageIO.read(Images.class.getResource(path));
            }     
            catch (IOException e) 
            {
                e.printStackTrace();
            }
            return null;
        }
    }
}

I hope someone knows what I'm doing wrong and may have a clue how to help.

\$\endgroup\$
  • \$\begingroup\$ This could be solved a lot faster with an SSCCE \$\endgroup\$ – Shaun Wild Jul 4 '16 at 9:42
  • \$\begingroup\$ I'm sorry for not having that done before. I'm new to this Forum. If i unterstand correctly SSCCE means i should edit the code that way that it can simply be used to test with the minimum and that it shows the Problem? I'll do that as soon as i can. In about an Hour. I hope it'll help to solve the problem \$\endgroup\$ – FlaverBeat Jul 4 '16 at 10:50
  • \$\begingroup\$ I've now changed the code above. Just copying it should be enough. The flashing is not frequently, so you have to wait until it happens (at least it's how it's for me). \$\endgroup\$ – FlaverBeat Jul 4 '16 at 12:21
0
\$\begingroup\$

In your Main you create an Engine object an Call run() on it. But in the constructor you also Call run.

Could it be that you have two Threads where you want only one ?

\$\endgroup\$
  • \$\begingroup\$ No, that second run() was just my mistake in the example BUT you gave me a good idea. I do create two threads and that was the problem! If you look into the code, i create a new thread of the instance that already exists and start that too. I now rewrote it so, that the Launcher class uses the start() method which creates a thread which starts the run(). It seems that the flashing is now gone. Thank you very much! \$\endgroup\$ – FlaverBeat Jul 5 '16 at 12:35
0
\$\begingroup\$

Try changing the value of MAX_BUFFER_STRATEGY to 2, it sounds to be like there isn't a doubble buffer on the code, if nto comment below the rest of the code, and i will have a mess around with it later on, or might be able to see something else.

\$\endgroup\$
  • \$\begingroup\$ It's currently on 3 and i tried 2. No visual change at all. \$\endgroup\$ – FlaverBeat Jul 3 '16 at 19:45
  • \$\begingroup\$ hmmm, pastebin me all your code,I'll go through it see if can't work it out quick, from what you've pasted doesn't look like theres anything wrong. \$\endgroup\$ – jordy2254 Jul 3 '16 at 20:06
  • \$\begingroup\$ That IS all. The only thing missing are the variables and the Time class which is just the time maths exported into another class. I've edited the post. Now you can see everything that I'm currently using. \$\endgroup\$ – FlaverBeat Jul 3 '16 at 20:08
  • \$\begingroup\$ Change the strategy.show(); graphics.dispose(); around to be the other way around that mnay be causing it. if not may be a Time issue \$\endgroup\$ – jordy2254 Jul 3 '16 at 20:11
  • \$\begingroup\$ Already tried that. That makes absolutely no difference. And the time class should be fine, because i already wrote it directly into the loop from something i found online to limit the ticks but it didnt change a thing. \$\endgroup\$ – FlaverBeat Jul 3 '16 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.