Graphisches Game Menü

J@ckWhiteIII

Mitglied
Hallo,
vorweg gestellt muss ich einmal anmerken, dass ich schon einmal gefragt hatte, wie man die Maus bei einem graphischen UI für ein Game "locked", so dass ein Button nur ein mal gedrückt werden kann.

So, nun aber zum Punkt: Ich habe mir eine Klasse geschrieben, die vom Rectangle erbt. Im Constructor gibt man den Namen und die Position des Buttons an. Das Rectangle wird benutzt, um es möglich zu machen, dass bei einem mouseOver oder einem Klick sich die Text-/Hintergrundfarbe ändert. Soweit, so gut. Nun ist das Problem, dass man in Java ein Objekt LEIDER nicht manuell Löschen kann, denn wenn im Titlescreen "Start Game" stand, so steht es im Spiel selbst nicht mehr da, ABER das Objekt ist ja noch vorhanden! das bedeutet also, dass, selbst wenn der Button nicht mehr sichtbar ist, darauf geklickt werden kann. Jetzt hatte ich ein wenig auf diesem Forum und im Internet nach einer Lösung gesucht, war dabei jedoch nicht auf vernünftige Lösungen gestoßen. Also frage ich noch einmal explizit, ob jemand Erfahrung mit so etwas hat, oder ob er eine Lösung weiß. Angezeigt werden die Buttons übrigens mit einer ArrayList.
Mal ein Screenshot des Menüs:
Menu.png


Ein Screenshot des Game selbst (derzeit noch stark im Debug Mode..) :
InGame.png


ich hoffe einfach mal, dass mir jemand helfen kann und dass ich mein Problem einigermaßen einleuchtend Schildern konnte.
Vielen dank für eventuelle Antworten 🙂

P.S. es soll mal das Spiel "Risiko" werden (mit Ideen aus 'Axis & Allies').
 
das bedeutet also, dass, selbst wenn der Button nicht mehr sichtbar ist, darauf geklickt werden kann.
Mir ist nicht so ganz klar worauf Du hinaus willst bzw. was die Fragestellung ist. Aber auf nicht sichtbare Buttons kann auch nicht geklickt werden. Bzw das Klicken durch den Anwender in den Bereich des Buttons kann man nicht verhindern ;-) aber der ActionListener bleibt dabei tot.
Wenn ich's richtig verstanden habe zeichnest Du ja sowieso alles selbst (oder was hat das mit dem Rectangle auf sich) daher verstehe ich überhaupt nicht was das Problem ist.
 
Das hier ist die "Texting" Klasse, die ich gemacht habe.

Java:
import java.awt.*;
import java.awt.geom.Rectangle2D;

public class Texting extends Rectangle {
	
	private static final long serialVersionUID = 1L;
	public String text;
	public int x;
	public int y;
	public Font f = new Font("Arial",Font.PLAIN,14);
	public FontMetrics fm = new FontMetrics(f){private static final long serialVersionUID = 1L;};
	public Rectangle2D bounds;
    public int widthInPixels; 
	
	public Texting (String text,int xx, int yy){
		this.text = text;
		this.x = xx;
		this.y = yy;
		bounds = fm.getStringBounds(text, null);
		widthInPixels = (int) bounds.getWidth(); 
		setBounds(xx - 3,yy - 15,widthInPixels,20);
	}
	
	public void click(int mouseButton){
		if (mouseButton == 1){
			if (!KeyStates.locked){
				if (Texting.mouseOver(Screen.mse,this)){
					Screen.c.start();
					Screen.c.setFramePosition(0);
					if (!KeyStates.locked){
						switch(this.getText()){
						case "Start Game":
							KeyStates.locked = true;
							Screen.gameState = 1;
							break;
						case "Quit Game":
							KeyStates.locked = true;
							System.exit(0);
							break;
						case "Quit Current Game":
							KeyStates.locked = true;
							Screen.gameState = 0;
							break;
						case "Continue":
							KeyStates.locked = true;
							Screen.gameState = 1;
							break;
						case "Pause":
							KeyStates.locked = true;
							Screen.gameState = 2;
							break;
						}
						KeyStates.locked = true;
					}
				}
			}
		}
	}
	
