Forum zamknięte. Zapraszamy do grupy na Facebooku
Odpowiedz 
 
Ocena wątku:
  • 1 Głosów - 5 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
Problem z powtarzaniem wykonywania programu
07-03-2014, 10:39 AM
Post: #1
Problem z powtarzaniem wykonywania programu
Witam!
Piszę właśnie pierwszy program graficzny "Snake" i napotkałem na problem z powtarzaniem programu. Program po włączeniu wykonuje się nie wiedzieć czemu 2 razy?!, a chciałbym aby powtarzał się do czasu wyłączenia programu. Oto mój tekst źródłowy (na razie bez obsługi klawiatury, tylko poruszający się w prawo wąż):

Kod:
import java.awt.EventQueue;

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Window();
            }
        });
    }
}

Kod:
import javax.swing.JPanel;
import javax.swing.JFrame;

public class Window extends JFrame{
    public Window() {
        super("Snake");
        
        JPanel area = new Area();
        
        add(area);
        pack();
        
        setLocation(400, 250);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }
}

Kod:
import java.awt.*;
import java.awt.geom.*;

import javax.swing.JPanel;

import java.util.List;
import java.util.ArrayList;

public class Area extends JPanel {
    
    private int[][] area = new int[50][30];
    private boolean isFirst = true;
    private List<Integer> snakePoz = new ArrayList<Integer>();
    private int turnSnake = 0;
    
    public Area() {
        setPreferredSize(new Dimension(501, 301));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        Rectangle2D rectangle = new Rectangle2D.Double(0, 0, 500, 300);
        
        g2d.draw(rectangle);
        
        snake();
        madeArea();
        
        Ellipse2D snakeDraw;
        
        for(int i = 0; i < 50; i++){
            for(int j = 0; j < 30; j++) {
                switch(area[i][j]) {
                    case 0:
                        break;
                    case 1:
                        snakeDraw = new Ellipse2D.Double( i * 10, j * 10, 10, 10);
                        g2d.fill(snakeDraw);
                }
            }
        }
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    private void snake() {
        if(!isFirst) {
            for(int i = snakePoz.size() - 1; i > 0; i-- ) {
                snakePoz.set(i, snakePoz.get(i - 1));
            }
            switch(turnSnake) {
                case 0:
                    snakePoz.set(0, snakePoz.get(1) + 100);
                    break;
                case 1:
                    snakePoz.set(0, snakePoz.get(1) - 1);
                    break;
                case 2:
                    snakePoz.set(0, snakePoz.get(1) - 100);
                    break;
                case 3:
                    snakePoz.set(0, snakePoz.get(1) + 1);
            }
        } else {
            snakePoz.add(2615);
            snakePoz.add(2515);
            snakePoz.add(2415);
            isFirst = false;
        }
        
        int x = 1;
        System.out.println("wykonanie: " + x);
    }
    
    private void madeArea() {
        
        int i, j;
        
        for(i = 0; i < 50; i++) {
            for(j = 0; j < 30; j++) {
                area[i][j] = 0;
            }
        }
        
        int wartosc;
        int x;
        int y;
        
        for(i = 0; i < snakePoz.size(); i++) {
            wartosc = snakePoz.get(i);
            x = (int) wartosc / 100;
            y = (int) wartosc - x * 100;
            area[x][y] = 1;
        }
    }
}

Nie wiem co jest źle i jakoś nie potrafię znaleźć w tym błędu, może jakiś MainLoop na końcu jak w OpenGL'u?

I jeśli ma to jakieś znaczenie dodam, że piszę na Linuxie CruchBang (#!).
Znajdź wszystkie posty użytkownika
Odpowiedz cytując ten post
07-03-2014, 06:08 PM
Post: #2
RE: Problem z powtarzaniem wykonywania programu
1. To usuń tego sleepa z paintComponent(Graphics g);
2. Musisz jakoś odświeżać ten interfejs, sam z siebie tego raczej nie będzie robił.

GG: 2802571
Znajdź wszystkie posty użytkownika
Odpowiedz cytując ten post
07-03-2014, 08:10 PM
Post: #3
RE: Problem z powtarzaniem wykonywania programu
Próbowałem użyć repaint() na końcu konstruktora klasy Window ale nic to nie daje, a jak wsadzę go w fora to w ogóle nic mi nie rysuje - tylko okienko się otwiera.
Usunięcie sleep()'a też nie pomaga, a poza tym bez niego cały program byłby bez sensu.
Głównie chodzi o to że program wykonuje się raz raz, raz dwa (a kilka razy po dodaniu repaint() nawet trzy), a ja chciałbym zrozumieć co się w nim dzieje (żebym wiedział co naprawić).
I jeszcze metoda repaint() mnie zastanawia, bo nie za bardzo wiem jak ją użyć. Może mógłbym dostać jakiś link, albo wskazówkę jak szukać czegoś o tej metodzie (nie mam nic przeciwko żeby było to po angielsku)?

Przepraszam za mało zrozumiałą składnie wypowiedzi, ale nie wiem jak to inaczej krótko opisać.
Znajdź wszystkie posty użytkownika
Odpowiedz cytując ten post
07-03-2014, 09:28 PM (Ten post był ostatnio modyfikowany: 07-03-2014 09:30 PM przez lolo.)
Post: #4
RE: Problem z powtarzaniem wykonywania programu
Dlaczego uważasz, że bez sleepa na końcu paintComponent(Graphics g); program będzie bez sensu? Nie masz po uruchomieniu czegoś takiego, że okno przez 1s jest czarne/puste?
Chciałem zasugerować byś spróbował minimalizować i przywracać okno to wtedy powinno to być widoczne ale na linuksie chyba to nie działa (ale możesz spróbować) jak byłem zalogowany na Windowsa to mogłem to zauważyć. Przy każdym przywróceniu była wywoływana automatycznie metoda repaint() i można było to zaobserwować te 1s przywiechy w budowaniu okna tzn. po przywróceniu było ono przez 1s czarne i dopiero wtedy pojawiał się snake.

O repait() możesz przeczytać np. TU
Ta metoda nie przebudowuje interfejsu od razu po wywołaniu tylko sugeruje JFrame, że powinien to zrobić.
Program wywołuje się tylko kilka razy bo nic nie wywołuje paintComponent(Graphics g) która przebudowywuje interfejs i aktualizuje w twoim przypadku położenie snake.

Proponuję zainteresować się klasą Timer.

GG: 2802571
Znajdź wszystkie posty użytkownika
Odpowiedz cytując ten post
Odpowiedz 


Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości