Kaloyan Drenski
Kaloyan Drenski

Reputation: 1076

Java flashing graphic

I am reading programming video games for the evil genius, and i am using its code. It compiles well, but the problem is that my graphic is flashing.

import java.awt.*;
import javax.swing.*;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author kaldren
 */
public class MyGame extends JFrame {

    final int WIDTH = 900, HEIGHT = 650;

    double p1Speed = .5, p2Speed = .5;

    Rectangle left = new Rectangle(0, 0, WIDTH / 9, HEIGHT);
    Rectangle right = new Rectangle((WIDTH / 9) * 9, 0, WIDTH / 9, HEIGHT);
    Rectangle top = new Rectangle(0, 0, WIDTH, HEIGHT / 9);
    Rectangle bottom = new Rectangle(0, (HEIGHT / 9) * 9, WIDTH, HEIGHT / 9);
    Rectangle center = new Rectangle((int) ((WIDTH / 9) * 2.5), (int)
            ((HEIGHT / 9) * 2.5), (int) ((WIDTH / 9) * 5), (HEIGHT / 9) * 4);
    Rectangle obstacle = new Rectangle(WIDTH / 2, (int) ((HEIGHT / 9) * 7), WIDTH / 10, HEIGHT / 9);
    Rectangle obstacle2 = new Rectangle(WIDTH / 3, (int) ((HEIGHT / 9) * 5), WIDTH / 10, HEIGHT / 4);
    Rectangle obstacle3 = new Rectangle(2 * (WIDTH / 3), (int) ((HEIGHT / 9) * 5), WIDTH / 10, HEIGHT / 4);
    Rectangle obstacle4 = new Rectangle(WIDTH / 3, HEIGHT / 9, WIDTH / 30, HEIGHT / 9);
    Rectangle obstacle5 = new Rectangle(WIDTH / 2, (int) ((HEIGHT / 9) * 1.5), WIDTH / 30, HEIGHT / 4);

    Rectangle finish = new Rectangle(WIDTH / 9, (HEIGHT / 2) - HEIGHT / 9, (int) ((WIDTH / 9) * 1.5), HEIGHT / 70);

    Rectangle p1 = new Rectangle(WIDTH / 9, HEIGHT / 2, WIDTH / 30, WIDTH / 30);
    Rectangle p2 = new Rectangle(((WIDTH / 9) + ((int) ((WIDTH / 9) * 1.5) / 2)), (HEIGHT / 2) + (HEIGHT / 10),
            WIDTH / 30, WIDTH / 30);

    public MyGame() {
        super("Radical Racing");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        Move1 m1 = new Move1();
        Move2 m2 = new Move2();
        m1.start();
        m2.start();
    }

    public void paint(Graphics g)
    {
        super.paint(g);

        g.setColor(Color.DARK_GRAY);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        g.setColor(Color.GREEN);

        Rectangle line0 = new Rectangle(WIDTH / 9, HEIGHT / 2, (int) ((WIDTH / 9) * 1.5) / 2, HEIGHT / 140);
        Rectangle line1 = new Rectangle(((WIDTH / 9) + ((int) ((WIDTH / 9) * 1.5) / 2)), (HEIGHT / 2) + 
            (HEIGHT / 10), (int) ((WIDTH / 9) * 1.5) / 2, HEIGHT / 140);


        g.fillRect(left.x, left.y, left.width, left.height);
        g.fillRect(right.x, right.y, right.width, right.height);
        g.fillRect(top.x, top.y, top.width, top.height);
        g.fillRect(bottom.x, bottom.y, bottom.width, bottom.height);
        g.fillRect(center.x, center.y, center.width, center.height);
        g.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
        g.fillRect(obstacle2.x, obstacle2.y, obstacle2.width, obstacle2.height);
        g.fillRect(obstacle3.x, obstacle3.y, obstacle3.width, obstacle3.height);
        g.fillRect(obstacle4.x, obstacle4.y, obstacle4.width, obstacle4.height);
        g.fillRect(obstacle5.x, obstacle5.y, obstacle5.width, obstacle5.height);

        g.setColor(Color.WHITE);

        g.fillRect(line0.x, line0.y, line0.width, line0.height);
        g.fillRect(line1.x, line1.y, line1.width, line1.height);

        g.setColor(Color.YELLOW);

        g.fillRect(finish.x, finish.y, finish.width, finish.height);

        g.setColor(Color.BLUE);
        g.fill3DRect(p1.x, p1.y, p1.width, p1.height, true);

        g.setColor(Color.RED);
        g.fill3DRect(p2.x, p2.y, p2.width, p2.height, true);

    }

    public class Move1 extends Thread {

        public void run() {
            while (true) {
                try {
                    repaint();
                    if (p1Speed <= 5) 
                        p1Speed += .2;

                    p1.y -= p1Speed;

                    Thread.sleep(75);
                } catch (Exception e) {
                    break;
                }
            }
        }
    }

    public class Move2 extends Thread
    {
        public void run()
        {
            while(true)
            {
                try 
                {
                    repaint();
                    if(p2Speed <= 5)
                        p2Speed+=.2;

                        p2.y-=p2Speed;

                        Thread.sleep(75);

                } catch (Exception e) {break;}
            }
        }
    }


    public static void main(String[] args) {
        new MyGame();
    }
}

Upvotes: 0

Views: 466

Answers (2)

Paul Samsotha
Paul Samsotha

Reputation: 209102

1) Stay away from Thread.sleep()s and while(true)s in Swing apps. Use a Swing Timer. See How to Use Swing Timers. Also see examples here and here and here and here and here

2) Don't paint on top-level containers like JFrame cause they already do the heavy lifting of painting component and they aren't double buffered. Instead paint on JPanel/JComponent and override paintComponent and call super.paintComponent, not paint

3) Run Swing apps from the Event Dispatch Thread (EDT). You can do so by wrapping your new MyGame() in a SwingUtilities.invokeLater.... See Initial Threads for more details.

4) For multiple objects/shapes you want to draw, you should take an OOP approach, as seen in this example and most the other example above using Timers.

Upvotes: 4

PlasmaPower
PlasmaPower

Reputation: 1878

You will need to double buffer your JFrame, insert the following into your paint method:

BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();

//Paint using g2d instead of g, example g2d.fillRect(0, 0, 1, 1);

Graphics2D g2dComponent = (Graphics2D) g;
g2dComponent.drawImage(bufferedImage, null, 0, 0);  

Upvotes: 1

Related Questions