	public static boolean mouseOver(Point mouse,Texting t){
		if (t.contains(mouse)){
			return true;
		}else{
			return false;
		}
	}
	
	public String getText(){
		return text;
	}
	
	public void draw(Graphics g){
		if(!mouseOver(Screen.mse,this)){
			g.setColor(new Color(100,0,0));
		}else{
			g.setColor(new Color(100,0,100));
		}
		g.setFont(f);
		g.fillRect(x - 4, y - 14,widthInPixels + 8, 20);
		g.setColor(new Color(255,0,0));
		g.drawString(text, x, y);
	}

}

Daraus wird in der hauptklasse halt ein Objekt gemacht, welches dann mittels
Java:
for(int i=3;i<7;i++){
        texts.get(i).draw(g);
}

angezeigt wird 🙂 da das Rectangle objekt aber (wenn es nicht mehr angezeigt( .draw(g) ) nicht mehr gerufen wird) immer noch da ist, kann noch darauf geklickt werden. Ich habe einen Allgemeinen Mouselistener, in dem immer die .click methode von dem jeweiligen Texting aufgerufen wird. Eventuell ist das etwas mehr verständlich? Wenn es gewünscht ist, kann ich auch alles posten...

Die Frage ist eben, wie ich es machen kann, dass das Rectangle Objekt nicht mehr da ist (es wird ja gerade nicht mehr gebraucht)
 
Also geht es gar nicht um Buttons.

Die Klasse Testings ist ja ganz schön merkwürdig, aber wenn
Code:
KeyStates.locked==true
ist wird die click Methode ja sofort wieder beendet.

Über das Design dieser Klasse würde ich nochmal nachdenken:
- Warum die statische mouseOver? Das wäre doch eine typische Instanzmethode eines Objektes.
- In der Methode click sind schon alle Texte bekannt, die jemals eine Instanz dieser Klasse besitzen kann?? das sieht irgendwie nach "durch die Brust ins Auge" aus.
- Die Klasse sollte eher Rectangle verwenden, aber nicht diese Klasse erweitern. Texting ist kein Rectangle
 
Hmmm das design wird wohl noch mal überdacht werden müssen ^^ mouseOver steht (noch) static, weil ich sie vorher in der KeyStates Klasse aufgerufen wurde, und da ja witzigerweise alle aus anderen Klassen, die man darin verwenden möchte, static setzten muss...

Bei der click Methode war ich mir nicht sicher, wie ich es sonst machen sollte...Es kann ja verschiedene "buttons" geben, und da wollte ich halt irgendwie schauen, um welchen es sich handelt und dementsprechend handeln...Aber, um ehrlich zu sein, ich habe noch nie ein solches UI/Menü gemacht, und da ja alles mit der maus gemacht werden soll usw ist das für mich etwas kompliziert...weil der text ja anklickbar sein soll und so weiter :/ Verbesserungsvorschläge und Tipps sind also gern gesehen.

Erst einmal Danke für deine Antwort, ich setze mich mal wieder ran 🙂
 
und da ja witzigerweise alle aus anderen Klassen, die man darin verwenden möchte, static setzten muss...
Versteh ich nicht. In einem Java Programm muss man - abgesehen von der main Methode - gar nichts static setzen. Oftmals deutet die Verwendung von static auf Fehler in Klassendesign hin.

Clicks werden oder sonstige Actions werden üblicherweise nicht direkt von der Komponente verarbeitet sondern an einen Listener gemeldet, der sie z.B. zur Verarbeitung an einen Controller weiter reicht. Ein mögliches Entwurfsmuster:
Model View Controller ? Wikipedia
die click Methode ist in Deiner Klasse also eigentlich völlig fehl am Platz - oder hast Du beim Umgang mit Buttons die JButton Klasse erweitert um in Ihr die Buttonclicks zu verarbeiten?
 
