Wielowątkowość, na przykładzie prostej animacji.

Odpowiedz Nowy wątek
2013-11-23 20:05

Rejestracja: 6 lat temu

Ostatnio: 3 lata temu

0

Cześć,
mam do napisania program, w którym przetestuję działanie wielowątkowości, sęk w tym, że nie wiem nawet od czego zacząć i jak się za to zabrać. Dodatkowo mamy korzystać z pluginu SwingDesigner (Window Builder). Oto założenia programu:

  • posiada 4 klasy (wątki): Lis, Kura, Świat, Run,
  • Lis porusza się po planszy i szuka w swoim otoczeniu jajka, które składa kura. Jeśli nie ma jajka w jego najbliższym otoczeniu to idzie w jednym z 4 kierunków losowo,
  • Kura - chodzi po planszy w dowolnym kierunku i składa jajka w losowych momentach czasu
  • Świat - postarza jajka, jeśli jajko ma więcej niż 10 lat i lis je zje to znika z planszy, po 30 latach jajko znika z planszy,
  • Szybkość mijającego roku ma być możliwe do zmiany w okienku programu, za pomocą np. suwaka,
  • Synchronizacja wątków (przez 'synchronize'):
    • Lis i Kura nie mogą wejść na to samo pole w tym samym czasie,
    • Kura nie może złożyć jajka na innym jajku,
  • Plansza ma mieć wymiary m x m,
  • Rysowanie ma się odbywać na ramce,
  • Kury, Lisy, Jajka mogą być na planszy reprezentowane dowolnie, tzn. np. za pomocą literek lub 'kwadracików' o różnych kolorach.

Bardzo, potrzebuję pomocy z tym zadaniem, tak naprawdę to nie wiem jeszcze nic, więc chciałbym się od Was dowiedzieć o czym muszę poczytać. Najchętniej zobaczyłbym jakieś przykłady podobnych programów, żeby mieć na czym się wzorować i w ogóle każda pomoc jest tutaj mile widziana.

Z góry dziękuję za każda odpowiedź.
Pozdrawiam.

Pozostało 580 znaków

2013-11-23 20:19

Rejestracja: 6 lat temu

Ostatnio: 1 rok temu

0

Moje umiejetnosci niestety nie pozwalaja jeszcze na fachowe rady ale moze tutaj znajdziesz cos pomocnego, mowi on troche o watkach, timerze, kolizji obiektow itp. :)

https://www.youtube.com/playl[...]TfBNZ98eOOCk2fOFg7Qg5yoQfFAdf

Pozostało 580 znaków

2013-11-24 13:22

Rejestracja: 7 lat temu

Ostatnio: 5 lat temu

1

Proponuję zacząć od obczajenia wielowątkowości - interfejs Runnable i klasa Thread, oraz nauki rysowania w Swing. Od razu, rada na przyszłość - oddzielaj mechanizm działania / funkcjonalność programu od GUI. Najlepiej żeby cała wizualizacja była w formie osobnej klasy rysującej - np. dziedziczącej po JPanel albo Canvas i tylko otrzymywała lub sczytywała aktualne dane do odrysowania.


Pozostało 580 znaków

2013-11-24 14:37

Rejestracja: 6 lat temu

Ostatnio: 3 lata temu

0

Dziękuję za obie odpowiedzi. A czy wiecie gdzie mógłbym podpatrzeć jakieś podobne programy, tak aby mieć z czego czerpać inspirację?

Teraz nie mam czasu ale jak chcesz to Ci mogę przesłać fragment kodu z jakiegoś mojego starego projektu, gdzie była animacja kulki - tj. kulka wędrowała tam gdzie się kliknęło :P. Jak jesteś zainteresowany to napisz PW, to jakoś wieczorem Ci podeślę. - Qbisiek 2013-11-24 15:48

Pozostało 580 znaków

2013-11-24 21:25
Moderator

Rejestracja: 6 lat temu

Ostatnio: 1 rok temu

0

http://www.pitt.edu/~marchegi/JavaProg/BounceBall.java

Tutaj masz kod programu ze skaczacymi pileczkami gdzie kazda kolejna jest nowym watkiem, mysle ze moze byc przydatne:)

Pozostało 580 znaków

kszychu
2013-11-24 22:05
kszychu
0

Musisz wymyslic sposob "reprezentacji" (model) poszczegolnych pol na mapie. Moze to byc np. lista obiektów typu Field - obiekty te
będą zawierać koordynaty pola, które reprezentują oraz jego stan (czy zawiera jajka, kto znajduje sie na polu itp.). Wiadomo, że
kura, świat i lis to będą osobne wątki, które będą "współdzielić" między sobą listę tych obiektów - więc musisz się postarać żeby
operacje na obiektach tej listy były zsynchronizowane, bo inaczej pojawią się różne nieciekawe problemy związane z wielowątkowością :)

Pozostało 580 znaków

2013-11-24 22:11

Rejestracja: 6 lat temu

Ostatnio: 3 lata temu

