Frage von wkp125, 64

Wie kann ich einen Button verschieben - C#?

Hallo,

ich habe angefangen mit der C Sharp Programmierung.

Ich bin gerade dran das Brettspiel Mühle zu programmieren.

Spielbrett mit Felder steht schon.

Buttons habe ich erzeugt.

Jetzt folgendes:

Ich habe Picture-Buttons auf die Ecken des Mühlebrettes platziert. Wenn ich nun meinen Spielstein anklicke, soll die Position des Button gespeichert werden und bei einem weiteren klickt auf einen Picture-Button gesetzt werden.

Ich programmiere Objekt orientiert.

Kann mir jemand weiterhelfen, bin schon am verzweifeln....

Vielen Dank

Gruß wkp125

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von CrystalixXx, 48

Was ist ein Picture-Button?

Wenn du mit Steuerelementen arbeitest, dann haben diese eine Location-Eigenschaft. Die gibt die Position von der oberen linken Ecke des übergeordneten Containers (bei dir möglicherweise die Form) zur oberen linken Ecke des Steuerelementes an.

Wenn es dir um die Logik der unterschiedlichen Programmzweige bei einem Klick geht, dann verwende eine zusätzliche Variable. Ist diese leer, dann wurde das erste mal geklickt und du kannst ihr einen Wert zuweisen (nämlich die Position). Ist diese nicht leer, dann wurde bereits einmal geklickt und sie hat einen Wert. Dann kannst du den Button auf diese Position setzen.

Oder wie auch immer; kann sein, dass ich dein Problem nicht ganz verstanden habe.

Kommentar von wkp125 ,

Sorry, ich habe  mich evtl. nicht richtig ausgedrückt. Der Picture-Button ist ein Button, dem ich ein Bild hinzugefügt habe (im folgenden Bild, die Buttons mit den Kreisen).

Also oben Links sitz mein "Stein". Jetzt möchte ich diesen anklicken, diese Position merken lassen und wenn ich jetzt z.b. auf den Button links unten klicke, soll dieser sich dort hin verschieben.

Hast du ein Code-Schnipsel für mich? Ich habe schon einiges versucht gehabt.

Kommentar von CrystalixXx ,
Private p As Point
Private invalidPoint As Point = Point.Empty

Private Sub btnPositionsStein_Click(sender As System.Object, e As System.EventArgs) Handles Button9.Click, Button8.Click, Button7.Click, Button6.Click, Button5.Click, Button3.Click, Button12.Click, Button11.Click, Button10.Click
If Not p.Equals(invalidPoint) Then
If TypeOf sender Is Button Then
btnSpielstein.Location = CType(sender, Button).Location
p = invalidPoint
End If
End If
End Sub

Private Sub btnSpielstein_Click(sender As System.Object, e As System.EventArgs) Handles btnSpielstein.Click
p = btnSpielstein.Location
End Sub

Ich habe in dem Beispiel 9 Buttons in einer 3 x 3 Anordnung angelegt und alle die gleiche Click-Methode zugewiesen ("btnPositionsStein_Click"). Der Spielstein heißt btnSpielstein und ruft bei einem Klick die "btnSpielstein_Click"-Methode auf.

Man muss zuerst auf den Spielstein klicken (dann wird die Position gespeichert) und dann auf einen der 9 Buttons. Dann wird der Spielstein an die neue Position verschoben. Klickt man direkt auf einen der 9 Buttons, dann passiert gar nichts.

(Falls die Position von x=0 und y=0 ebenfalls eine gültige Position sein darf, dann musst du "invalidPoint" einen anderen Wert zuweisen, z.B. New Point(Integer.MinValue, Integer.MinValue) oder ähnlich.)

Kommentar von wkp125 ,

Ich werde es ausprobieren. Danke

Kommentar von wkp125 ,

ich habe das versucht, ich komme jedoch mit dem Sub, End Sub etc. nicht zu recht.

Kannst du meine Visual Studio Projekt bitte unter folgendem Link ansehen?

