Dit is het zevende en laatste deel van onze Cocos2D-lessenreeks over het klonen van Centipede voor iOS. Zorg ervoor dat je de voorgaande delen hebt voltooid voordat je begint.
In de laatste zelfstudie hebben we besproken hoe eenvoudige botsingsdetectie kan worden uitgevoerd tussen alle objecten in onze game.
In de tutorial van vandaag zullen we de dingen inpakken door het bespreken van de scores, voorwaarden voor winnen, game-audio en game over-scherm.
Vanaf nu, wanneer je de rups vernietigt, gebeurt er niets. De manier om verder te komen is door het niveau te verhogen en opnieuw op te starten met enkele nieuwe spruiten en een nieuwe rups. Dit is gemakkelijk te bereiken omdat we het spel hebben opgebouwd om dit vanaf het begin te ondersteunen. Open GameLayer.m en voeg de volgende methode toe:
- (void) checkNextLevel if ([self.caterpillars count] == 0) // 1 self.level ++; // 2 // 3 CGPoint startingPosition = ccp (kGameAreaStartX, kGameAreaHeight + kGameAreaStartY - kGridCellSize / 2); Caterpillar * caterpillar = [[[Caterpillar alloc] initWithGameLayer: self level: self.level position: startingPosition] autorelease]; [self.caterpillars addObject: caterpillar]; // 4 int minSproutCount = kStartingSproutsCount + self.level * 2; if ([self.sprouts count] < minSproutCount) int numberOfSproutsToPlace = minSproutCount - [self.sprouts count]; for(int x = 0; x < numberOfSproutsToPlace; x++) [self placeRandomSprout];
Nu we de methode hebben geïmplementeerd, moeten we het elke keer dat de rups geraakt wordt noemen. Binnenkant van de splitCaterpillar: atSegment:
methode, voeg de volgende regel toe vóór de return-opdracht in de eerste if-instructie:
if ([caterpillar.segments count] == 1) // ... // Voeg deze regel toe [self checkNextLevel]; terug te keren;
Dit is de toestand wanneer de rups slechts een enkel segment is. Voeg het hier naast het toevoegen ook toe helemaal onderaan deze methode. Dat zou alle gevallen moeten omvatten.
Als je het spel nu uitvoert, zou je oneindig moeten kunnen spelen met de snelheid van de rups die op elk niveau toeneemt.
In het spel zijn er verschillende plaatsen waar de speler zijn score kan verhogen. Zij zijn:
We gaan nogal wat rondspringen om scoring toe te voegen aan elk van deze acties, zo kaal met mij.
Voordat we beginnen met het bijwerken van de score, moeten we nog drie constanten definiëren die de basis zijn voor het scoren. Open GameConfig.h en voeg de volgende 3 regels toe:
#define kSproutHitPoints 25 #define kCaterpillarHitPoints 200 #define kNextLevelPoints 1000
Je zult zien hoe deze worden gebruikt als we iets verder in deze tutorial komen.
Laten we beginnen met het toevoegen aan de spelerscore als ze een sprout in het spel raken. Open Missile.m, importeer Player.h en voeg de volgende code toe aan de binnenkant van de lus die controleert op een botsing met een sprout:
self.gameLayer.player.score + = kSproutHitPoints + (arc4random ()% self.gameLayer.level) * (arc4random ()% self.gameLayer.level); [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore object: nil];
Dit verhoogt de spelerscore op basis van de basispunten en enige mate van willekeur op basis van het huidige niveau. Op die manier krijgen ze meer punten voor het uitschakelen van de spruiten.
Zoals we deden bij het opstellen van de beginscore, moeten we een melding plaatsen die het scorelabel van de speler zal bijwerken. Dit gebeurt bij elke score-update. Als je het spel nu uitvoert, zou je het scorelabel van de speler moeten zien updaten elke keer dat je een sprout raakt.
De volgende plaats die we gaan scoren is wanneer de rups geraakt wordt. Helemaal onderaan de bijwerken:
methode in Missile.m, voeg de volgende code toe voordat je de rups splitst:
if (hitCaterpillar && hitSegment) // Voeg deze regels toe self.gameLayer.player.score + = kCaterpillarHitPoints + (arc4random ()% self.gameLayer.level) * (arc4random ()% self.gameLayer.level); [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore object: nil]; // ... code om de rups te splitsen ...
Deze code is niet veel anders dan wat je hierboven zag. De laatste plaats om scoren toe te voegen is wanneer de speler op niveau gaat. Deze code wordt in de checkNextLevel
methode die je hierboven hebt geschreven. Open GameLayer.m, navigeer naar checkNextLevel
methode en voeg de volgende code toe net na de if-instructie:
self.player.score + = kNextLevelPoints * self.level; [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore object: nil];
Geen verrassingen hier. Als je wat variatie wilt toevoegen aan de score in je eigen spel, voel je dan vrij om de score te wijzigen.
Vanaf nu heeft je speler de Game Genie ingeschakeld en heeft hij oneindige levens. We moeten dat veranderen. Maak eerst een nieuw bestand met de naam GameOverLayer.m dat CCLayer uitbreidt.
Voeg de volgende code toe aan GameOverLayer.h:
#import "cocos2d.h" #import "GameConfig.h" @interface GameOverLayer: CCLayer @property (nonatomic, assign) NSInteger-score; @property (nonatomic, retain) CCLabelTTF * scoreLabel; @property (nonatomic, retain) CCLabelTTF * highScoreLabel; + (CCScene *) scène Met Score: score (NSInteger); @einde
Ik zal uitleggen wat elk van deze eigenschappen en methodes tijdens de implementatie doet. Voeg nu de volgende code toe aan GameOverLayer.m
#import "GameOverLayer.h" #import "GameLayer.h" #import "SimpleAudioEngine.h" @implementation GameOverLayer @synthesize score = _score; @synthesize scoreLabel = _scoreLabel; @ synthetiseer highScoreLabel = _highScoreLabel; // 1 + (CCScene *) sceneWithScore: (NSInteger) score // 'scene' is een object autorelease. CCScene * scène = [CCScene knooppunt]; // 'layer' is een object autorelease. GameOverLayer * layer = [GameOverLayer node]; layer.score = score; // laag toevoegen als een kind om te scčne [scène addChild: laag]; // geef de scènereeks terug; // 2 - (void) dealloc [_oscoreLabel release]; [_highScoreLabel release]; [super dealloc]; - (id) init if ((self = [super init])) // 3 [CCTexture2D setDefaultAlphaPixelFormat: kCCTexture2DPixelFormat_RGB565]; CCSprite * background = [CCSprite spriteWithFile: @ "game-over.png"]; background.anchorPoint = ccp (0,0); [self addChild: achtergrond]; // 4 _scoreLabel = [[CCLabelTTF labelWithString: @ "0" dimensions: CGSizeMake (320, 30) alignment: UITextAlignmentCenter fontName: @ "Helvetica" fontSize: 30] behouden]; _scoreLabel.anchorPoint = ccp (0,0); _scoreLabel.position = ccp (0,155); [self addChild: _scoreLabel]; _highScoreLabel = [[CCLabelTTF labelWithString: [NSString stringWithFormat: @ "High:% d", 0] dimensions: CGSizeMake (320, 35) alignment: UITextAlignmentCenter fontName: @ "Helvetica" fontSize: 30] behouden]; _highScoreLabel.anchorPoint = ccp (0,0); _highScoreLabel.color = (ccColor3B) 255,0,0; _highScoreLabel.position = ccp (0,195); [self addChild: _highScoreLabel]; // 5 [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES]; [[SimpleAudioEngine sharedEngine] playEffect: @ "game-over.caf"]; terugkeer zelf; - (void) setScore: (NSInteger) score _score = score; self.scoreLabel.string = [NSString stringWithFormat: @ "Score:% d", _ score]; // 6 NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; NSInteger highScore = [standaard integerForKey: @ "Centipede Highcore"]; // 7 if (score> highScore) highScore = score; [standaardinstellingen setInteger: score forKey: @ "Centipede Highcore"]; [standaardsynchronisatie]; self.highScoreLabel.string = [NSString stringWithFormat: @ "High:% d", highScore]; // 8 - (BOOL) ccTouchBegan: (UITouch *) touch withEvent: (UIEvent *) gebeurtenis [[CCDirector sharedDirector] replaceScene: [CCTransitionFade transitionWithDuration: .5 scene: [GameLayer-scène] withColor: ccWHITE]]; terugkeer JA; @end
Hier is een screenshot van wat dit scherm is moeten ziet eruit als:
De laatste stap is om GameLayer.m te openen en de volgende regels toe te voegen aan het einde van de updateLives
methode:
if (lifeCount == 0) [[CCDirector sharedDirector] replaceScene: [CCTransition Fade transitionWithDuration: .5 scene: [GameOverLayer sceneWithScore: self.player.score] withColor: ccWHITE]];
Hiermee wordt gecontroleerd of de levens zijn ingesteld op 0. Als dit het geval is, vervangen we de huidige scène door de scène voor Game Over.
De laatste stap in onze game polish is om geluid toe te voegen. Download eerst de onderstaande geluiden en voeg ze toe aan uw project:
GameSounds.zip
Traditioneel was het omgaan met geluid een hele klus in een OpenGL-game. Je zou iets moeten gebruiken als OpenAL of een andere gecompliceerde C ++ -bibliotheek. Cocos2D heeft de zaken enorm vereenvoudigd met hun SimpleAudioEngine
bibliotheek. Het geeft je de mogelijkheid om gemakkelijk loopende achtergrondmuziek en snelle geluiden te spelen.
Nogmaals, we gaan behoorlijk wat rondspringen. Dus, als de plaatsing van een code niet duidelijk is voor jou, vraag het me dan in de comments of verwijs naar de broncode van deze tutorial.
Open AppDelegate.m en importeer SimpleAudioEngine.h en voeg de volgende regel toe aan de onderkant van de applicationDidFinishLaunching
methode.
[[SimpleAudioEngine sharedEngine] playBackgroundMusic: @ "background.caf"]; i
Dat is het! Er is slechts één regel nodig om onze achtergrondmuziek gedurende de speeltijd af te spelen. Nu moeten we alleen geluidseffecten afspelen als reactie op verschillende acties.
In Caterpillar.m, wanneer de Caterpillar botst met de speler (tegen het einde van de bijwerken:
methode):
[[SimpleAudioEngine sharedEngine] playEffect: @ "player-hit.caf"];
In Missile.m, wanneer de raket de sprout raakt:
[[SimpleAudioEngine sharedEngine] playEffect: @ "sprout-hit.caf"];
Ook in Missile.m, wanneer de raket de Caterpillar raakt:
[[SimpleAudioEngine sharedEngine] playEffect: @ "caterpillar-hit.caf"];
In de methode init in GameOverLayer.m:
[[SimpleAudioEngine sharedEngine] playEffect: @ "game-over.caf"];
Dat zou alle geluiden moeten dekken die ik in de game heb gebruikt. Zorg er ook voor dat u SimpleAudioEngine.h importeert in elk van de bovenstaande klassen.
Dit concludeert de 7-delige instructiereeks over het maken van een Caterpillar-spel met Cocos2D voor de iPhone. Inmiddels zou je een goed begrip moeten hebben van hoe je een eenvoudig spel kunt ontwerpen en bouwen met de Cocos2D-game-engine. Als u vragen of opmerkingen heeft, kunt u deze hier achterlaten in het opmerkingengedeelte of ze op Twitter schrijven.
Happy codering!