[self.gameTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- (void)steps{ _steps++; if (_steps % 60 == 0) { [self updateGameClock]; } //背景處理 [self.model moveBackground]; [self.bgView setBackgroundFrame1:self.model.bgFrame1 andFrame2:self.model.bgFrame2]; //英雄視圖位置重新整理 self.heroView.center = self.model.hero.position; //英雄飛機射擊 if (_steps % 10 == 0) { [self.model.hero fire]; } //射擊子彈處理 [self checkBullets]; //初始化敵機 [self initialEnemies]; //敵機移動 [self updateEnemies]; //碰撞檢測 [self collisionDetector];}
_step是靜態長整型,記錄重新整理次數。
- (void)moveBackground{ self.bgFrame1 = CGRectOffset(self.bgFrame1, 0, RMoveOffset); self.bgFrame2 = CGRectOffset(self.bgFrame2, 0, RMoveOffset); CGRect topFrame = CGRectOffset(self.gameArea, 0, -self.gameArea.size.height); if (self.bgFrame1.origin.y >= self.gameArea.size.height) { self.bgFrame1 = topFrame; } else if (self.bgFrame2.origin.y >= self.gameArea.size.height) { self.bgFrame2 = topFrame; }}
每次重新整理背景視圖向下移動一個點
- (void)collisionDetector{ /******子彈碰撞敵方飛機******/ NSMutableSet *removeBulletSet = [NSMutableSet set]; for (BulletView *bulletView in self.bulletViewSet) { Bullet *bullet = bulletView.bullet; for (EnemyView *enemyView in self.enemyViewSet) { Enemy *enemy = enemyView.enemy; if (CGRectIntersectsRect(bulletView.frame, enemyView.frame) && !enemy.toBlowup) { enemy.hp -= bullet.damage; if (enemy.hp <= 0) { enemy.toBlowup = YES; } else { if (enemy.type == REnemyTypeBig) { [enemyView stopAnimating]; } enemyView.image = enemyView.hitImage; } [removeBulletSet addObject:bulletView]; } } } for (BulletView *bulletView in removeBulletSet) { [bulletView removeFromSuperview]; [self.bulletViewSet removeObject:bulletView]; } /******爆炸處理******/ if (_steps % 4 == 0) { NSMutableSet *toRemovedSet = [NSMutableSet set]; for (EnemyView *enemyView in self.enemyViewSet) { Enemy *enemy = enemyView.enemy; if (enemy.toBlowup) { enemy.speed = 0; enemyView.image = enemyView.blowupImages[enemy.blowupFrames++]; } if (enemy.blowupFrames == enemyView.blowupImages.count) { [toRemovedSet addObject:enemyView]; } } for (EnemyView *enemyView in toRemovedSet) { self.totalScore += enemyView.enemy.prize; [self updateScoreLabel]; [self.enemyViewSet removeObject:enemyView]; [enemyView removeFromSuperview]; } [toRemovedSet removeAllObjects]; } /******敵機碰撞英雄飛機******/ for (EnemyView *enemyView in self.enemyViewSet) { if (CGRectIntersectsRect(enemyView.frame, self.model.hero.collisionRect)) { [self.heroView stopAnimating]; NSArray *images = [ImageResources sharedImages].heroBlowupImages; self.heroView.image = images[3]; self.heroView.animationImages = images; self.heroView.animationDuration = 1.0f; self.heroView.animationRepeatCount = 1; [self.heroView startAnimating]; [self pauseGameTimer]; MyLog(@"英雄死亡"); [[SoundsTool shareSoundsTool] playSoundWithType:RSoundTypeHeroOver]; [self endGame]; } }}
上面是碰撞檢測部分。分別對兩種情況進行了處理,並對爆炸動畫進行了逐幀顯示。
- (void)setToBlowup:(BOOL)toBlowup{ if (toBlowup == NO) { _toBlowup = NO; } else { _toBlowup = YES; RSoundType soundType; switch (self.type) { case REnemyTypeSmall: soundType = RSoundTypeSmallBlowup; break; case REnemyTypeMiddle: soundType = RSoundTypeMiddleBlowup; break; case REnemyTypeBig: soundType = RSoundTypeBigBlowup; break; } [[SoundsTool shareSoundsTool] playSoundWithType:soundType]; }}
- (void)playSoundWithType:(RSoundType)soundType{ NSString *soundName = nil; switch (soundType) { case RSoundTypeBullet: soundName = @"bullet"; break; case RSoundTypeSmallBlowup: soundName = @"enemy1_down"; break; case RSoundTypeMiddleBlowup: soundName = @"enemy3_down"; break; case RSoundTypeBigFly: soundName = @"enemy2_out"; break; case RSoundTypeBigBlowup: soundName = @"enemy2_down"; break; case RSoundTypeHeroOver: soundName = @"game_over"; break; } [self playSoundWithSoundName:soundName];}- (void)playSoundWithSoundName:(NSString *)soundName{ SystemSoundID soundId = [self.soundDict[soundName] unsignedLongValue]; AudioServicesPlaySystemSound(soundId);}
初始化敵機方法
- (void)initialEnemies{ NSInteger level = self.model.gameLevel; NSInteger flag = RMaxLevel/level; NSInteger timeS = arc4random_uniform(10*flag)+10/level+flag*1; NSInteger timeM = arc4random_uniform(50*flag)+200/level+flag*3; NSInteger timeB = arc4random_uniform(100*flag)+1000/level+flag*10; Enemy *enemy = nil; if (_steps % timeS == 0) { enemy = [self.model createEnemyWithType:REnemyTypeSmall andSize:[ImageResources sharedImages].smallFlyImage.size]; [self initEnemyViewWithEnemy:enemy]; } else if (_steps % timeM == 0) { enemy = [self.model createEnemyWithType:REnemyTypeMiddle andSize:[ImageResources sharedImages].middleFlyImage.size]; [self initEnemyViewWithEnemy:enemy]; } else if (_steps % timeB == 0) { enemy = [self.model createEnemyWithType:REnemyTypeBig andSize:[[ImageResources sharedImages].bigFlyImages[0] size]]; [self initEnemyViewWithEnemy:enemy]; [[SoundsTool shareSoundsTool] playSoundWithType:RSoundTypeBigFly]; }}
敵機初始化時間這個設定看習慣隨便了,由於遊戲中大部分方法都進行了封裝,就不全貼出來了。可以自行下載,從架構到編寫時間比較短,而且出現道具的功能也沒有實現,希望有改進的建議或者改進後的例子可以交流。