Hallo.

Dass man in Java nichts manuell löschen kann ist zwar richtig, wird von dir aber falsch interpretiert. Wenn du die Referenz des Buttons löschst (auf null setzt), ihn aus Lists rausnimmst bzw. Ihn von dem JFrame/JPanel wieder removest wird die Instanz nurnoch als Datenleiche in RAM sein. Auch fals der GC die Instanz nicht sofort aufräumt so weiss dein Programm garnichts mehr von dem Button und wird ihn weder Zeichnen, noch auf einen Klick reagieren.
 
Model View Controller ? Wikipedia
die click Methode ist in Deiner Klasse also eigentlich völlig fehl am Platz
Wenn ich das also recht verstehe, ist Texting das model. Jedoch verstehe ich nicht ganz, was view und controller sind. Aus dem Link:
Präsentation (view)
Die Präsentationsschicht ist für die Darstellung der benötigten Daten aus dem Modell und die Entgegennahme von Benutzerinteraktionen zuständig.
Das heißt also, dass die Daten vom model an den view geleitet werden, sowie benutzerdaten empfangen werden. Dann, laut Wiki:
Steuerung (controller)
Die Steuerung verwaltet eine oder mehrere Präsentationen, nimmt von ihnen Benutzeraktionen entgegen, wertet diese aus und agiert entsprechend. Zu jeder Präsentation existiert eine Steuerung. Es ist die Aufgabe der Steuerung, Daten zu manipulieren. Die Steuerung entscheidet aufgrund der Benutzeraktion in der Präsentation, welche Daten im Modell geändert werden müssen. Sie enthält weiterhin Mechanismen, um die Benutzerinteraktionen der Präsentation einzuschränken. Die Steuerung kann in manchen Implementierungen ebenfalls zu einem „Beobachter“ des Modells werden, um bei Änderungen der Daten den View direkt zu manipulieren.
Eventdaten werden also vom view an den controller geschickt, der dann je nach event die daten des models ändert.

Nun wären folglich also der view gleich einem eventListener für EINE Art von Objekt und der controller...naja...eben das verstehe ich nicht. Geht es dabei eigentlich um drei verschiedene klassen? Also, der model Klasse, der view Klasse und der controller Klasse? Wie wird überhaupt alles in der Hauptklasse implementiert? Fragen über Fragen...Hoffe auf eine Antwort.
P.s. Studiert? 😀




Dass man in Java nichts manuell löschen kann ist zwar richtig, wird von dir aber falsch interpretiert. Wenn du die Referenz des Buttons löschst (auf null setzt), ihn aus Lists rausnimmst bzw. Ihn von dem JFrame/JPanel wieder removest wird die Instanz nurnoch als Datenleiche in RAM sein. Auch fals der GC die Instanz nicht sofort aufräumt so weiss dein Programm garnichts mehr von dem Button und wird ihn weder Zeichnen, noch auf einen Klick reagieren.
D.h. also, dass es ganz einfach reicht, das Objekt aus der Liste zu entfernen. Sehr gut, das bringt mich auf jeden Fall ein ganzes Stück weiter. Vielen Dank für die Antwort.
 
Hallo.

Dass man in Java nichts manuell löschen kann ist zwar richtig, wird von dir aber falsch interpretiert. Wenn du die Referenz des Buttons löschst (auf null setzt), ihn aus Lists rausnimmst bzw. Ihn von dem JFrame/JPanel wieder removest wird die Instanz nurnoch als Datenleiche in RAM sein. Auch fals der GC die Instanz nicht sofort aufräumt so weiss dein Programm garnichts mehr von dem Button und wird ihn weder Zeichnen, noch auf einen Klick reagieren.


Genau so siehts aus, das Objekt musst du nicht löschen. Das Object "stirbt" genau dann wenn es nicht mehr gebraucht wird
 

Zurück
Oben