Jump to content
Unity Insider Forum
Sign in to follow this  
eXestend

Ein einfaches Spiel - Zahlen Klicken

Recommended Posts

Hallo,

 

ich habe es immer mal wieder versucht und bin nie lange am Ball geblieben. Das möchte ich mal ändern und daher einen noch anderen Weg gehen. Kein Buch und kein Video. Beides habe ich schon gemacht. Gewisse Grundkenntnisse sollten vorhanden sein.

 

Ich habe mir daher ein sehr simples Spiel überlegt. Das würde ich sehr gerne mit euch gemeinsam verwirklichen um mir selbst auch mal eine Motivation zu geben das was ich in Unity Beginne zu beenden.

 

Quasi ein Workshop.

 

Die Idee:

  • Ein paar Cubes in einem Raster 4 x 6 (oder 5 x 5 etc.)
  • Die Cubes sollen beim Laden zufällige Zahlen besitzen (zwischen 1 und 50 als Beispiel)
  • Man soll dann die Zahlen Anklicken in aufsteigender Reinfolge.
  • Der Timer zählt die Sekunden die man benötigt.
  • Pro richtig geklickte Zahl gibt es x Punkte (z.B. 5)
  • Falsche Zahlen: gibt es einen Abzug von Punkten ( meinetwegen 5)
  • Hat man alles geklickt, kann man den Wert Speichern und neustarten.

 

Ich hoffe, dass eine Umsetzung nicht so kompliziert wäre. Das ist so zumindest eines meiner Ziele für den heutigen Abend.

Ich denke viele von euch würden sowas in 5 Minuten machen.

 

Was ich mich jetzt Frage:

  • Wie fange ich da an. Werden die Zahlen Cubes über die ein GUI Text liegt?
  • Wird es nur ein GUI Text.
  • Wie weise ich den Cubes die verschiedenen zahlen zu
  • Gebe ich vom Würfel zurück (Ich wurde geklickt und wenn die Zahl derzeit die zu klicktende Zahl ist dann wird es als richtiger klick gewertet) oder gibt der Klick zurück: Der Cube 4 wurde geklickt.

Naja, ich bin mal gespannt und hoffe, nicht wieder zu hoch gegriffen zu haben.

 

LG

Share this post


Link to post
Share on other sites

Zu den Fragen:

Die "Cubes" würde ich ganz banal durch einfache Buttons realisieren und die Zahl wird dann einfach als Text des Buttons gesetzt.

Somit wären eigentlich schon Frage 1-3 beantwortet.

Frage 4 ist aber prinzipiell auch nicht schwer zu beantworten.

Da gibt es, wie so oft, sehr viele Herangehensweisen.

Ich würde mir dazu einfach alle Buttons initialisieren lassen und die random erzeugten Werte (dabei müsstest du darauf achten, dass keine Zahl mehrfach vorkommt, das wäre aber auch schon das schwierigste denke ich ^^) in eine List schreiben.

Die Liste sortieren und dann kannst du von vorne weg immer die Zahlen wegknipsen ^^

 

Hast du also eine sortierte Liste, musst du eig nur immer den Feldwert gegen List[0] prüfen und weißt, ob das jetzt stimmt oder nicht.

Also hast du z.B. ein 2x3 Spielfeld und erzeugst 6 Zufallszahlen, hättest du vllt am Ende so eine Liste:

2 , 47 , 19 , 8 , 12 , 7

 

Daraus ergibt sich dann das Spielfeld:

2 47 19

8 12 7

 

Die Werte sind ja schon in den Buttons gespeichert also kannst du die Liste auch verändern wie du lustig bist.

Die Liste dann sortieren, dann kommt sowas raus:

2, 7, 8, 12, 19, 47

 

Und dann musst du nur noch sowas machen:

if(ButtonIsPressed){
  if(Button.Text == List[0]){
  ChangeScore(true);
  ChangeButtonAppearance(true);
  // Dinge die man vielleicht sonst noch machen will
  List.RemoveAt(0);
  }
  else{
     ChangeScore(false);
     ChangeButtonAppearance(false);
  }
}

 

Also.. so würde ich das jetzt angehen :D

 

Zum Code:

In ChangeScore() würde ich einfach eine if-else Verzweifung einbauen, falls die Wahl richtig oder falsch war.

Genau so bei ChangeButtonAppearance(). Deshalb die true bzw. false Parameter.

 

Bei true würde dann der Score hochgezählt werden (ChangeScore) bzw. der Button vllt grün erscheinen oder ausgeblendet werden oder was auch immer du da gedacht hast (ChangeButtonAppearance) und bei false würde eben der Score runtergezählt(ChangeScore) oder was du hald da implementieren willst bzw. der Button dann vllt rot markiert oder ähnliches. (ChangeButtonAppearance)

 

Um die Zeit zu messen hättest du jetzt auch ein paar Möglichkeiten.

Am einfachsten wäre wohl zu Beginn des Levels eine Stopwatch zu erzeugen und zu starten und sobald alle Buttons richtig geklickt wurden stoppst du sie wieder..

Gibt dir die Zeit sehr präzise in Millisekunden ^^

Die Überprüfung ob alles richtig geklickt wurde kannst du ja dann z.B. in der Update laufen lassen und schauen ob die Liste noch min. 1 Element hat. Wenn der Count auf 0 steht kannst du die ganze restliche Logik ablaufen lassen..

Neustart button anzeigen, score speichern,...

Share this post


Link to post
Share on other sites

Hallo exestend,

 

