Bygg et Caterpillar spill med Cocos2D Endelige trinn

Dette er den syvende og siste delen av vår Cocos2D opplæringsserie om kloning av Centipede for iOS. Pass på at du har fullført de forrige delene før du begynner.

Sist…

I den siste opplæringen diskuterte vi hvordan du gjør enkel kollisjonssensing mellom alle objektene i spillet vårt.

I dagens veiledning vil vi pakke opp ting ved å diskutere scoring, vinnende forhold, spill lyd og spill over skjermen.


Trinn 1: Fremme spillet

Fra nå av, når du ødelegger larven, skjer ingenting. Veien fremover er å øke nivået og starte på nytt med noen nye spirer og en ny larve. Dette er lett oppnådd ettersom vi har bygd spillet for å støtte dette siden begynnelsen. Åpne GameLayer.m og legg til følgende metode:

 - (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: selvnivå: self.level posisjon: startingPosition] autorelease]; [self.caterpillars addObject: caterpillar]; // 4 int minSproutCount = kStartingSproutsCount + self.level * 2; hvis ([self.sprouts count] < minSproutCount)  int numberOfSproutsToPlace = minSproutCount - [self.sprouts count]; for(int x = 0; x < numberOfSproutsToPlace; x++)  [self placeRandomSprout];    
  1. Sjekk om det er noen larver igjen
  2. Øk nivået
  3. Opprett en ny caterpillar og legg den til spillet (basert på det nye nivået)
  4. Legg til spirer for å matche minSproutCount

Nå som vi har implementert metoden, må vi ringe det hver gang larven blir rammet. Innsiden av splitCaterpillar: atSegment: metode, legg til følgende linje før returoppgaven innsiden av den første hvis setningen:

 hvis ([caterpillar.segments count] == ​​1) // ... // Legg denne linjen [self checkNextLevel]; komme tilbake; 

Dette er tilstanden når larven er bare et enkelt segment. I tillegg til å legge det til her, legg det til selve bunnen av denne metoden også. Det skal dekke alle tilfellene.

Hvis du kjører spillet på dette tidspunktet, bør du være i stand til å spille uendelig med hastigheten på larven som øker på hvert nivå.


Trinn 2: Scoring

Innenfor spillet er det flere steder hvor spilleren kan øke sin score. De er:

  • Slår en spire
  • Slår på larven
  • Fremme til neste nivå

Vi skal hoppe ganske mye for å legge til poengsum for hver av disse handlingene, så bare med meg.

Før vi begynner å oppdatere poengsummen, må vi definere tre flere konstanter som vil være utgangspunktet for scoring. Åpne GameConfig.h og legg til følgende 3 linjer:

 #define kSproutHitPoints 25 #define kCaterpillarHitPoints 200 #define kNextLevelPoints 1000

Du vil se hvordan disse brukes som vi får litt videre inn i denne opplæringen.

La oss begynne med å legge til spillerens poengsum når de treffer en spire i spillet. Åpne opp Missile.m, importer Player.h, og legg til følgende kode innsiden av sløyfen som kontrollerer for en kollisjon med spire:

 self.gameLayer.player.score + = kSproutHitPoints + (arc4random ()% self.gameLayer.level) * (arc4random ()% self.gameLayer.level); [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore objekt: null];

Dette øker spillerens poengsum basert på basispunkter og en viss tilfeldighet basert på dagens nivå. På den måten, når spilleren går opp på nivå, får de flere poeng for å ta ut spirene.

Som vi gjorde da vi satte opp første poengsum, må vi legge inn et varsel som vil oppdatere spillerens poenglabel. Dette er gjort på hver scoring oppdatering. Hvis du kjører spillet på dette punktet, bør du se spillerenes poengsuml oppdatering hver gang du treffer en spire.

Det neste stedet vi skal legge til scoring er når larven er truffet. På selve bunnen av Oppdater: metode i Missile.m, legg til følgende kode før du sperrer larven:

 hvis (hitCaterpillar && hitSegment) // Legg til disse linjene self.gameLayer.player.score + = kCaterpillarHitPoints + (arc4random ()% self.gameLayer.level) * (arc4random ()% self.gameLayer.level); [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore objekt: null]; // ... kode for å dele larven ...

Denne koden er ikke mye annerledes enn hva du så over. Det endelige stedet å legge til scoring er når spilleren beveger seg på nivå. Denne koden vil bli plassert inne i checkNextLevel metode som du skrev over. Åpne GameLayer.m, naviger til checkNextLevel metode og legg til følgende kode like etter if-setningen:

 self.player.score + = kNextLevelPoints * self.level; [[NSNotificationCenter defaultCenter] postNotificationName: kNotificationPlayerScore objekt: null];

Ingen overraskelser her. Hvis du vil legge til litt variasjon i scoring i ditt eget spill, er du velkommen til å endre poengverdiene.


Trinn 3: Spill over

Fra nå av har spilleren Game Genie på og har uendelig liv. Vi må endre det. Først oppretter du en ny fil som heter GameOverLayer.m som utvider CCLayer.

Legg til følgende kode Til GameOverLayer.h:

 #import "cocos2d.h" #import "GameConfig.h" @interface GameOverLayer: CCLayer @property (nonatomic, assign) NSInteger score; @property (ikkeatomisk, behold) CCLabelTTF * scoreLabel; @property (ikkeatomisk, behold) CCLabelTTF * highScoreLabel; + (CCScene *) sceneWithScore: (NSInteger) poengsum; @slutt

Jeg vil forklare hva hver av disse egenskapene og metodene gjør under implementeringen. Legg nå følgende kode til GameOverLayer.m

 #import "GameOverLayer.h" #import "GameLayer.h" #import "SimpleAudioEngine.h" @implementation GameOverLayer @synthesize score = _score; @synthesize scoreLabel = _scoreLabel; @synthesize highScoreLabel = _highScoreLabel; // 1 + (CCScene *) sceneWithScore: (NSInteger) poengsum // 'scene' er en autorelease-objekt. CCScene * scene = [CCScene node]; // 'lag' er en autorelease-objekt. GameOverLayer * layer = [GameOverLayer node]; layer.score = score; // legg lag som barn til scene [scene addChild: lag]; // returnere scenen tilbake scenen;  // 2 - (void) dealloc [_scoreLabel release]; [_highScoreLabel release]; [super dealloc];  - (id) init hvis ((selv = [super init])) // 3 [CCTexture2D setDefaultAlphaPixelFormat: kCCTexture2DPixelFormat_RGB565]; CCSprite * background = [CCSprite spriteWithFile: @ "game-over.png"]; background.anchorPoint = ccp (0,0); [self addChild: background]; // 4 _scoreLabel = [[CCLabelTTF labelWithString: @ "0" dimensjoner: CGSizeMake (320, 30) justering: UITextAlignmentCenter fontName: @ "Helvetica" fontSize: 30] behold]; _scoreLabel.anchorPoint = ccp (0,0); _scoreLabel.position = ccp (0,155); [self addChild: _scoreLabel]; _highScoreLabel = [[CCLabelTTF labelWithString: [NSString stringWithFormat: @ "Høy:% d", 0] dimensjoner: CGSizeMake (320, 35) justering: UITextAlignmentCenter fontName: @ "Helvetica" fontSize: 30] behold]; _highScoreLabel.anchorPoint = ccp (0,0); _highScoreLabel.color = (ccColor3B) 255,0,0; _highScoreLabel.position = ccp (0,195); [self addChild: _highScoreLabel]; // 5 [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: selvprioritet: 0 swallowsTouches: YES]; [[SimpleAudioEngine sharedEngine] playEffect: @ "game-over.caf"];  returner selv;  - (void) setScore: (NSInteger) poengsum _score = score; self.scoreLabel.string = [NSString stringWithFormat: @ "Score:% d", _ score]; // 6 NSUserDefaults * standard = [NSUserDefaults standardUserDefaults]; NSInteger highScore = [standard integerForKey: @ "CentipedeHighScore"]; // 7 hvis (score> highScore) highScore = score; [standardinnstillinger setInteger: score forKey: @ "CentipedeHighScore"]; [standard synkronisere];  self.highScoreLabel.string = [NSString stringWithFormat: @ "Høy:% d", highScore];  // 8 - (BOOL) ccTouchBegan: (UITouch *) berør medEvent: (UIEvent *) hendelse [[CCDirector sharedDirector] replaceScene: [CCTransitionFade transitionWithDuration: .5 scene: [GameLayer scene] withColor: ccWHITE]]; returnere JA;  @slutt
  1. Dette er vår standard metode for å sette opp en ny scene. Den eneste forskjellen er at den tar en NSInteger og setter den til nåværende poengsum.
  2. Rydde opp
  3. Gi bakgrunnen
  4. Sett opp etikettene for å vise poengsummen og høy poeng
  5. Aktiver berøringer
  6. Se opp høy poengsum
  7. Sammenlign ny poengsum til høyeste poengsum, lagre den nye poengsummen hvis den er høyere.
  8. Start et nytt spill hvis spilleren berører skjermen

