odbijajace sie kulki

0

Witam serdecznie,

Prosze o pomoc w dokonczeniu programu.
Musze napisac program ktory poprzez klawisz dodaje
kulke (watek) do panelu. Kulki maja sie odbijac od
scianek i od siebie.

Nie wiem jak utworzyc funkcje
ktora by realizowala odbicia kulek od siebie (pozniej
musze to zrobic w bloku synchronicznym...).

Z gory dziekuje za pomoc :)

Ponizej kod jaki zrobilem do teraz:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Choice;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/* 
 *  Klasa glowna: PlaygroundExecute.java - uruchamia aplikacje 
 */

public class PlaygroundExecute {

	protected static void run() {
		Playground pg = new Playground();
		pg.show();
		pg.setSize(300, 250);
		pg.setTitle("PlaygroundExecute");
		pg.setVisible(true);
		pg.setResizable(false);
		// pg.b.start();
	}

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

/*
 * Playground.java
 */

class Playground extends Frame {

	Panel ballPanel = new Panel();
	Panel commandsPanel = new Panel();
	// Box box = new Box (50, 50, 100, 100);

	final int max = 100;
	int num; // number of balls
	Ball[] ball = new Ball[max]; // array of balls

	public Playground() {

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		setLayout(new BorderLayout());

		Font f = new Font("Courier", Font.BOLD, 12);
		Label titleLabel = new Label("PLAYGROUND", Label.CENTER);
		titleLabel.setFont(f);
		commandsPanel.add(titleLabel);

		commandsPanel.setLayout(new GridLayout(6, 1));

		addButton(commandsPanel, "Dodaj kulke", new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				Ball b = new Ball(ballPanel);
				b.start();
			}

		});

		ballPanel.setBackground(Color.LIGHT_GRAY);

		add(ballPanel, BorderLayout.CENTER);
		add(commandsPanel, BorderLayout.WEST);
	}

	private void addButton(Panel p, String title, ActionListener a) {
		Button b = new Button(title);
		p.add(b);
		b.addActionListener(a);
	}
}

/*
 * Ball.java - uruchamia watki kulek
 */

class Ball extends Thread {

	// int numBalls;
	// Ball[] balls = new Ball[numBalls];

	Panel pl;

	static final int XSIZE = 15;
	static final int YSIZE = 15;

	int x = 100;
	int y = 100;
	int dx = 2;
	int dy = 2;

	// konstruktor
	public Ball(Panel b) {
		pl = b;
	}

	public void draw() {
		Graphics g = pl.getGraphics();
		g.fillOval(x, y, XSIZE, YSIZE);
		g.dispose();

	}

	public void move() {
		if (!pl.isVisible())
			return;
		Graphics g = pl.getGraphics();
		g.setXORMode(pl.getBackground());
		g.fillOval(x, y, XSIZE, YSIZE);
		Dimension d = pl.getSize();

		x += dx;
		y += dy;

		if (x < 0) {
			x = 0;
			dx = -dx;
		}
		if (x + XSIZE >= d.width) {
			x = d.width - XSIZE;
			dx = -dx;
		}
		if (y < 0) {
			y = 0;
			dy = -dy;
		}
		if (y + YSIZE >= d.height) {
			y = d.height - YSIZE;
			dy = -dy;
		}
		g.fillOval(x, y, XSIZE, YSIZE);
		g.dispose();
	}

	public void run() {
		try {
			draw();
			for (;;) {
				move();
				sleep(5);
			}
		} catch (InterruptedException e) {
		}
	}
}
0

Metoda brute force (niewyrafinowana == dobra).
Dodajesz kulki do listy, przetrzymującej wszystkie kulki:

//pole w playground
List<Ball> wszystkieKulki = new LinkedList<Ball>();

// ...
public void actionPerformed(ActionEvent evt) {
   Ball b = new Ball(ballPanel);
   wszystkieKulki.add(b);
   b.start();
}

