前一阵子看到了很多版本的打飞机游戏,有Java版的C++版本的还有C语言版的。。。
这几天闲着的时候写了一个OC版的,也正好是因为答应朋友写这个游戏来把飞机都换成他照片- -。
没有用Cocos2d框架,用的QuartzCore中的CADisplayLink来完成。
先看下完成后的效果
简单的架构思路设计如下:
图片资源与音乐资源都以单例方式实现模型,在需要的地方调用。
核心部分是对每秒60帧刷新方法中的处理。
self.gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(steps)];
[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]; }
背景处理代码
- (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]; } } }
在设置toBlowup属性中播放爆炸音效。
- (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]; } }
补充这个游戏是用Xcode5写的,另外附上用Iphone4玩时候内存和CPU的使用情况。
Demo源码:点击打开链接
以上为本篇博客全部内容,欢迎指正和交流。转载注明出处~