Problem z dziedziczeniem

0

Witam mam taka klase Thing ktora reprezentuje u mnie kazdy obiekt.

public abstract class Thing {
	private Image image;
	private float x;
	private float y;
	private float speed;
	private final int WIDTH;
	private final int HEIGHT;
	
	public Thing(String filename, float x, float y, float speed) {
		try {
			Image image = ImageIO.read(new File(filename));
		} catch (Exception e) {}
		this.x = x;
		this.y = y;
		this.speed = speed;
		WIDTH = image.getWidth(null);
		HEIGHT = image.getHeight(null);
	}
	
	//Zwraca ksztalt do sprawdzania czy contains...
	public Rectangle2D getShade() {
		return new Rectangle2D.Float(x, y, WIDTH, HEIGHT);
	}
		
	public Image getImage() {
		return image;
	}
		
	public Point2D getPoint() {
		return new Point2D.Float(x, y);
	}
		
	public float getX() {
		return x;
	}
		
	public float getY() {
		return y;
	}
}

Teraz chce utworzyc klase gracza ktora nie bedzie sie roznila niczym oprcz jednej dodatkowej metody dzieki ktorej uzytkownik moze graczem sterowac. Wiec robie tak:

public class Player extends Thing {
	public Player(String filename, float x, float y, float speed) {
		super(filename, x, y, speed);
	}
	
	public void moveToPoint(Point2D targetPoint) {
		int targetX = (int)targetPoint.getX();
		int targetY = (int)targetPoint.getY();
		//Jezeli kursor jest na statku to przerywamy zeby nie bylo efektu trzesania sie
		if ( ((int)x+20 < targetX+3) && ((int)x+20 > targetX-3) ) {
			return;
		}
		float distanceX = targetX - x;
		float distanceY = targetY - y;
		//Dodanie 20px wymiarow statku
		distanceX -= 20;
		distanceY -= 20;
		//Ustalenie wartosci shiftow
		float shiftX = speed;
		float shiftY = speed;
		if (abs(distanceX) > abs(distanceY)) {
			shiftY = abs(distanceY) / abs(distanceX) * speed;
		}
		if (abs(distanceY) > abs(distanceX)) {
			shiftX = abs(distanceX) / abs(distanceY) * speed;
		}
		//Zmiana kierunku shifta w zaleznosci od polozenia
		if (distanceX < 0) {
			shiftX = -shiftX;
		}
		if (distanceY < 0) {
			shiftY = -shiftY;
		}
		//Jezeli statek mialby wyjsc poza granice to przerywamy
		if ( (((int)x+shiftX < 0) || ((int)x+shiftX > 260)) || ((y+shiftY < 0) || (y+shiftY > 360)) ) {
			return;
		}
		//Zmiana pozycji gracza
		x += shiftX;
		y += shiftY;
	}

i IDE mi podkresal na czerwono x i y mowiac by zmienic je na protected. Zmiana na protected sprawia ze wywala mi sledzenie stosu. Co zle robie?

0

Zmiana na protected sprawia ze wywala mi sledzenie stosu.

Co wywala? Chodzi może o stacktrace (to bym przetłumaczył bardziej jako ślad stosu)?

0

Jak cos po zmianie klasy wygladaja tak:

THING
public abstract class Thing {
	protected Image image;
	protected float x;
	protected float y;
	protected float speed;
	protected final int WIDTH;
	protected final int HEIGHT;
	
	public Thing(String filename, float x, float y, float speed) {
		try {
			Image image = ImageIO.read(new File(filename));
		} catch (Exception e) {}
		this.x = x;
		this.y = y;
		this.speed = speed;
		WIDTH = image.getWidth(null);
		HEIGHT = image.getHeight(null);
	}
	
	//Zwraca ksztalt do sprawdzania czy contains...
	public Rectangle2D getShade() {
		return new Rectangle2D.Float(x, y, WIDTH, HEIGHT);
	}
		
	public Image getImage() {
		return image;
	}
		
	public Point2D getPoint() {
		return new Point2D.Float(x, y);
	}
		
	public float getX() {
		return x;
	}
		
	public float getY() {
		return y;
	}
}
PLAYER
public class Player extends Thing {
	public Player(String filename, float x, float y, float speed) {
		super(filename, x, y, speed);
	}
	