da gibt es mehrere Ansätze, solltest du es nicht als reine GUI-Lösung realisieren wollen (siehe der obige Vorschlag von Tiwaz), dann könntest du einfache Cube Primitive nehmen und einen Cube mit einem 3DText Objekt (das die jeweilige Zahl trägt) kombinieren (indem du z.b. beide Objekte in ein entsprechend benanntes GameObject - das hierbei als Container fungiert - steckst). Über einen Raycast von der Mausposition des Spielers ausgehend könntest du dann den angeklickten Collider des zugehörigen Cubes inklusive seines Containers identifizeren.

 

Viele Grüße,

zero

  • Like 1

Share this post


Link to post
Share on other sites

Danke für eure Beiträge. Genau das ist es ja, was mir zu schaffen macht. Ein wenig. So viele Möglichkeiten. Es ist für mich schwierig, da einen guten Anfang zu finden.

 

Die Cubes sollen ja zufällige Werte beim Start des Spieles benötigen.

Das heißt, dass ich z.B. 6 Cubes erstelle.

Die Cubes bekommen ja jeweils dann den Namen Cube1,Cube2,Cube3,Cube4,Cube5,Cube6

Diese private Var würde ich dann auch so anlegen:

private cube1
private cube2
private cube3
private cube4
private cube5
private cube6

 

Dann habe ich meine Variablen. Denen muss ich dann ja Werte zuweisen.

Random rnd = new Random();
int cube1= rnd.Next(0, 20)
int cube2= rnd.Next(0, 20)
int cube3= rnd.Next(0, 20)
int cube4= rnd.Next(0, 20)
int cube5= rnd.Next(0, 20)
int cube6= rnd.Next(0, 20)

 

Dann sollten die Variablen Werte haben.

 

Diesen Wert muss ich dann noch dem Text zuweisen.

GetComponent<TextMesh>().text = cube1;

 

Soweit bin ich in der Theorie. Das ganze wäre mit Arrays aber sicherlich wie schon erwähnt leichter.

Share this post


Link to post
Share on other sites

Das ganze wäre mit Arrays aber sicherlich wie schon erwähnt leichter.

Du kannst da noch ungefähr alle anderen positiven Adjektive dranhängen, die in der Software-Entwicklung eine Rolle spielen :D

 

Ein Kernpunkt der Entwicklung mit Unity kommt hier noch nicht so ganz durch: Komponenten.

Mit Unity vermeidet man es nach Möglichkeit, ein Skript zu schreiben, das mehrere Objekte steuert.

 

Anstatt also ein Skript zu bauen, das allen Cubes Zahlen gibt, kriegt jeder Cube eine Instanz desselben Skripts, mit dem er sich selbst eine Zahl gibt.

 

void Start()
{
 GetComponent<TextMesh>().text = Random.Range(0,20);
}

Die "Random"-Klasse in dem Code ist übrigens UnityEngine.Random, nicht System.Random.

 

Im Weiteren kannst du dann mit static arbeiten.

So kannst du z.B. am Anfang zählen, wie viele Cubes es gibt, und wird ein Cube gelöscht, davon wieder abziehen:

private static int cubesLeft = 0;

void Awake()
{
 cubesLeft++;
}

void OnDestroy()
{
 cubesLeft--;
}

 

Je nach dem, ob der Spieler falsche Cubes anklicken kann oder nicht, kannst du mit einem statischen int (letzte angeklickte Zahl, die nächste muss höher sein) oder einer statischen Liste (alle restlichen Cubes stehen in der richtigen Reihenfolge darin, der angeklickte muss der erste in der Liste sein) arbeiten.

  • Like 2

Share this post


Link to post
Share on other sites

Für den "leichten" Einstieg macht es sehr viel Sinn der objektorientieren Philosophie von Unity zu folgen. Das bedeutet eine "Cube-Containerinstanz" (ich kürze mal CCI ab) bestehend z.b. aus einem Container (Gameobject als Parent), einem Textmesh und einem Cube Primitive inklusive Collider als ein Objekt zu betrachten und dieses Verbundobjekt über an das Parent angehängte Skripte zu steuern. Des weiteren ist es sinnvoll einen Controller (leeres GameObject + Skripte) zu erstellen, der diese Objekte dann in der Szene verwaltet und steuert. Damit erzeugt der Controller die CCIs und verarbeitet ebenfalls eine Klickaktion des Players auf eine CCI (via SendMessage an den Controller). Leider ist aus Performancesicht das Anhängen eines Skriptes pro Objekt - vor allem wenn es sehr viele werden - wieder eher schlecht, hier verschiebt man das ursprünglich an den Objekten hängende Skript an die Controllerinstanz, die dann durch die existierenden Objekte in der Scene iteriert und die Aktionen an den CCIs ausführt. Allerdings ist bei deinem Vorhaben die Menge an Instanzen sehr überschaubar und daher ist es viel einfacher und natürlicher die CCIs über ein oder mehrere Skripte am Parent der CCIs zu steuern.

  • Like 1

Share this post


Link to post
Share on other sites

Das bedeutet eine "Cube-Containerinstanz" (ich kürze mal CCI ab) bestehend z.b. aus einem Container (Gameobject als Parent), einem Textmesh und einem Cube Primitive inklusive Collider als ein Objekt zu betrachten und dieses Verbundobjekt über an das Parent angehängte Skripte zu steuern.

 

Hi, ich sehe nicht ganz den Vorteil davon, dem Würfel noch ein leeres Parent GameObject zu geben und das Skript daran zu hängen.

Warum nicht das Skript (das ja für den / die Würfel geschrieben worden ist) direkt an das Würfel Object hängen?

So hätte (ähm... habe) ich das gemacht bisher....

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...