Aufgabe 2 war es, das Spiel “Lights Out” nachzuprogrammieren. Es funktioniert folgendermaßen:Eine Tastenmatrix mit den Dimensionen a * b besteht aus kleinen Leuchtdioden. Drückt man nun auf eine der Dioden, wird diese und alle umliegenden Lampen umgeschalten. Ziel ist es, alle Lampen aus zu schalten.
Im zweiten Spielmodus ist das Ziel das gleiche, allerdings wird auf Tastendruck das Rechteck links über der betätigten Taste umgeschalten. Das ganze habe ich in der Game-Engine Unity umgesetzt. Diese ist in der Grundversion frei zugänglich und bietet vorgefertigte Bausteine wie eine Render-Engine oder Physik-Skripte. Die eigene Spiellogik implementiert man dort mit kleinen C#- oder Javascripts, die dann von sog. GameObjects ausgeführt wird. Nachdem man im Hauptmenü die Dimensionen des Spielfelds sowie den Spielmodus angibt, öffnet sich eine neue Szene. Nun werden in dieser mithilfe des folgenden Skripts a*b Buttons erzeugt, die unsere Leuchtdioden darstellen sollen:

void Start () {
	var width = GameObject.Find("SettingsCarrier").GetComponent<Settings>().width;
	var height = GameObject.Find("SettingsCarrier").GetComponent<Settings>().height;

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			GameObject o = Instantiate(prefab, new Vector2(x*factor-width/2f*factor, y*factor-height/2f*factor), Quaternion.identity) as GameObject;
			o.transform.parent = transform;
		}
	}
}

Als ich diesen Code erstellt habe, wusste ich noch nicht dass sich aus jeder Klasse auch ein Array dieser erzeugen lässt. Würde ich das Spiel heute entwickeln, dann würde ich die Buttons in einem zweidimensionalen Array speichern. Dies würde den nächsten Abschnitt vollkommen überflüssig machen.

Damit die Buttons auch etwas tuen, wenn man auf sie klickt, muss man die Methode “OnMouseDown()” benutzen. In ihr wird in meinem Projekt also zuerst die eigene Position bestimmt und dann abhängig vom Spielmodus die anderen Buttons umgeschalten.Die Schwierigkeit ist es, aus dem Index einer Lampe die Position derselbigen zu errechnen. Dies geschieht mithilfe von Modulo sowie der ganzzahligen Division.
Wenn die errechneten Positionen dann auch noch existieren (um IndexOutOfBounds vorzubeugen), werden sie umgeschalten.

void OnMouseDown(){
	
	 var width = GameObject.Find("SettingsCarrier").GetComponent<Settings>().width;   //Breite
	 var height = GameObject.Find("SettingsCarrier").GetComponent<Settings>().height; //Höhe
 
	 int selfI = transform.parent.root.GetChild(transform.GetSiblingIndex()).GetSiblingIndex(); //Index self
 
	 int iHor = selfI % width;
	 int iVer = selfI / width;
 
	switch (GameObject.Find("Start").GetComponent<onClick>().gamemode) {      //Switch wg Game-Mode
		case 0:     //Spielmodus
			// linker Nachbar:
			if (iHor > 0)
			{
				transform.parent.root.GetChild(iVer * width + iHor - 1).GetComponent<Switch>().change();
			}
					
			// rechter Nachbar:
			if (iHor < width-1)
			{
				transform.parent.root.GetChild(iVer * width + iHor + 1).GetComponent<Switch>().change();
			}

			// unterer Nachbar:
			if (iVer > 0)
			{
				transform.parent.root.GetChild((iVer - 1) * width + iHor).GetComponent<Switch>().change();
			}

			// oberer Nachbar:
			if (iVer < height-1)
			{
				transform.parent.root.GetChild((iVer + 1) * width + iHor).GetComponent<Switch>().change();
			}

			// eigenen Status ändern
			change();
			break;
				
		case 1:     //Alt. Spielmodus
			for(int x = 0; x<= iHor; x++){
				for (int y = 0; y < height - iVer; y++){
					transform.parent.root.GetChild(transform.GetSiblingIndex() -x +y*width).GetComponent<Switch>().change();
				}
			}

			break;

		case 2:         //Erstellung Spielfeld
			change();
			break;
	 }
 }

Um zu prüfen, ob der Spieler gewonnen hat, wird nach jeder Interaktion geprüft, ob alle Buttons aus sind. Sind sie das, so wird die Gewinner-Szene geladen.</p>

void Update(){
	bool gewinn = true;
	for (int i = 0; i < GameObject.Find("SettingsCarrier").GetComponent<Settings>().width * GameObject.Find("SettingsCarrier").GetComponent<Settings>().height; i++){
    	if (!GameObject.Find("Holder").transform.GetChild(i).GetComponent<Switch>().state){
        	gewinn = false; }
 		}
 
	if (gewinn && GameObject.Find("Start").GetComponent<onClick>().gamemode != 2){
    	UnityEngine.SceneManagement.SceneManager.LoadScene("Win");
	}
}