Teraz trzeba porównać położenia kulek. Można zrobić to rożnie. Przez komparator, przez equals ( bardzo złe rozwiązanie ) przez własną metodę. Najprostsze rozwiązanie każda z każdą jest rozsądne, ale dla małej ilości kulek. Ilość porównań n! czy coś koło tego... Lepsza metoda to podzielić planszę na kilka "obszarów" i porównywać kulki każda z każdą tylko w danym obszarze. Mam nadzieję że nadążasz. Kolejny algorytm jest już znacznie bardziej skomplikowany. Załóżmy, że nasza plansza ma wymiary MxN. Utwórzmy zatem tablicę o takich wymiarach i "kolorujmy" pola aktualnie zajęte przez kulki. Komplikuje się za to algorytm przesunięcia:
Wyznacz miejsce docelowe
sprawdź czy jest puste
"pokoloruj" to miejsce
"wytrzyj" stare położenie.

można też dla ułatwienia zamienić ostatnie dwa kroki.

0
Koziołek napisał(a)

Metoda brute force (niewyrafinowana == dobra).
Dodajesz kulki do listy, przetrzymującej wszystkie kulki:

Teraz trzeba porównać położenia kulek. Można zrobić to rożnie. Przez komparator, przez equals ( bardzo złe rozwiązanie ) przez własną metodę. Najprostsze rozwiązanie każda z każdą jest rozsądne, ale dla małej ilości kulek. Ilość porównań n! czy coś koło tego... Lepsza metoda to podzielić planszę na kilka "obszarów" i porównywać kulki każda z każdą tylko w danym obszarze. Mam nadzieję że nadążasz. Kolejny algorytm jest już znacznie bardziej skomplikowany. Załóżmy, że nasza plansza ma wymiary MxN. Utwórzmy zatem tablicę o takich wymiarach i "kolorujmy" pola aktualnie zajęte przez kulki. Komplikuje się za to algorytm przesunięcia:
Wyznacz miejsce docelowe
sprawdź czy jest puste
"pokoloruj" to miejsce
"wytrzyj" stare położenie.

można też dla ułatwienia zamienić ostatnie dwa kroki.

Dziekuje za zainteresowanie tematem:)
Mam problem z napisaneniem tego co proponujesz... nie bardzo jak wiem jak zaimplementowac taka metode. Moglbys napisac cos wiecej w formie kodu?:>
wykonujaca

0

Taki maly offtopic, ale caly powyzszy kod wyglada ma na niemal spisany z Core Java 2. Advanced Features, rozdzial 1.: Multithreading. Jesli to prawda i to na zaliczenie jest jakies, to sie zastanow bo skoro ja poznalem to i prowadzacy moze. A jesli nieprawda to z calym szacunkiem przepraszam za pomowienia, ale na serio to wyglada bardzo podobnie i nadal jest podejrzany...

0

Najprostsze rozwiązanie każda z każdą jest rozsądne, ale dla małej ilości kulek. Ilość porównań n! czy coś koło tego...

Taka mała korekta: do wykrywania kolizji wystarczy n * (n - 1) / 2 porównań, czyli O(n^2), co jest jednak dużo mniejsze niż n! Dla kilkuset kulek nie będzie żadnego problemu. Kiedyś robiłem bilard i ten algorytm działał świetnie w realtime na starym PII 450 MHz.

Oczywiście masz rację, że na wolnym sprzęcie i skomplikowanej grze np. na telefonie komórkowym ten algorytm jest słaby i wtedy lepiej sobie podzielić przestrzeń na mniejsze kawałki.

0

@Królik, hm... rzeczywiście n^2. Była dopiero 21.30 jak to pisałem...

@studenttt, biorąc pod uwagę to co napisał core2 raczej nie. Zrzynanie kodu i PRZEDSTAWIANIE JAKO WŁASNY nie jest ładne.

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