Her er et skjermbilde av hva denne skjermen bør ser ut som:

Det siste trinnet er å åpne GameLayer.m og legge til følgende linjer til slutten av updateLives metode:

 hvis (lifeCount == 0) [[CCDirector sharedDirector] replaceScene: [CCTransitionFade transitionWithDuration: .5 scene: [GameOverLayer sceneWithScore: self.player.score] withColor: ccWHITE]]; 

Dette kontrollerer om livene er satt til 0. Hvis så, erstatter vi gjeldende scene med Game Over-scenen.


Trinn 4: Game Audio

Det endelige trinnet i vårt spill polish er å legge til lyd. Først last ned lydene under og legg dem til prosjektet ditt:

GameSounds.zip

Tradisjonelt har håndtering av lyd vært ganske vondt i et OpenGL-spill. Du må bruke noe som OpenAL eller et annet komplisert C ++-bibliotek. Cocos2D har sterkt forenklet ting med sine SimpleAudioEngine bibliotek. Det gir deg muligheten til å enkelt spille looping bakgrunnsmusikk samt raske lyder.

Igjen, vi skal hoppe rundt ganske mye. Så, hvis plasseringen av noen kode er uklart for deg, vennligst spør meg i kommentarene eller referer til kildekoden til denne opplæringen.

Åpne AppDelegate.m og importer SimpleAudioEngine.h og legg til følgende linje nederst på siden applicationDidFinishLaunching metode.

 [[SimpleAudioEngine sharedEngine] playBackgroundMusic: @ "background.caf"]; jeg

Det er det! Det er bare nødvendig med en linje for å spille bakgrunnsmusikken i spilletidens varighet. Nå trenger vi bare å spille lydeffekter som svar på ulike handlinger.

I Caterpillar.m, når Caterpillar kolliderer med spilleren (mot slutten av Oppdater: metode):

 [[SimpleAudioEngine sharedEngine] playEffect: @ "player-hit.caf"];

I Missile.m, når missilen treffer Sprout:

 [[SimpleAudioEngine sharedEngine] playEffect: @ "sprout-hit.caf"];

Også i Missile.m, når missilen treffer Caterpillar:

 [[SimpleAudioEngine sharedEngine] playEffect: @ "caterpillar-hit.caf"];

I init-metoden i GameOverLayer.m:

 [[SimpleAudioEngine sharedEngine] playEffect: @ "game-over.caf"];

Det skal dekke alle lydene jeg har brukt i spillet. Sørg også for å importere SimpleAudioEngine.h i hver av klassene ovenfor.


Konklusjon

Dette avsluttes 7 del opplæringsserien om å skape et Caterpillar-spill som bruker Cocos2D til iPhone. Nå skal du ha en solid forståelse av hvordan du designer og bygger et enkelt spill ved hjelp av Cocos2D-spillmotor. Hvis du har noen spørsmål eller kommentarer, vær så snill å la dem stå i kommentaravsnittet her eller skriv dem til meg på Twitter.

Glad koding!