Java Spielfeld mit Bildern füllen

Schau dir mal contentpane.getComponent(n) an.

Musst mal schaun, wie du an den index kommst, dann laesst du dir die Referenz geben und aenderst was immer du willst.
 
Hab das mal probiert, aber comp is immer null :(


Code:
public void delete(int x, int y){

		Component comp = content.getComponentAt(x, y);
		if (comp != null){
			System.out.println("tada");
		content.remove(comp);	
		}
}


EDIT: Hab es

Code:
public void delete(int x, int y){
	// 

		Component comp = content.getComponent(n);
		if (comp != null){
			System.out.println("tada");
		content.remove(comp);	
		}
		}

Jetzt muss ich nur noch alles so umschreiben, dass man koordinaten eingeben kann und dann das richtige n ausgewählt wird :) Danke!
 
Zuletzt bearbeitet:
getComponent(n) ist zwar möglich, aber halt eich für nicht wirklich sinnvoll...
ich würde alle Labels ein einen zweidimensionalen Array ablegen
JLabel[][] labels...
 
So, jetzt halt ich's nicht mehr länger aus, ich muss einfach schreiben!

Erstmal find ich's schön, cl0udt, dass du dich näher mit Java beschäftigen willst und selbstständig an einem Projekt bastelst.
Allerdings vertrete ich auch die Auffassung, dass man Anfängern, nur weil sie eben neu in der Materie sind, nicht unbedingt immer die einfachsten und dafür "hässlichsten" Lösungen präsentieren sollte! Nicht, dass du darum gebeten hättest, natürlich...

Ich will kurz erklären, wieso ich die Lösung, die dir hier vorgeschlagen wurde, als ungut empfinde. Kurz und einfach gesagt, es ist eine furchtbar unperformante Lösung des Problems. Jedes Component-Objekt birgt einen unheimlichen Verwaltungsaufwand für die JRE.
Hat das Component den Fokus, wurde mit der Maus darüber gefahren, geklickt, eine Taste angeschlagen, muss ich das Component neu zeichnen, weil es ungültig gemacht wurde von einem Kind oder Vaterobjekt, habe ich schon rekursiv die Größe des Component berechnet, und so weiter und so weiter. Da passieren so viele Sachen, die einfach nicht benötigt werden!
Natürlich merken wir das bei der Benutzung nicht, weil die heutigen Rechner so unglaublich schnell sind. Aber ich komme noch aus Zeiten der Programmierung, in denen der Hauptspeicher in Rechnern so klein war, dass man zu lange Methoden in mehrere Methoden aufteilen musste, um sie überhaupt laden und ausführen zu können. Mir blutet einfach das Herz, wie viele Leute all die tolle Leistung durch Faulheit oder Schlampigkeit unbrauchbar machen.
Außerdem, falls du irgendwann mal wieder ein ähnliches Problem hast, dann denkst du dir, okay, löst du es wieder so, wie du es eben jetzt gelernt hast. Wenn es dann aber zum Beispiel um GameOfLife geht, wo du ca vier Millionen Zellen hast, dann zeigt dir die JRE den Vogel.

Wie also kann man dein Problem eleganter lösen?
Zunächst einmal sollte man sich grob überlegen, welche Anforderungen das Programm stellt. In deinem Fall ist es sehr einfach:
1. Wir haben ein Spielfeld, bei dem sich maximal alle Sekunde ein oder mehrere Felder ändern.
2. Wir wollen das zu ändernde Feld gezielt mit Koordinaten ansprechen können.
3. Wir wollen bei einem Mausklick auf ein Feld dessen Koordinaten wissen.

Das alles deutet darauf hin, dass wir eine Möglichkeiten suchen sollten, die vergleichsweise sehr selten angesprochen und verändert werden muss (1 Sekunde ist ewig lang).

Daher mein Vorschlag! Wir erzeugen ein Bild, das in den Hauptspeicher gelegt wird und welches das Spielfeld darstellt. Dieses Bild lassen wir von einen JPanel zeichnen.
Wenn eine Zelle verändert werden soll, zeichnen wir die Änderungen in das Bild und lassen das JPanel aktualisieren.
So wird so gut wie kein Overhead produziert.

Ich habe dir mal ein Beispielprogramm geschrieben, bei dem jede Zelle drei verschiedene Stati haben kann und bereits Mausklicks registriert werden. Ich habe noch keine Kommentare reingeschrieben sondern versucht, alles möglichst einleuchtend zu benennen, trotzdem kannst du natürlich gerne Fragen stellen :)

