leicht gemacht: Cocos2d und Menus

Der Vorteil eines Frameworks wie Cocos2d ist, dass viele Funktionen die eine App erst vollständig machen, bereits enthalten und einfach zu konfigurieren sind. So ist es mit Cocos2d zum Beispiel sehr einfach ein Menu zu erstellen.

Die geschieht mit Objekten der Klassen CCMenu und CCMenuItem. Das CCMenuItem stellt dabei einen Knopf dar, während das CCMenu die einzelnen Knöpfe zu einer logischen Einheit zusammenfasst.

//create Button 
CCMenuItem *startButton = [CCMenuItemImage itemFromNormalImage:@"start.png" 
				selectedImage:@"start_pressed.png" 
				target:self 
				selector:@selector(startMethod)];

startButton.position = ccp(240,180);

Wir haben mit dem obenstehenden Code einen Knopf erstellt, welcher das Aussehen des Bildes „start.png“ hat. Es ist sogar möglich das Aussehen des Knopfes zu ändern, wenn der Benutzer ihn drückt (selectedImage:@“start_pressed.png“).

Wenn der Nutzer auf den Knopf drück wird in der aktuellen Klasse (target:self) die Methode „startMethod“ aufgerufen. Selbstverständlich kann hier auch die Methode einer anderen Klasse als target angegeben werden:

//create Button 
CCMenuItem *startButton = [CCMenuItemImage itemFromNormalImage:@"start.png" 	
				selectedImage:@"start.png" 
				target:eineAndereKlasse 
				selector:@selector(startMethod)];

startButton.position = ccp(240,180);

Allerdings sehen wir im Moment noch gar keinen Menuknopf – uns fehlt noch das Menu:

CCMenu mainMenu = [CCMenu menuWithItems: startButton, nil];
mainMenu.position = CGPointZero;
[self addChild:mainMenu];

Damit können wir wahrscheinlich 90% unserer Menus bauen. Für alle Fortgeschrittenen folgen nun noch ein paar besondere Kniffe, die euch eventuell mal begegnen werden.

Knöpfe später hinzufügen

Manchmal ist es notwendig, dass gewisse Knopfe erst während der Laufzeit angezeigt werden. Eventuell soll vorher ein Bild angezeigt werden, auf dem steht z.B. „Löse erst Aufgabe 1“
Auch dies ist in Cocos2d möglich.

if (buttonCanBePressed) {
   CCMenuItem *continueButton = [CCMenuItemImage itemFromNormalImage:@"continue.png" 							
                                        selectedImage:@"continue.png" 
					target:eineAndereKlasse 
				        selector:@selector(continueMethod)];

    continueButton.position = ccp(240,180);
    [mainMenu addChild: continueButton];
} else {
    CCSprite *continueSprite = [CCSprite spriteWithFile:@"noContinue.png"];
    continueSprite.position = ccp(240,180);
    [self addChild: continueSprite];
}

Über die boolsche Variable buttonCanBePressed entscheidet sich, ob nur ein Bild angezeigt wird (else-Zweig) oder direkt der Knopf. Natürlich muss das mainMenu hier bereits erstellt und zu self hinzugefügt worden sein.

ein Menu inaktiv schalten

Ein Menu kann auch kurzfristig deaktiviert werden, ohne dass es komplett entfernt werden muss:

// inaktiv setzten
mainMenu.enabled = NO;

// aktiv setzten
mainMenu.enabled = YES;

Aufrufenden Knopf übergeben

Als Programmierer will man natürlich eine Methode sooft wie möglich wiederverwenden können. Eventuell muss man in der aufgerufenen Methode trotzdem wissen, wer der Aufrufende war. Dazu können wir uns der Möglichkeit bedienen den aufrufenden Knopf zu übergeben.

//create Button 1
CCMenuItem *startButton = [CCMenuItemImage itemFromNormalImage:@"start.png" 
					selectedImage:@"start.png" 
					target:self 
				        selector:@selector(startMethod:)];
startButton.position = ccp(240,180);
startButton.userData = 0;

//create Button 2
CCMenuItem *startButton = [CCMenuItemImage itemFromNormalImage:@"start_with_powerup.png" 							
                                        selectedImage:@" start_with_powerup.png" 
					target:self 
					selector:@selector(startMethod:)];
startButton.position = ccp(240,180);
startButton.userData = 5;

- (void) startMethod:(id)sender
{
	// sender einem Typ zuweisen
        CCMenuItem *item = (CCMenuItem *)sender;
	int index = (int)item.userData;

	if( index == 5){
		// etwas cooles machen

	} else {
		// etwas großartiges machen
	}
}

 Menus auf Textbasis

Natürlich muss nicht immer ein Bild genommen werden um einen Menuknopf darzustellen, auch wenn ich das empfehle. Der Grund ist relativ simpel: Bei einem Bild könenn wir die Größe und damit den klickbaren Bereich selbst bestimmen und Fehlbedienungen  vorbeugen. Bei Textmenus muss eben nur der Text  klickbar.

Wenn Textmenus genutzt werden achtet bitte darauf, dass die Schriftgröße groß genug gewählt wird.

Hier der Quellcode. Das CCMenuItem wird einfach durch CCMenuItemLabel ersetzt.

// Default font size will be 22 points.
[CCMenuItemFont setFontSize:22];

CCMenuItemLabel *galleryItem = [CCMenuItemFont itemWithString:@"Start" block:^(id sender){
		[self startGame];
	}];

CCMenuItemLabel *highscoreItem = [CCMenuItemFont itemWithString:@"Highscore" block:^(id sender){
		[self showHighscore];
	}];

CCMenuItemLabel *optionsItem = [CCMenuItemFont itemWithString:@"Optionen" block:^(id sender){
		[[CCDirector sharedDirector] replaceScene: [Option scene]];
	}];

CCMenu *menu = [CCMenu menuWithItems:galleryItem, nil];

[mainMenu alignItemsVertically];
mainMenu.position = ccp(240,180);
[self addChild:mainMenu z:0];

}

Bis zum nächsten mal,
alles Gute.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.