zoukankan      html  css  js  c++  java
  • iOS_31_cocos2d_微信飞机

    终于效果图:


    纹理素材



    场景

    //
    //  GameScene.m
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-27.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  雷电,游戏场景
    
    #import "GameScene.h"
    #import "Hero.h"
    // 背景音乐
    //#import "SimpleAudioEngine.h"
    #import "OALSimpleAudio.h"
    // 子弹精灵
    #import "Pellet.h"
    // 敌机
    #import "Enemy.h"
    
    
    
    
    // 一次性初始化的子弹的最大数量
    #define kPelletMaxCount 10
    // 子弹两次出现之间的总的累计时间间隔
    #define kPelletTotalIntervalTime 0.3
    
    // 敌机的最大数量
    #define kEnemyMaxCount 5
    
    @interface GameScene()
    {
        // 由于一个spriteBatchNode相应一个纹理(图片),因此,从纹理相冊裁剪出来的小精灵(帧),全部交给spriteBatchNode统一管理,场景仅仅须要 与 spriteBatchNode打交道
        CCSpriteBatchNode *_batch;
        // 背景2图片 始终在背景1图片的头顶上
        CCSprite *_bg1, *_bg2;
        
        // 英雄,主角
        Hero *_hero;
        // 标记 是否正在执行
        BOOL _isGameRuning;
        
    
        // 重要~~~~子弹缓存
        NSMutableArray *_pelletArr;
        // 成员变量 用于记住 累加的间隔时间,它当达到一定量时(如0.3秒),才发射一串子弹
        // 子弹两次出现之间的总的间隔(累积)时间
        CGFloat _pelletTotalIntervalTime;
        
        // 重要~~~~敌人缓存
        NSMutableArray *_enemyArr;
       
    }
    @end
    
    @implementation GameScene
    
    #pragma mark - 覆盖父类方法
    -(id)init
    {
        if (self=[super init]) {
            
            // 1.基本初始化
            [self setupBasic];
            
            // 2.初始化背景
            // 初始化背景 ,并加入到batchNode中,统一管理,在时钟方法里,滚动背景
            [self setupBg];
            
            // 3.初始化英雄
            // 初始化英雄 ,并加入到batchNode中,统一管理,在时钟方法里,碰撞检測
            [self setupPlayer];
    
            // 4.初始化子弹
            // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
            [self setupPelletArr];
    
            // 5.初始化敌机
            [self setupEnemyArr];
    
            // 6.開始游戏
            [self startGame];
        }
        return self;
    }
    
    #pragma mark - 初始化
    
    #pragma mark 1.基本初始化
    - (void)setupBasic
    {
        
        
        // 1.载入纹理相冊 到精灵帧缓存
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"gameArts.plist"];
        
        // 2.创建sprite批处理
        _batch = [CCSpriteBatchNode batchNodeWithFile:@"gameArts.png"];
        [self addChild:_batch];
        
        // 3.加入一个button,暂停或继续游戏
        [self setupPauseButton];
    }
    // 4.加入一个button,暂停或继续游戏
    - (void)setupPauseButton
    {
        // 调用父类封装的方法,绑定监听方法:gameControlBtnClicked
         [self addBtn:@"暂停/继续" position:ccp(0.5, 0.5) target:self sel:@selector(gameControlBtnClicked)];
        
    }
    #pragma mark 2.初始化背景
    - (void)setupBg
    {
    
        NSString *bgPicName = @"background_2.png";
        _bg1 = [CCSprite spriteWithImageNamed:bgPicName];
        _bg1.anchorPoint = CGPointZero;
        
        // 背景2图片 始终在背景1图片 的头顶上
        _bg2 = [CCSprite spriteWithImageNamed:bgPicName];
        _bg2.anchorPoint = CGPointZero;
        
        [_batch addChild:_bg1];
        [_batch addChild:_bg2];
    }
    #pragma mark 3.初始化玩家
    - (void)setupPlayer
    {
        _hero = [Hero node];
        // 由于是从同一个大纹理中,依据key裁剪出来的,所以能够加到同一个精灵batchNode,由它统一管理
        [_batch addChild:_hero];
    }
    #pragma mark 4.初始化子弹缓存
    // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
    - (void)setupPelletArr
    {
        _pelletArr = [NSMutableArray array];
        // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
        for (int i = 0; i<kPelletMaxCount; i++) {
            // 默认 就是先隐藏的
            Pellet *b = [Pellet node];
            // 类型为:大子弹
            b.type = kPelletTypeBig;
            // 加入到数组中
            [_pelletArr addObject:b];
            // 加入到spriteBatchNode
            [_batch addChild:b];
        }
         
    }
    
    #pragma mark 5.初始化敌机缓存
    // 初始化指定数量的敌机 ,并加入到batchNode中,统一管理,在时钟方法里,安排敌机出场
    - (void)setupEnemyArr
    {
        // 1.初始化 敌机缓存
        _enemyArr = [[NSMutableArray alloc] init];
        
        for (int i = 0; i<kEnemyMaxCount; i++) {
            // 默认 就是先隐藏的
            Enemy *e = [Enemy node];
            // 类型为:敌机_1
            e.type = kEnemyType_1;
            // 加入到 敌机数组中
            [_enemyArr addObject:e];
            // 加入到spriteBatchNode
            [_batch addChild:e];
        }
         
    }
    #pragma mark - 游戏控制button点击
    - (void)gameControlBtnClicked
    {
        // 假设 正在游戏,就暂停;反之继续游戏
        if (_isGameRuning) {
            // _isGameRuning = NO;
            [self pauseGame];
        } else {
            // _isGameRuning = YES;
            [self startGame];
        }
    }
    #pragma mark 開始
    - (void)startGame
    {
        // 1.首先置标记为 1
        _isGameRuning = YES;
        // 同意交互
        self.userInteractionEnabled = YES;
        
        // 2.播放背景音乐
         
         
    
        [[OALSimpleAudio sharedInstance] preloadBg:@"game_music.mp3"];
        [[OALSimpleAudio sharedInstance] playBgWithLoop:YES];
    //    [[OALSimpleAudio sharedInstance]playBg:@"game_music.mp3" loop:YES];
        // 3.初始化 子弹两次出现 之间须要的总的累计间隔时间,如 0.3秒
        // 这样一设置之后,game一開始就有子弹射出去了
        _pelletTotalIntervalTime = kPelletTotalIntervalTime;
        
    
    }
    #pragma mark 暂停
    - (void)pauseGame
    {
        // 1.首先置标记为 0
        _isGameRuning = NO;
        // 停止交互(触摸移动)
        self.userInteractionEnabled = NO;
        
        // 2.停止全部消息调度
        // 同一时候,也要让spriteBatchNode中管理的全部成员,执行 unscheduleAllSelectors 方法
         [_batch.children makeObjectsPerformSelector:@selector(unscheduleAllSelectors)];
        
        // 3.暂停背景音乐
        
     
        [[OALSimpleAudio sharedInstance]stopBg];
        [[OALSimpleAudio sharedInstance]stopAllEffects];
    
    }
    #pragma mark 结束
    - (void)endGame
    {
        // 1.首先置标记为 0
        _isGameRuning = NO;
        self.userInteractionEnabled = NO;
        
        // 2.停止全部消息调度
         
        // 同一时候,也要让spriteBatchNode中管理的全部成员,执行 unscheduleAllSelectors 方法
        [_batch.children makeObjectsPerformSelector:@selector(unscheduleAllSelectors)];
        
        // 3.停止背景音乐
     
     
        
        
         
    }
    #pragma mark - 时钟方法
    - (void)update:(CCTime)delta
    {
        // 假设 游戏暂停中,则不更新不论什么状态
        if (!_isGameRuning) {
            return;
        }
        
        // 1.背景动画(始终向下滚动)
        [self bgAnimation];
        
        // 2.子弹动画(射出,执行轨迹)
        [self pelletAnimation:delta];
        
        // 3.敌机出场作战
        [self enemyAnimation:delta];
        
        // 4.碰撞边界检測
        [self collsionAndBoundaryCheck];
    }
    
    #pragma mark 1.滚动背景
    // 1.背景动画(始终向下滚动)
    - (void)bgAnimation
    {
        // 2张背景图片,始终相差一张图片的高度(不管屏幕多高)
        CGFloat height = _bg1.contentSize.height;
        CGFloat bg1_Y = _bg1.position.y;
        // 向下走
        bg1_Y--;
        // 临界点
        // 向下走过程中,假设 1 超出屏幕了,将1 拉回去(2的y取决于1的y,因此,仅仅要设置1的y)
        if (bg1_Y <= -height) {
            bg1_Y = 0;
        }
        _bg1.position = ccp(0, bg1_Y);
        // 2始终在1的头顶上
        _bg2.position = ccp(0, bg1_Y + height);
    }
    #pragma mark 2.子弹动画
    - (void)pelletAnimation:(CCTime)delta
    {
        // 先累加 delta时间,到一定量时,再发射子弹
        _pelletTotalIntervalTime += delta;
        // 假设累计间隔时间达到了 预订的值:如0.3秒,能够发射子弹,位置是:英雄头顶
        if (_pelletTotalIntervalTime >= kPelletTotalIntervalTime) {
            
            Pellet *pellet;
            for (pellet in _pelletArr) {
                // 假设数组中,还有 子弹不可见,说明在屏幕外;因此,可回收循环使用;仅仅需又一次调整位置 发射出去
                if (pellet.visible == NO) {
                    CGPoint from = ccp(_hero.position.x, CGRectGetMaxY(_hero.boundingBox));
                    [pellet emitFrom:from velocity:ccp(0, 200)];
                    break;
                }
                // 假设,数组中没有一个能够用的....那么遍历完后,仅仅能创建新的了,(记得也要加到数组中去哦~)
                pellet = nil;
            }
            
            // 假设,数组中没有一个能够用的....那么遍历完后,仅仅能创建新的发射了,(记得也要加到数组中去哦~)
            // 没有可循环利用的子弹
            if (pellet == nil) {
                // 事实上,内部已经封装了,默认创建出来的新子弹是不可见,仅仅有在发射emit时,才可见
                Pellet *p = [Pellet node];
                // 大子弹
                p.type = kPelletTypeBig;
                // 重要~~~一定要,记得,加入到数组中
                [_pelletArr addObject:p];
                 
                
                // 加入到精灵batchNode
                [_batch addChild:p];
                
                // 射出新子弹
                CGPoint from = ccp(_hero.position.x, CGRectGetMaxY(_hero.boundingBox));
                [p emitFrom:from velocity:ccp(0, 200)];
            }
            // 用于记录的成员变量,清零
            _pelletTotalIntervalTime = 0;
        }
    }
    
    #pragma mark 3.敌机出场作战
    - (void)enemyAnimation:(CCTime)delta
    {
        Enemy *enemy;
        for (enemy in _enemyArr) {
            // 假设数组中,还有 敌机不可见,说明在屏幕外;因此,可回收循环使用;仅仅需又一次调整位置 參加战场
            if (enemy.visible == NO) {
                // 详细怎样 运动,内部自己决定
                [enemy attendTheBattle];
                // 一次时钟周期,送一个敌机上战场
                break;
            }
        }
        
    }
    
    #pragma mark 碰撞边界检測
    - (void)collsionAndBoundaryCheck
    {
        // 子弹检測
        Pellet *pellet;
        for (pellet in _pelletArr) {
            // 仅仅有在屏幕范围内,可见的,才须要进行碰撞检測;如不可见,直接,分析下一个子弹
            if (pellet.visible == NO) continue;
            
            // 1.子弹 与 屏幕 检測
            // 2.子弹 与 敌机 检測
            [self checkPellet:pellet];
            
        }// 遍历子弹缓存数组 结束
        
    }
    // 1.子弹 与 屏幕 检測
    // 2.子弹 与 敌机 检測
    - (void)checkPellet:(Pellet *)pellet
    {
        // 子弹边框与屏幕边框 进行交集检測
        if (!CGRectIntersectsRect(self.boundingBox, pellet.boundingBox)) {
            // 1.离开屏幕了(再无交集),子弹消失
            [pellet dismiss];
             
        } else {
            // 2.子弹还在屏幕内,才要进行,与敌机的 碰撞检測
            // 敌机检測
            Enemy *enemy;
            for (enemy in _enemyArr) {
                // 假设不可见,不须要检測
                // 仅仅有在屏幕范围内,可见的,才须要进行碰撞检測;如不可见,直接,分析下一个
                if (enemy.visible == NO) continue;
                // 1.敌机与屏幕rect检測
                // 2.敌机与子弹检測
                // 3.敌机与英雄检測
                [self enemy:enemy checkWithPellet:pellet];
                
            }// 遍历子弹缓存数组 结束
        }// 子弹 和 敌机的 碰撞检測
    }
    
    // 1.敌机与屏幕rect检測
    // 2.敌机与子弹检測
    // 3.敌机与英雄检測
    - (void)enemy:(Enemy *)enemy checkWithPellet:(Pellet *)pellet
    {
        // 敌机 边框与屏幕rect边框 进行交集检測
        if (!CGRectIntersectsRect(self.boundingBox, enemy.boundingBox)) {
            // 假设 没有交集,代表,敌机 逃离屏幕范围,故隐藏 敌机;
            [enemy hide];
             
        } else if (CGRectIntersectsRect(pellet.boundingBox, enemy.boundingBox)) {
            // 仅仅有在屏幕范围内的敌机,才须要 和 (在屏幕范围内的)子弹 进行交集检測
            // 首先,隐藏子弹
            [pellet dismiss];
            
            // 然后,敌机中弹
            [enemy gotHit];
        } else {
            // 自己定义方法,英雄与敌机 交集检測
            [self enemyCheckWithHero:enemy];
        }
    }
    // 自己定义方法,英雄与敌机 交集检測
    - (void)enemyCheckWithHero:(Enemy *)enemy
    {
        // 子弹 尽管 没有打中,可是 英雄与敌机 相撞,结果还是,game over
        if (CGRectContainsRect(_hero.boundingBox, enemy.boundingBox)) {
            [_hero dieWithEnemyTogether];
            
            // game over,结束游戏
            [self endGame];
        }
    }
    #pragma mark - 触摸事件
    // 必须有 touch began ,否则 不能响应
    - (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
    {
         
    }
    - (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
    {
        // 1.当前点
        CGPoint curPoint = [[CCDirector sharedDirector] convertToGL:[touch locationInView:touch.view]];
        
        // 2.上一个点
        CGPoint prePoint = [[CCDirector sharedDirector] convertToGL:[touch previousLocationInView:touch.view]];
        
        
         
        // 3.设置飞机的位置
        CGPoint newPosition = ccpAdd(_hero.position, ccpSub(curPoint, prePoint));
        
         
        
        // 4.拖动过程中,边界检測,不能出屏幕
        CGFloat _heroWidth = _hero.contentSize.width;
        CGFloat _heroHeight = _hero.contentSize.height;
        if (newPosition.x <  _heroWidth*0.5) {
            return;
        } else if(newPosition.x > self.contentSize.width - _heroWidth*0.5){
            return;
        }else if (newPosition.y < 0){
            return;
        }else if(newPosition.y > self.contentSize.height - _heroHeight){
            return;
        }
        _hero.position = newPosition;
    }
    @end<span style="font-family:Courier New;color:#393939;"><span style="font-size: 24px; line-height: 32px; background-color: rgb(245, 245, 245);"><strong>
    </strong></span></span>


    子弹Pellet

    //
    //  Pellet.h
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-28.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "CCSprite.h"
    
    typedef enum {
        // 小子弹
        kPelletTypeSmall,
        // 大子弹
        kPelletTypeBig
    }PelletType;
    
    @interface Pellet : CCSprite
    // 子弹类型
    @property (nonatomic,assign) PelletType type;
    // 子弹速度 (Y方向,和X方向)
    @property (nonatomic, assign) CGPoint velocity;
    
    // 发射 emit,參数:射出的点  射出的速度 
    - (void)emitFrom:(CGPoint)from velocity:(CGPoint)velocity;
    // 消失/隐藏
    - (void)dismiss;
    
    
    @end
    


    //
    //  Pellet.m
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-28.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "Pellet.h"
    
    // 精灵帧 用到
    #import "cocos2d.h"
    // 音效
    //#import "SimpleAudioEngine.h"
    #import "OALSimpleAudio.h"
    
    @implementation Pellet
    
    #pragma mark - 父类方法
    
    -(id)init
    {
        if (self=[super init]) {
            // 子弹创建时,默认隐藏,仅仅有当调用发射emit方法时,才显示
            self.visible = NO;
        }
        return self;
    }
    #pragma mark - 拦截setter
    - (void)setType:(PelletType)type
    {
        _type = type;
        
        // 更换子弹精灵的 图片
        NSString *imgName = _type == kPelletTypeSmall ?

    @"bullet1.png" : @"bullet2.png"; CCSpriteFrame *frame = [CCSpriteFrame frameWithImageNamed:imgName]; [self setSpriteFrame:frame]; } #pragma mark - 供外界调用 // 发射 emit,參数:射出的点 射出的速度 - (void)emitFrom:(CGPoint)from velocity:(CGPoint)velocity{ self.visible = YES; // 设置位置 self.position = from; // 设置速度 self.velocity = velocity; // 音效播放 // [[SimpleAudioEngine sharedEngine] playEffect:@"Pellet.mp3"]; [[OALSimpleAudio sharedInstance]playEffect:@"bullet.mp3"]; } // 消失/隐藏 - (void)dismiss { self.visible = NO; [self unscheduleAllSelectors]; } #pragma mark - 时钟方法(飞行) - (void)update:(CCTime)delta { // 当子弹消失后,不再更新position... if (!self.visible) { return; } // deltaTime 时间内,移动(飞行)一段距离 // 路程s = 速度v * 时间t CGPoint s = ccpMult(self.velocity, delta); self.position = ccpAdd(self.position, s); } @end



    英雄Hero

    //
    //  Hero.h
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-27.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "CCSprite.h"
    
    @interface Hero : CCSprite
    
    
    // 简单处理,英 雄与敌机 相撞,结果还是,game over
    - (void)dieWithEnemyTogether;
    @end
    


    //
    //  Hero.m
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-27.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  主角,代表玩家的 英雄
    
    #import "Hero.h"
    #import "cocos2d.h"
    #import "CCDirector.h"
    #import "CCAnimation.h"
    @implementation Hero
    
    
    
    // 初始化玩家(的飞机)
    - (id)init
    {
        // 事实上,磁盘里没有hero_fly_1.png 图片,它是到大图片的帧缓存中,依据key取出(裁剪)小图片
        if (self = [super initWithImageNamed:@"hero_fly_1.png"]) {
            // 1.初始化位置,底部,中间
            self.anchorPoint = ccp(0.5, 0);
            // 从导演那儿拿到viewSize就是屏幕的size
            CGSize fullScreenSize = [[CCDirector sharedDirector] viewSize];
            self.position = ccp(fullScreenSize.width * 0.5, 0);
            
            // 2.创建 帧动画 须要的两个精灵帧
            CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
            CCSpriteFrame *frame1 = [cache spriteFrameByName:@"hero_fly_1.png"];
            CCSpriteFrame *frame2 = [cache spriteFrameByName:@"hero_fly_2.png"];
            
            NSArray *spriteFramesArr = @[frame1, frame2] ;
    
            
            // 3.为精灵加入动画
            CCAnimation *animation = [CCAnimation animationWithSpriteFrames:spriteFramesArr delay:0.1];
            CCActionAnimate *animate = [CCActionAnimate actionWithAnimation:animation];
            // 4.播放帧动画
            [self runAction:[CCActionRepeatForever actionWithAction:animate]];
        }
        return self;
    }
    // 简单处理,英 雄与敌机 相撞,结果还是,game over
    - (void)dieWithEnemyTogether
    {
        // 停止之前的帧动画
        [self stopAllActions];
        
        // 直接播放 爆炸 帧动画
        NSMutableArray *frames = [NSMutableArray array];
        
        for (int i = 1; i<=4; i++) {
            NSString *name = [NSString stringWithFormat:@"hero_blowup_%d.png", i];
            CCSpriteFrame *f = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
            [frames addObject:f];
        }
        
        CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.1];
        [self runAction:[CCActionAnimate actionWithAnimation:animation]];
    }
    @end
    


    敌机Enemy(有待发散)

    //
    //  Enemy.h
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-28.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "CCSprite.h"
    //相应plist文件里 5种图片
    typedef enum {
        kEnemyType_1 = 1,
        kEnemyType_2 = 2,
        kEnemyType_3 = 3,
        kEnemyType_4 = 4,
        kEnemyType_5 = 5
    } EnemyType;
    
    @interface Enemy : CCSprite
    
    @property (nonatomic, assign) EnemyType type;
    // 出如今游戏中,出场,增加战斗
    - (void)attendTheBattle;
    - (void)hide;
    // 被击中
    - (void)gotHit;
    @end
    


    //
    //  Enemy.m
    //  31_cocos2D入门
    //
    //  Created by beyond on 14-9-28.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "Enemy.h"
    #import "cocos2d.h"
    #import "OALSimpleAudio.h"
    #import "CCAnimation.h"
    #import "CCDirector.h"
    
    @interface Enemy()
    {
        // 最大的生命值
        int _maxHp;
        // 生命值
        int _hp;
    }
    @end
    
    @implementation Enemy
    
    
    #pragma mark - 父类方法
    
    -(id)init
    {
        if (self=[super init]) {
            // 敌机创建时,默认隐藏,仅仅有当调用出场,參加战斗 时,才显示
            self.visible = NO;
        }
        return self;
    }
    
    
    #pragma mark - 拦截setter方法
    - (void)setType:(EnemyType)type
    {
        _type = type;
        
        // 依据 敌人类型,设置 敌人显示的图片
        [self setEnemyImage];
        
        // 依据 敌人类型,设置 敌人最大生命值
        switch (type) {
            case kEnemyType_1:
                _maxHp = 1;
                break;
            case kEnemyType_2:
                _maxHp = 2;
                break;
            case kEnemyType_3:
                _maxHp = 3;
                break;
            case kEnemyType_4:
                _maxHp = 4;
                break;
            case kEnemyType_5:
                _maxHp = 5;
                break;
            
            default:
                break;
        }
    }
    
    #pragma mark - 时钟方法
    - (void)update:(CCTime)delta
    {
        // 同其它的子弹、英雄一样,仅仅有在显示时,才须要更新位置
        // 当敌人处于不可见时,说明被打死了,或逃出屏幕了,因此无需更新其位置
        if (!self.visible) {
            return;
        }
        // 不断调整敌人的位置 (速度 能够和最大生命值一样,设置不同的...)
        self.position = ccpAdd(self.position, ccp( 0, -100 * delta));
    }
    #pragma mark - 供外部调用
    // 出如今游戏中,出场,增加战斗
    - (void)attendTheBattle
    {
        // 出场时,满血
        _hp = _maxHp;
        // 出场时,显示
        self.visible = YES;
        // 出场时,位置,从屏幕顶部俯冲下来
        self.anchorPoint = ccp(0.5, 0);
        
        CGSize winSize = [CCDirector sharedDirector].viewSize;
        // 重要~~~之所以要减一,是由于...出场时,要让它一仅仅脚 踏进屏幕,与屏幕窗体的rect有交集
        self.position = ccp(winSize.width * CCRANDOM_0_1(), winSize.height - 1);
        // 边界检測
        
    }
    // 被击中
    - (void)gotHit
    {
        _hp--;
        
        if (_hp == 0) {
            // 1.播放相应的被打中时 的音效
            [self playHitSound];
            // 2.播放相应的被爆炸动画
            [self playExplodeAnimation];
            
        }
    }
    // 消失
    - (void)hide
    {
        self.visible = NO;
        
        [self unscheduleAllSelectors];
    }
    
    #pragma mark - 抽取方法
    // 依据 敌人类型,设置 敌人显示的图片
    - (void)setEnemyImage
    {
        // 依据 敌人类型,设置 其图片
        NSString *name = [NSString stringWithFormat:@"enemy%d_fly_1.png", _type];
        // 从精灵帧缓存中,取出精灵帧,从而设置到精灵身上,显示
        CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
        [self setSpriteFrame:frame];
    }
    
    // 播放相应的被打中时 的音效
    - (void)playHitSound
    {
       [[OALSimpleAudio sharedInstance] playEffect:[NSString stringWithFormat:@"enemy%d_down.mp3", _type]];
    }
    // 播放爆炸动画,爆炸完,隐藏,最后又一次设置显示图片,为參加下一次战斗作准备
    - (void)playExplodeAnimation
    {
        NSMutableArray *frames = [NSMutableArray array];
        // 这个爆炸效果的 4 应该动态变化 ....
        for (int i = 1; i<=4; i++) {
            NSString *name = [NSString stringWithFormat:@"enemy1_blowup_%d.png", i];
            CCSpriteFrame *f = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
            [frames addObject:f];
        }
        // 名词,动画
        CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.1];
        // 动作_1 爆炸
        CCActionAnimate *explosion = [CCActionAnimate actionWithAnimation:animation];
        // 动作_2 不可见
        CCActionHide *hide = [CCActionHide action];
        // 动作_3 由于爆炸后,精灵的显示图片变了,所以要又一次设置回来,以便下一次 參加战斗
        CCActionCallFunc *func = [CCActionCallFunc actionWithTarget:self selector:@selector(setEnemyImage)];
        // 动作_4 用序列包装
        CCActionSequence *sequence = [CCActionSequence actions:explosion,hide,func, nil];
        // 运行动作
        [self runAction:sequence];
    }
    @end
    



















  • 相关阅读:
    生活有时候就是个戏本
    Android dp、dpi、px
    iOS10以后相机、相册等授权问题
    iOS圆角性能问题
    激荡10年,珍贵的毕业礼物
    Android API 指南
    Android 配置
    Android Error
    安卓 MIUI真机测试
    iOS 同一段文字显示不同颜色
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7007278.html
Copyright © 2011-2022 走看看