0

Naprawdę bardzo wszystkim dziękuję za odpowiedzi :) W miarę możliwości czasowych w zacznę pisać ten program i jak tylko natrafię na jakieś problemy to na pewno jeszcze napiszę :)
Jeszcze raz dziękuję i pozdrawiam :)

Pozostało 580 znaków

2013-11-28 17:31

Rejestracja: 6 lat temu

Ostatnio: 3 lata temu

0

Ok, więc dopiero zaczynam z moim programem i chciałem przetestować działanie Timera i już natrafiłem na błąd, którego nie mogę przeskoczyć. Chciałem narysować kwadrat i sprawić aby się po prostu poruszał, byle jak i napisałem coś takiego:
Klasa zadanie:

import java.util.TimerTask;

public class Zadanie extends TimerTask
{
    int poz1 = 0;
    int poz2 = 0;

    @Override
    public void run(){
        poz1++;
        poz2++;

        Ramka.ramka.repaint();    
    }
}

Klasa Ramka:

package lab04_pop;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Timer;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Ramka extends JFrame {
    Zadanie zadanie = new Zadanie();
    Timer timer = new Timer();
    static JFrame ramka;

    public Ramka (){
        setSize (600, 400);
        setTitle ("Plansza");

        timer.scheduleAtFixedRate (zadanie, 10, 10);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
}

    public void paint (Graphics g){
        g.setColor (Color.RED);
        g.fillRect (zadanie.poz1, zadanie.poz2, 100, 100);

    }

public static void main (String[] args){
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new Ramka();
        }
    });
}
}

Jest ktoś w stanie mi powiedzieć co robię źle? Eclipse mi wyrzuca błąd:

Exception in thread "Timer-0" java.lang.NullPointerException
at lab04_pop.Zadanie.run(Zadanie.java:14)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)

Pozostało 580 znaków

2013-11-28 20:24

Rejestracja: 7 lat temu

Ostatnio: 5 lat temu

1

Tworzysz obiekt Zadanie, który wewnątrz metody run() odwołuje się do Obiektu Ramka, który to nie jest jeszcze stworzony. Ponadto nie jestem pewien czy w JFrame w ogóle da się rysować. Lepiej w konstruktorze Ramki stwórz jakiś JPanel i na nim rysuj i do niego się odwołaj w swojej metodzie run().


Pozostało 580 znaków

2013-11-30 14:15

Rejestracja: 6 lat temu

Ostatnio: 3 lata temu

0

Mam kolejny problem. Trochę poczytałem i postanowiłem sporo zmienić, udało mi się wprawić obiekty w ruch i trochę przetestować rysowanie. Chciałem przejść do narysowania planszy (postanowiłem reprezentować ja przez tablicę dwuwymiarową), po której będą chodzić moje Lisy i Kury, ale niestety nie generuje się to co chciałem, czyli plansza tylko pusta (szara) ramka. Oto mój kod:

Klasa animacja:

package lab04_pop;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Animacja extends JPanel {
    Kura kura = new Kura(this);
    Świat świat = new Świat (this);

    public void plansza (){
        świat.zrobPlansze();
    }

    /*private void move() {
        kura.move();
    }*/

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        /*kura.paint(g2d);*/
        świat.paint(g2d);

    }

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("Kurnik");
        Animacja animacja = new Animacja();
        frame.add(animacja);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true) {
            /*animacja.move();*/
            animacja.repaint();
            Thread.sleep(10);
        }
    }
}

Klasa świat:

package lab04_pop;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.Random;

public class Świat {
    @SuppressWarnings("unused")
    private Animacja animacja;
    int plansza [][] = new int [20][20];

    public Świat(Animacja animacja) {
        this.animacja= animacja;
    }

    public void zrobPlansze (){
        Random gen = new Random();
        for (int i=0; i<plansza.length; i++){
            for (int j=0; j<plansza[0].length; j++){
                plansza[i][j]=gen.nextInt(2);
            }
        }
    }

    public void paint(Graphics2D g) {
        for (int i=0; i<plansza.length; i++){
            for (int j=0; j<plansza[0].length; j++){
                switch (plansza[i][j]){
                case 0:
                    g.setColor(Color.GRAY);
                    g.fillRect(20*j, 20*i, 20, 20);
                    break;
                case 1:
                    g.setColor(Color.ORANGE);
                    g.fillRect(20*j, 20*i, 20, 20);
                    break;
                case 2:
                    g.setColor(Color.RED);
                    g.fillRect(20*j, 20*i, 20, 20);
                    break;
                }
            }
        }
    }
}

Co robię źle?

Pozostało 580 znaków

2013-11-30 14:36

Rejestracja: 11 lat temu

Ostatnio: 1 godzina temu

0

Błędy są dwa:

  • nigdzie nie wywołujesz metody zrobPlansze, zatem w tablicy plansza są same zera,
  • masz zły zakres losowania, musi być
    plansza[i][j]=gen.nextInt(3);

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

Odpowiedz

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