IOS飞机大战OC版


前一阵子看到了很多版本的打飞机游戏,有Java版的C++版本的还有C语言版的。。。

这几天闲着的时候写了一个OC版的,也正好是因为答应朋友写这个游戏来把飞机都换成他照片- -。

没有用Cocos2d框架,用的QuartzCore中的CADisplayLink来完成。


先看下完成后的效果

IOS飞机大战OC版_第1张图片 IOS飞机大战OC版_第2张图片IOS飞机大战OC版_第3张图片 IOS飞机大战OC版_第4张图片



简单的架构思路设计如下:

IOS飞机大战OC版_第5张图片



图片资源与音乐资源都以单例方式实现模型,在需要的地方调用。

核心部分是对每秒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];
}

_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];
        }
    }
}

上面是碰撞检测部分。分别对两种情况进行了处理,并对爆炸动画进行了逐帧显示。

在设置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的使用情况。

IOS飞机大战OC版_第6张图片IOS飞机大战OC版_第7张图片


Demo源码:点击打开链接



以上为本篇博客全部内容,欢迎指正和交流。转载注明出处~

你可能感兴趣的:(ios,游戏,飞机大战)