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.
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.
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];
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å.
Innenfor spillet er det flere steder hvor spilleren kan øke sin score. De er:
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.
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
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.
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.
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!