BufferedImage w Javie - program na zaliczenie semestru.

0

Cześć, kończę drugi semestr IT i potrzebuję napisać program na zaliczenie jednego z przedmiotów. Temat, który wylosowałem to symulator samochodu. Program ma być oczywiście w okienku.
Mój problem pojawia się w momencie pokazywania czegoś na ekranie. Od jakiegoś czasu próbuje ogarnąć o co chodzi, głównie chodzi o to:

private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

public void render() {
        Graphics2D g = (Graphics2D) image.getGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(10, 10, 100, 100);
        g.dispose();
}

Nie mam pojęcia dlaczego miałoby to nie działać, cały kod można obejrzeć tutaj

0

Może to wina tego, że szybko przejrzałem, ale nie widzę nigdzie w kodzie abyś używał metody render().

0

Okej, a więc tak chciałbym osiągnąć coś takiego, że, Main jest głównym plikiem odpalającym cały program. Simulator ma być klasą, która implementuje Runnable tj. na bieżąco sprawdza, renderuje oraz updatuje mi to co znajduje się w JPanelu, który jest przypisany do JFrame w klasie Window. Z tego co teraz zauważyłem kompletnie nie działa to:

if(System.currentTimeMillis() - fpsTimer > 1000) {
            System.out.printf("%d FPS", fps);
            System.out.println();

            fps = 0;
            updates = 0;
            fpsTimer += 1000;
        }

Czyli, w którymś momencie metody run musi coś wywalać.
Całość będzie się opierała na kilku grafikach, które będą się co klatkę odświeżać w JPanelu, tj. będę wyświetlał prędkość, biegi itd.

0
Zevcore napisał(a):

Z tego co teraz zauważyłem kompletnie nie działa to:

if(System.currentTimeMillis() - fpsTimer > 1000) {
            System.out.printf("%d FPS", fps);
            System.out.println();

            fps = 0;
            updates = 0;
            fpsTimer += 1000;
        }

Skoro w metodzie run, przed tym kawałkiem kodu co wstawiłeś tutaj, jest pętla while(true), to ten kawałek kodu się nie wykonuje. A pętla jest wieczna, bo nigdzie nie wywołałeś Simulator.stop().

0

Skróciłem trochę ten kod i zamiast JPanelu użyłem Canvasa, niestety efekt ten sam, dalej nic nie wyświetla:

Klasa główna (Container):

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

public class Container extends JFrame implements Runnable {

    /* Ustawienia okna */
    private final String title = "Sim";
    private final int width = 1280;
    private final int height = 720; // hd res

    /* Zawartość okna */
    private Screen screen;

    /* Ustawienia Runnable */
    private boolean running;
    private Thread thread;
    private int frames;
    private int updates;

    public Container() {


        /* Utworzenie okna */
        setTitle(title);
        setPreferredSize(new Dimension(width, height)); // -------- //
        setMinimumSize(new Dimension(width, height));   // Rozmiary //
        setMaximumSize(new Dimension(width, height));   // -------- //

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.WHITE);
        setLocationRelativeTo(null);
        setResizable(false);

        /* Dodanie zawartości do okna */
        pack();
        setVisible(true);


    }

    public synchronized void start() {
        running = true;

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

    public synchronized void stop() {
        running = false;

        System.exit(0);
    }

    public void init() {
        screen = new Screen(width, height);
        add(screen);
    }

    public void update() {

    }

    public void render() {
        Graphics2D g = screen.getG();
        g.setColor(Color.black);
        g.fillRect(10, 10, 100, 100);
    }

    @Override
    public void run() {
        long x = System.nanoTime();
        long y = System.currentTimeMillis();

        double ns = 1000000000D / 60D;
        double delta = 0; // Unprocessed

        int updates = 0;
        int frames = 0;

        init();

        while(running) {
            long now = System.nanoTime();
            delta += (now - x) / ns;
            x = now;

            boolean shouldRender = true;
            while(delta >= 1) {
                updates++;
                update();
                delta -= 1;
                shouldRender = true;
            }

            try {
                Thread.sleep(1);
            } catch(Exception e) {
                e.printStackTrace();
            }

            if(shouldRender) {
                frames++;
                render();

                //Pokaż fpsy
                if(this.frames != 0) {
                    System.out.printf("%d FPS \n", this.frames);
                }
            }

            if(System.currentTimeMillis() - y >= 1000) {
                y += 1000;
                this.frames = frames;
                this.updates = updates;


                frames = 0;
                updates = 0;
            }
        }
    }

    public static void main(String[] args) {
        new Container().start();
    }

}

oraz klasa Screen:

import java.awt.*;
import java.awt.image.BufferedImage;

public class Screen extends Canvas {

    private BufferedImage content;
    private Graphics2D g;

    public Screen(int width, int height) {
        setSize(new Dimension(width, height));
        content = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        g = (Graphics2D) content.getGraphics();
    }

    public Graphics2D getG() {
        return g;
    }
}

1

Rozwiązałem ten problem, jedyne czego potrzebowałem to BufferStrategy

bs = screen.getBufferStrategy();
        if(bs == null) {
            screen.createBufferStrategy(3);
            return;
        }

        g = bs.getDrawGraphics();

1 użytkowników online, w tym zalogowanych: 0, gości: 1