Jak zrobić animację klatka po klatce?

0

Mam napisać program, który wyświetla animację. Z okienkiem itp nie mam problemu ale z samą animacja już tak. Otóż animacja to okręgi wyświetlane klatka po klatce. I to wszystko mam w pliku .txt. I w każdej linijce pierwsza liczba to nr klatki a reszta współrzędna x i y tej kuli (chyba max to 1200 tych kulek). Będę wdzięczny za pomoc jak to ogarnąć i w razie czego za udzielenie odpowiedzi na dodatkowe pytania.

1

Weź dowolny program w Swingu, który coś wyświetla jako animację, następnie podmień etap renderowania grafiki, tak aby wyświetlał co potrzebujesz.

Model powinien wczytać (zapewne przed rozpoczęciem) plik, ułożyć sobie informacje w nim zawarte w taki sposób aby dało się szybko wyrenderować kolejne klatki.

Poniżej podaję pisane na kolanie przykłady, w założeniu ma to ilustrować temat, a nie pokazywać ładne praktyki programistyczne :)

		canvas = new Canvas() {
			private static final long serialVersionUID = 1L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);
//tutaj sobie rysuj co wynika z modelu danych na daną klatkę, poniżej jakiś abstrakcyjny przykład
				g.drawRect(0, 0, CANVAS_SIZE - 1, CANVAS_SIZE - 1);
				for (int i = 0; i < 30; i++) {
					int x = rng.nextInt(CANVAS_SIZE - 2);
					int y = rng.nextInt(CANVAS_SIZE - 2);
					g.fillOval(x, y, 8, 8);
				}
			}
		};