	public void moveToPoint(Point2D targetPoint) {
		int targetX = (int)targetPoint.getX();
		int targetY = (int)targetPoint.getY();
		//Jezeli kursor jest na statku to przerywamy zeby nie bylo efektu trzesania sie
		if ( ((int)x+20 < targetX+3) && ((int)x+20 > targetX-3) ) {
			return;
		}
		float distanceX = targetX - x;
		float distanceY = targetY - y;
		//Dodanie 20px wymiarow statku
		distanceX -= 20;
		distanceY -= 20;
		//Ustalenie wartosci shiftow
		float shiftX = speed;
		float shiftY = speed;
		if (abs(distanceX) > abs(distanceY)) {
			shiftY = abs(distanceY) / abs(distanceX) * speed;
		}
		if (abs(distanceY) > abs(distanceX)) {
			shiftX = abs(distanceX) / abs(distanceY) * speed;
		}
		//Zmiana kierunku shifta w zaleznosci od polozenia
		if (distanceX < 0) {
			shiftX = -shiftX;
		}
		if (distanceY < 0) {
			shiftY = -shiftY;
		}
		//Jezeli statek mialby wyjsc poza granice to przerywamy
		if ( (((int)x+shiftX < 0) || ((int)x+shiftX > 260)) || ((y+shiftY < 0) || (y+shiftY > 360)) ) {
			return;
		}
		//Zmiana pozycji gracza
		x += shiftX;
		y += shiftY;
	}
}
MAIN
public class MainPanel extends JPanel {
	private Player player = new Player("/player.gif", 130, 300, 3);
	private Point2D targetPoint = new Point2D.Float(130, 350); //Poczatkowa pozycja statku
	private ArrayList<Beam> beams = new ArrayList<Beam>();
	
	public MainPanel() {
		setPreferredSize(new Dimension(300, 400));
		
		addMouseMotionListener(new MouseMotionHandler());
		
		//Rozpoczynanie watkow
		Thread t = new Thread(new PlayerMoveRunnable());
		t.start();
	}
...
...
...

A co do bledu to wyglada tak:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at spacecommander.Thing.<init>(Thing.java:25)
at spacecommander.Player.<init>(Player.java:14)
at spacecommander.MainPanel.<init>(MainPanel.java:16)
at spacecommander.MainFrame.<init>(MainFrame.java:11)
at spacecommander.Test$1.run(Test.java:10)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

0

Zamiast robić puste catche to wrzucaj tam coś, logowanie lub coś innego. Stawiam, że image się nie ładuje i pozostaje nullem.

0

Tzn ja chcialbym zeby mi przekopiował pola z Thing do Player i zainicjował je zgodnie z konstruktorem nadklasy. Z bledu wynika ze konstruktor nie zainicjowal tych stalych

0

Jeśli ImageIO.read rzuci wyjątkiem to pole image pozostanie niezainicjowane, tzn pozostanie nullem. Sprawdź czy ImageIO.read rzuca wyjątkiem lub czy zwraca nulla. Najlepiej w ogóle gdzieś przed wywołaniem tej metody sprawdź co zwraca metoda File.exists dla parametru file.

0

Fakt z imagem byl problem, dzieki. A teraz mam inne pytanie w grze leci kilka watkow (np. dla kazdego pocisku jest tworzony oddzielny watek). Sleep ustawilem na 15 sek, czyli co 1 5 sekund kazdy pocisk jest przesuwany. Wydaje mi sie ze nie obciazylem jakos specialnie aplikacji a mimo to co jakis czas w konsoli wywala mi blad: Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Z czym jest zwiazy ten blad? Brak synchronizacji, instrukcji warunkowych (czy jak to sie tam zwie)?

0

Gdybyś jeszcze łaskawie podał kawałek kodu, w którym występuje problem to byłoby prościej. Patrząc na JavaDoca tego Exceptiona można dość do wniosku, że najprawdopodobniej iterujesz po kolekcji, jednocześnie (tzn z tego samego lub innego wątku) modyfikując ją używając metod nie wbudowanych w tenże iterator (tzn Iterator.remove itd).

0

No wlasnie w tym rzecz ze nie mam jak podac kawalka kodu w ktorym wystepuje problem po on moze byc wszedzie :P Zrobilem kilka watkow w ktorych, jak mowisz, na ArrayList sa wykonywane ciagle operacje dodawania i usuwania. W takim razie jak moglbym zaradzic temu wyjatkowi? Synchronizacja by tu pomogla czy cos innego?

0

Moim zdaniem masz po prostu skopany projekt aplikacji. Niemniej jeśli bardzo chcesz dobierać się do iterowanej kolekcji to zobacz np na: http://stackoverflow.com/questions/1775717/explain-synchronization-of-collections-when-iterators-are-used

PS możesz jeszcze poczytać o klasie CopyOnWriteArrayList - w niej nie trzeba synchronizować iteracji, natomiast pojedyncza mutacja jest dosyć kosztowna (dlatego w pojedynczej mutacji trzeba by było robić jak najwięcej naraz tak by zminimalizować ilość mutacji).

0

Zostaw Java i chodź zatańcz z nami Twista!

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