Swing Alle Objekte anzeigen auch bei JPanel-Überlappung

Newcomer2

Aktives Mitglied
Hallo Comunity,

ich versuch mich derzeit mal an einem Spiel, das in die Richtung "Age of Empires" und dergleichen gehen soll. Bisher funktioniert es wunderbar, dass ich zumindest schonmal bei Klick auf ein Objekt (Gebäude) neue Objekte (Figuren) generieren und diese einzeln ansteuern und bewegen kann. Die Figuren füllen dabei kein volles JPanel bzw. Canvas aus (schon mit beidem versucht).

Jetzt das Problem:
Bewege ich eine Figur über eine andere hinweg, so kann es sein, dass die darunterliegende hinter den JPanel/Canvas der sich bewegenden Figur verschwindet. Wie kann ich es schaffen, dass mir auch beim Passieren anderer Objekte, jedes Objekt angezeigt wird?

Hoffe mir kann hier jemand weiterhelfen.
 
Ich hoffe, ich habe das richtig verstanden, dass du jedes Objekt, das gezeichnet werden soll, in ein eigenes Panel packst?

Das wäre nämlich absolut falsch.
Wie ich bereits in einem anderen Thread gesagt habe:

Wenn du auf ein Blatt Papier zeichnest, zeichnest du alles auf dieses eine Blatt Papier.
Oder malst du eine Sonne auf ein extra Blatt, und klebst dieses Blatt dann auf den Hintergrund ???:L


Daher: Schau dir die Objekte Graphics und Graphics2D an.
Du kannst kein Spiel entwickeln, ohne diese zu kennen. :rtfm:
 
Leider nicht richtig.

Ich habe ein JPanel auf das die Objekte gelegt und verschoben werden können. Wenn jedoch ein Objekt ein anderes passiert, dann wird eines von beiden nicht mehr abgebildet, sondern durch das Canvas-Feld des anderen Objektes überdeckt. Hab hier mal soon Test-Fenster hochgeladen.

Das blaue Kästchen soll im Prinzip das Gebäude sein und die dabei erzeugten halben Strichfiguren die Figuren ^^ die Canvas-Größen für die Figuren sind
Java:
return new Dimension(30,60);
 

Anhänge

Hier mal der Ausschnitt aus der Hauptklasse des Programms.

Java:
@Override
	public void run() 
	{
		int[] x=new int[50+figures.size()],y=new int[50+figures.size()];
		while(th.isAlive())
		{
			for(int i=0;i<figures.size();i++)
			{
				if(figurX[i]+figures.get(i).getWidth()/2<mouseX[i]) figurX[i]++;
				if(figurX[i]+figures.get(i).getWidth()/2>mouseX[i]) figurX[i]--;
				if(figurY[i]+figures.get(i).getHeight()/2<mouseY[i]) figurY[i]++;
				if(figurY[i]+figures.get(i).getHeight()/2>mouseY[i]) figurY[i]--;
				if(figures.get(i).hasfocus==true)
				{
					System.out.println(figurX[i] +"  "+figurY[i]);
					System.out.println(mouseX[i] +"  "+mouseY[i]);
					figures.get(i).setLocation(figurX[i],figurY[i]);
				}	
				figures.get(i).setLocation(figurX[i],figurY[i]);
				panel.repaint();			
			}
			try {th.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
		}
	}
}

Und hier die beiden Canvas-Klassen:
Java:
@SuppressWarnings("serial")
class Kaserne
extends Canvas 
{
	boolean hasfocus;
	int x=0,y=0;

	public Kaserne()
	{
		super();
		this.hasfocus=false;
		enableEvents(AWTEvent.FOCUS_EVENT_MASK);
	}
	
	public Dimension getPreferredSize() { return new Dimension(15,30); }
	public Dimension getMinimumSize()   { return new Dimension(10,20); }
	public Dimension getMaximumSize()   { return new Dimension(30,60); }
	
	public boolean isFocusTraversable() { return true; }
	
	protected void processFocusEvent(FocusEvent event)
	{
		if (event.getID() == FocusEvent.FOCUS_GAINED)
		{
			for(int i=0;i<Canvasverschieben.figures.size();i++)
			{
				Canvasverschieben.figures.get(i).hasfocus=false;
				Canvasverschieben.figures.get(i).repaint();
			}
			hasfocus = true;
			repaint();
		} else if (event.getID() == FocusEvent.FOCUS_LOST)
		{
			hasfocus = false;
			repaint();
		}
		super.processFocusEvent(event);
	}
	
	public void paint(Graphics g) { ObjektXY(g,x,y); }
	
	void ObjektXY(Graphics g,int x,int y)
	{
		g.setColor(Color.BLUE);
		g.fillRect(x, y, getWidth(), getHeight());
		if(hasfocus)
			g.setColor(Color.orange);
		else
			g.setColor(Color.black);
		g.fillOval(x+getWidth()/2-1, y+getHeight()/2-2, 4, 4);
	}
}

class Figur
extends Canvas 
{
	private Image dbImage;
	private Graphics dbGraphics;
	boolean hasfocus;
	int x,y;
	
	public Figur() { super(); }
	
	public Dimension getPreferredSize() { return new Dimension(30,60); }
	public boolean isFocusTraversable() { return true; }
	
	
	public void update(Graphics g)
	{
	   //Double-Buffer initialisieren
	    if (dbImage == null) {
	       dbImage = createImage(
	          this.getSize().width,
	          this.getSize().height
	       );
	       dbGraphics = dbImage.getGraphics();
	    }
	    //Hintergrund löschen
	    dbGraphics.setColor(getBackground());
	    dbGraphics.fillRect(0,0,this.getSize().width,this.getSize().height);
	    
	    //Vordergrund zeichnen
	    dbGraphics.setColor(getForeground());
	    paint(dbGraphics);
	    
	    //Offscreen anzeigen
	    g.drawImage(dbImage,0,0,this);
	}
	
	public void paint(Graphics g)
	{
		x=getWidth()/2;
		y=getHeight()/2;
		ObjektXY(g,x,y); 
	}
	
	void ObjektXY(Graphics g,int x,int y)
	{
		int r=getWidth()/3;
		int r1=getWidth()/5;
		g.setColor(Color.black);
		g.fillOval(x-r/2,y/5-r/2,r,r);
		if(hasfocus)
		{
			g.setColor(Color.yellow);
			g.fillOval(x-r1/2,y/5-r1/2+1,r1,r1);
		}
		g.setColor(Color.black);
		g.fillRect(x-1,y/5+r/2,2,y);
	}
}

Ich hoffe das hilft etwas 🙂 und ihr könnt mir helfen 😀
 
Du brauchst nicht jedes Objekt auf einem eigenen Canvas zeichnen und diese dann in deinem Fenster verschieben.

Tutorials
Schau dir dort mal "2D-Spieleprogrammierung (Autor: Quaxli)" an. Ist sehr schön gemacht.
Beinhaltet einmal den fertigen Code und eine PDF mit Anleitung.
 

Zurück
Oben