https://cloud.web.de/ngcloud/external?locale=de&guestToken=2DP66RJHTcOwNZXxF...

Danke und Gruß wkp125

Kommentar von CrystalixXx ,

Hmm, ja. Ich hab mal wieder VB Code gepostet, statt C#. Passiert mir immer wieder.

Den obigen Code habe ich zu folgenden angepasst:

Button btn;

private void Steine_Click(object sender, EventArgs e)
{
btn = (Button)sender;
}

private void Felder_Click(object sender, EventArgs e)
{
if ((btn != null) && (sender is Button))
{
btn.Location = ((Button)sender).Location;
btn = null;
}
}

Den Code kannst du in dein Form1 kopieren. Außerdem musst du noch

Brett.FeldClicked += new EventHandler(Felder_Click);

im Form1_Load-Ereignis hinzufügen.


Dann habe ich in der Mühlebrett.cs diesen Code hinzugefügt:

public event EventHandler FeldClicked;

protected void OnFeldClicked(object sender, System.EventArgs e)
{
FeldClicked?.Invoke(sender, e);
}

private void Feld_Click(object sender, EventArgs e)
{
OnFeldClicked(sender, e);
}

und im Konstruktor dazu noch

Felder[i].Click += new EventHandler(Feld_Click);

Damit sollte es funktionieren.

Kommentar von wkp125 ,

Super, es hat funktioniert. Dankeschön.

Hast du einen Tipp für mich wie ich weiter vorgehen kann.

Ich möchte nun die Regeln definieren, d.h. das erst weiss dann schwarz dran komm, evtl. die button zum klicken deaktivieren ; dann wenn 3 steine in einer reihe von einer farbe ist, dass man beim "Gegner " ein stein nehmen darf; und wer gewonnen hat; zum schluss spiel neustarten bzw. zurücksetzten.

Ich benötige nur Anhaltspunkte, ich weis zwar was ich machen möchte, aber nicht wie ich es umsetzten kann.

Kommentar von CrystalixXx ,

Beim Start könntest du so vorgehen, dass du die Steine abwechselnd erstellst. Also nicht über zwei Schleifen, sondern eine. i teilst du dann durch 2 und kannst über den Rest bestimmen, ob weiß oder schwarz erstellt wird. So würden dann die Steine in abwechselnder Reihenfolge vom "Stapel" genommen werden.

Die Prüfung ob 3 in einer Reihe sind erfolgt dann immer nur nach dem Setzen eines Steines. Du musst dabei nicht das gesamte Spielfeld prüfen, sondern nur die betroffenen Reihen des zuletzt gelegten.

Möglicherweise wird es einfacher, wenn du noch ein eindimensionales Array mit 24 Elementen erstellst, wo du die einzelnen Spielsteine (also Buttons) speicherst. Oben links ist dann Element 0, oben rechts Element 2. Das obere rechte Feld des inneren Rechtecks wäre dann Element 8 und das Feld ganz unten links im äußeren Rechteck Element 21. Wird ein Spielstein gesetzt, speicherst du diesen Button an die entsprechende Position im Array. Wird ein Stein vom Feld genommen, überschreibst du ihn mit null.

Kommentar von CrystalixXx ,

Ergänzung:

Du könntest dann noch eine Liste mit den Regeln als String anlegen. Eine Regel beinhaltet dann die 3 Indizies, die für eine vollständige Reihe/Spalte stehen. Zum Beispiel:

List<String> Rules = new List<String>();
Rules.Add("0,9,21");
Rules.Add("9,10,11");

Wenn dann ein Stein auf Feld 9 gesetzt wird, durchsuchst du die Liste nach allen Strings, die die 9 enthalten. Dann filterst du die anderen beiden Indizies heraus und prüfst, ob an deren Position ebenfalls die selbe Farbe ist.

Antwort
von wkp125, 42

Das ist das Bild von meinem Programm

Keine passende Antwort gefunden?

Fragen Sie die Community