Od weekendu przysiadłem sobie do nauki Java i na rozruch robię sobie okienkową gierkę/strzelankę z próbą wykorzystania MVC i Swing.
Jako sceny na której co każdy tick timera rysowane są obiekty, używam elementu JPanel.
Tutaj mam takie pytanie:
Mam klasę odpowiedzialną za właśnie tę scenę i rysowanie po niej, co oczywiste extends JPanel i** override paintcomponent**, i chciałbym, żeby robiła właśnie tylko to, rysowała po scenie. W obecnej postaci, z tego powodu, że żeby móc ją nadpisać, metoda paintcomponent przyjmuje standardowo tylko jeden zdefiniowany rodzaj argumentu, a co za tym idzie, nie mogę przekazać sobie nowego obiektu do narysowania z poziomu kontrolera, bezpośrednio do tej metody. Muszę zrobić to tak, że mam kopię zmiennych w klasie JPanel.
Chodzi mi o to, że teraz moja klasa JPanel przechowuje kopie zmiennych zawierające w sobie informacje o obiektach do narysowania, i te zmienne są aktualizowane co tick timera. Co za tym idzie, muszę z góry zdefiniować wewnątrz paintcomponent co i jak będzie narysowane. Chciałbym dowiedzieć się, czy da się to ominąć i bezpośrednio przekazać obiekty do tej metody, tak by dalej nadpisywała ona metodę bazową i była wywoływana razem z repaint().
Core gierki jest już zrobione i powinienem zaimplementować resztę moich pomysłów. Wszystko działa i teraz, ale nie chciałbym przetrzymywać kopii tych zmiennych, bo teraz jest to ścieżka Model->Controller->kopie zmiennych->View aktualizacja kopii zmiennych-> rysowanie, a chciałbym Model->Controller i wywołanie metody z View, i przekazanie zmiennych-> View i rysowanie;
Poglądowo przykład kodu:
public class GameSceneView extends JPanel
{
static private ArrayList<Enemy> listOfEnemyShips;
public GameSceneView(int width, int height)
{
setPreferredSize(new Dimension(width, height));
listOfEnemyShips = new ArrayList<Enemy>();
}
//metoda do nadpisania listy zawierającej obiekty do narysowania, wywoływana z kontrolera co każdy tick Timera
public void updateListOfEnemyShips(ArrayList<Enemy> listOfEnemyShips)
{
GameSceneView.listOfEnemyShips = listOfEnemyShips;
}
//nadpisany paintComponent, metoda repaint() wywołana w kontrolerze co każdy tick Timera
@Override public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//rysowanie wszystkich obiektów z listy
for (Enemy enemy : listOfEnemyShips)
{
g2.drawImage(enemy.getImageOfEnemy(), enemy.getLocation().x, enemy.getLocation().y,
enemy.getSize().width, enemy.getSize().height, null);
}
}
}
A chciałbym coś takiego:
public class GameSceneView extends JPanel
{
public GameSceneView(int width, int height)
{
setPreferredSize(new Dimension(width, height));
}
//nadpisany paintComponent, metoda repaint() wywołana w kontrolerze co każdy tick Timera
@Override public void paintComponent(Graphics g, ArrayList<T> listOfObjects)
{
//wykonuje magię voodo, czary mary i rysuje obiekty z przekazanej listy
}
}
Następną kwestią o którą chciałbym się zapytać, to czy da się przekazać taką listę do metody bez definiowania typu zmiennych ( tak, bym mógł przekazać do funkcji listę ze zmiennymi Enemy oraz listę ze zmiennymi Bullet). Mam listy ze zmiennymi do narysowania, dziedziczącymi po obiekcie Rectangle, więc wszystkie mają standardowo dane o ich wielkości i położeniu. Chyba, że powinienem zabrać się do tego od kombinowania z metodą paintComponent(), albo utworzyć dodatkową klasę która będzie zajmować się tylko tym.
Nigdy czegoś takiego nie robiłem ani nie zastanawiałem się, czy można, więc pytam. Jeśli tak, to o czym poczytać.
Jeśli pytania durne, to przypominam, ogarniam to od weekendu.