A tak wygląda użycie:

		while (true) {
			try {
				Thread.sleep(995);
				modelAnimacji.tick(); //przygotowanie kolejnej klatki do wyświetlenia
				canvas.repaint();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
0

Super, a jeśli chodzi o wczytywanie 1 inta w danej linijce i później po kolei współrzędnych to jak to zrobić? Pewnie Scanner tylko jakie metody?

0

Może być, podaję szkic algorytmu: dopóki jest następna linijka, pobierz ją. Wynik rozbij (split) po spacjach, przekonwertuj odpowiednie elementy tej tablicy na int/Integer za pomocą Integer.valueOf.

0

Mam taką ramkę https://4programmers.net/Forum/Download/21630
i jak ustawić wysokość g,drawRect() zajmował całą tą przestrzeń a nie więcej?

0
Mattii4211 napisał(a):

Mam taką ramkę https://4programmers.net/Forum/Download/21630
i jak ustawić wysokość g,drawRect() zajmował całą tą przestrzeń a nie więcej?

W zapodanym przykładzie ja robię:

private static final int CANVAS_SIZE = 500;
//.........
canvas.setSize(CANVAS_SIZE, CANVAS_SIZE);
//a to jest taki roboczy pomysł na zrobienie obramowania, tj: rysuję prostokąt od 0,0 do punktu 1 piksel od końca canvas
g.drawRect(0, 0, CANVAS_SIZE - 1, CANVAS_SIZE - 1);
0

Tylko problem jest taki, że moja ramka (BorderLayout) może zmienić rozmiar a Canvas() musi cały czas być maksymalne
I jeszcze jedno pytanie BufferedReader in czy (int) in.lines().count() odczyta mi ilość linijek w pliku?

Zrobiłem g.drawrect(0,0, this.getsize().width, this.getSize().height)

0

Dobra analizuję ten twój przykład i jakoś nie wiem jak się za to zabrać. Dane w pliku od 2 linijki są tak poukładane: nr klatki, pozycja x pozycja y pozycja x .... Pozycje są double/float. I nie wiem za bardzo jak rozpracować to rysowanie tych kulek (drawOval).

0
Mattii4211 napisał(a):

Dobra analizuję ten twój przykład i jakoś nie wiem jak się za to zabrać. Dane w pliku od 2 linijki są tak poukładane: nr klatki, pozycja x pozycja y pozycja x .... Pozycje są double/float. I nie wiem za bardzo jak rozpracować to rysowanie tych kulek (drawOval).

Pierwszy z wyników Googla daje przyzwoity przykład: https://www.google.com/search?q=java+parse+file+of+doubles
Czyli powinieneś zrobić pętle po linijkach pliku, następnie zeskanować jeden int, i dowolną liczbę (par) doubli.

Odnośnie rysowania, nie ma pytania na które można by odpowiedzieć, natomiast zarzucę linkiem: https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics.html#drawOval-int-int-int-int-

0

Dobra, ze wczytywaniem sobie poradziłem ale nie wiem jak narysować na raz 1200 tych piłek na 1 klatce. Robię for(int i=0; i<1200; i++) i co dalej?
PS dane mam w ArrayList();
\Mam tak obecnie:

g.drawRect(0, 0, this.getSize().width, this.getSize().height);
				Graphics2D g2 = (Graphics2D) g;
				for (int i = 0; i < numberOfBalls; i++) {
					double x = positions.get(frame).get(j);
					double y = positions.get(frame).get(j+ 1);
					if(j > 1) {
						x1 = positions.get(frame).get(j-2)+10d;
						y1 = positions.get(frame).get(j - 1)+10d;
					}
					j = j+2;
					Ellipse2D circle = new Ellipse2D.Double(x1+x+10d, y1+y+10d, 10, 10);
					g2.draw(circle);
				}

ale rysuje mi te kulki tylko tak jakby w jednym kwadracie

0
Mattii4211 napisał(a):

Dobra, ze wczytywaniem sobie poradziłem ale nie wiem jak narysować na raz 1200 tych piłek na 1 klatce. Robię for(int i=0; i<1200; i++) i co dalej?
PS dane mam w ArrayList();

Dla każdego takiego i pobierasz z tej listy x, oraz y i wypełniasz "owal" na tej grafice. Przykład rysowania koła o promieniu 8 już podawałem powyżej, dokumentację do metody rysowania okręgu także.

PS Warunek kontynuacji pętli (i<1200) powinien więc zależeć od rozmiaru tej listy, a nie od wpisanej literału zgodnego z jakimś jednym inputem. Taki kod będzie odporniejszy na błędy oraz czytelniejszy.

0

Część danych dla 1 klatki:

33.6075 15.7753 31.324 31.9376 36.4659 7.90205 13.4089 30.7292 11.111 22.1588 19.0959 
0
Mattii4211 napisał(a):

Część danych dla 1 klatki:

33.6075 15.7753 31.324 31.9376 36.4659 7.90205 13.4089 30.7292 11.111 22.1588 19.0959 

No ok, jako że niektóre z tych liczb przekraczają 10, a żadna nie przekracza 100, to może jest to procentowe położenie a nie bezwzględnie w pikselach? Wtedy wystarczy przemnożyć procent przez rozmiar canvasu. Np. 25% x 480px == 120 px współrzędna.

0

Dobra twój pomysł to strzał w 10 tylko w jaki sposób pobrać aktualny jego rozmiar, gdyż okno się może zmieniać i na początku mam scereenSize()/2 oraz jak sprawić, żeby kulki tylko w canvas się wyświetlały?

0

do Canvas() dodałem addComponentListener()
i mam coś takiego:

public void componentResized(ComponentEvent e) {
				height = e.getComponent().getSize().height;
				width = e.getComponent().getSize().width;

Jak rozciągam okno to rozciągają się elementy tylko jak wyliczam x i y : (positions.get(frame).get(j+ 1)/100.0d)*height; to znów nie rozkładają się na cale okno
Pewnie jakiś prosty błąd ale już coraz gorzej myślę xd

Dodam jeszcze, że okienko ma BorderLayout() a Canvas() jest ustawiony jako Center

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