Hauptklasse
Code:
public class Game {

	// ==================================================================================================
	// {[> Attributes
	// ==============
	private int[][] cellArray = new int[20][10];
	private JFrame frame;
	private GamePanel gamePanel;



	// ==================================================================================================
	// {[> Initializers and Constructors
	// =================================
	public Game() {
		frame = new JFrame("Schiffe versenken");

		try {
			gamePanel = new GamePanel(this, cellArray.length, cellArray[0].length);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(0);
		}

		gamePanel.update(cellArray);

		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.add(gamePanel);
		frame.pack();
		frame.setVisible(true);
	}



	// ==================================================================================================
	// {[> Static Methods
	// ==================
	public static void main(String[] args) {
		new Game();
	}



	// ==================================================================================================
	// {[> Methods
	// ===========
	public void setCell(int x, int y, int type) {
		cellArray[x][y] = type;
		gamePanel.update(x, y, type);
		frame.repaint();
	}

	public void setCellClicked(int x, int y) {
		int newType = (cellArray[x][y] + 1) % 3;
		cellArray[x][y] = newType;
		gamePanel.update(x, y, newType);
		frame.repaint();
	}
}

Spielfeld
Code:
public class GamePanel extends JPanel {

	// ==================================================================================================
	// {[> Attributes
	// ==============
	private BufferedImage[] cellImages = new BufferedImage[3];
	private BufferedImage masterImage;
	private int columns, rows, cellSize, cellPadding = 1;



	// ==================================================================================================
	// {[> Initializers and Constructors
	// =================================
	public GamePanel(final Game game, int columns, int rows) throws IOException {
		super();

		this.columns = columns;
		this.rows = rows;

		cellImages[0] = ImageIO.read(ClassLoader.getSystemResourceAsStream("cell1.png"));
		cellImages[1] = ImageIO.read(ClassLoader.getSystemResourceAsStream("cell2.png"));
		cellImages[2] = ImageIO.read(ClassLoader.getSystemResourceAsStream("cell3.png"));
		cellSize = cellImages[0].getWidth();

		masterImage = new BufferedImage(cellPadding + columns * (cellPadding + cellSize), cellPadding + rows * (cellPadding + cellSize), BufferedImage.TYPE_INT_RGB);

		setPreferredSize(new Dimension(masterImage.getWidth(), masterImage.getHeight()));

		addMouseListener(new MouseAdapter() {

			private Point p;

			public void mouseReleased(MouseEvent e) {
				p = e.getPoint();
				game.setCellClicked(p.x / (cellSize + cellPadding), p.y / (cellSize + cellPadding));
			}
		});
	}



	// ==================================================================================================
	// {[> Methods
	// ===========
	public void paint(Graphics g) {
		g.drawImage(masterImage, 0, 0, null);
	}

	public void update(int[][] cellArray) {
		Graphics2D g = masterImage.createGraphics();

		g.setColor(Color.BLACK);
		g.fillRect(0, 0, getWidth(), getHeight());

		for (int x = 0; x < columns; x++) {
			for (int y = 0; y < rows; y++) {
				g.drawImage(cellImages[cellArray[x][y]], cellPadding + x * (cellPadding + cellSize), cellPadding + y * (cellPadding + cellSize), null);
			}
		}

		g.dispose();
	}

	public void update(int x, int y, int type) {
		Graphics2D g = masterImage.createGraphics();
		g.drawImage(cellImages[type], cellPadding + x * (cellPadding + cellSize), cellPadding + y * (cellPadding + cellSize), null);
		g.dispose();
	}
}
 
Zuletzt bearbeitet:
@Killkrog: Is ja gut gemeint von dir, aber du bringst einen Fahrschüler wohl auch nicht das Fahren mit einem Formel-1-Auto bei ... warum einfache Probleme nicht einfach lösen?

Programmieren ist Erfahrungssache, und die Erfahrung kommt mit der Zeit. Und weißt du was dabei interessant ist? Am meisten lernt man sogar, wenn man Dinge falsch macht...

Und rein interessehalber, was war das für ein System, bei dem du "Methoden" aufgrund der Arbeitsspeichergröße aufteilen musstest? Aber klar, das was über Methoden gesagt wird, gilt an sich auch für Funktionen...
Und im Übrigen sollte man Methoden unabhängig vom Arbeitsspeicher sowieso so klein wie möglich und nur für einen Zweck machen - eine Methode, die auf mehrere aufgeteilt werden kann sollte auch aufgeteilt werden...
 
Zurück
Oben