[一位菜鸟的COCOS-2D编程之路]2:我的第一个Cocoa-2d游戏---打飞机

这一下午边翻书边写代码,效果还是很不错的.先和大家分享下图片~


1.关于代理的内容,和我上一篇的内容大致相同,我今天主要讲解关于 HelloWorldlayer里面的东西.

先看看我们的.h文件

//
//  HelloWorldLayer.h
//  垂直射击游戏
//
//  Created by lichan on 13-12-7.
//  Copyright com.lichan 2013年. All rights reserved.
//


// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorldLayer
@interface HelloWorldLayer : CCLayer
{
    CCArray *_enemySprites;  //敌机的数组
    CGPoint _playerVelocity;//玩家战机的位置
    
    BOOL _isTouchToShoot;//是否点击屏幕开始射击
    CCSprite *_bulletSprite;//子弹精灵
    
    CCLabelTTF *_lifeLabel;//生命的显示label
    CCLabelTTF *_scoreLabel;//战机label
    
    int _totalLives;//所剩命的条数
    int _totalScore;//总的分数
    
    CCLabelTTF *_gameEndlabel;//游戏结束的label
}

//@property(nonatomic,) CCArray * _enemySprites;
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

@end


2.重点!看看我们的 helloWorldlayer.m文件的内容吧.我会在注释中讲解

//
//  HelloWorldLayer.m
//  垂直射击游戏
//
//  Created by lichan on 13-12-7.
//  Copyright com.lichan 2013年. All rights reserved.
//


// Import the interfaces
#import "HelloWorldLayer.h"

#import "SimpleAudioEngine.h"  //加载上声音的头文件,如果想让游戏有刺激感,声音是必不可少的



#define NUM_OF_ENEMIES 10  //敌机的数量

// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
enum{
    kTagPlayer = 1,   //我方战绩的tag
};


@interface HelloWorldLayer()

- (void)spawnEnemy;  //设置 敌机的俯冲效果

- (CCSprite *)getAvaliableEnemySprite;  //得到敌机精灵

- (void)updateplayerPosition:(ccTime)dt;  //更新我方战绩的位置,刷新位置

- (void)bulletFinishedMoving: (id)sender;  //子弹的生命周期的结束

@end




#pragma mark - HelloWorldLayer

// HelloWorldLayer implementation
@implementation HelloWorldLayer

// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
-(id) init  //里面定义了很多关于游戏中的一些视图,方法.
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super's" return value
	if( (self=[super init]) ) {
		
        CGSize winSize = [[CCDirector sharedDirector] winSize];
        
        CCSprite *bgSprite = [CCSprite spriteWithFile:@"background_1.jpg"];
        
        bgSprite.position = ccp(winSize.width/2, winSize.height/2);
        
        [self addChild:bgSprite];
        
        
        CCSprite *playerSprite = [CCSprite spriteWithFile:@"hero_1.png"];
        
        playerSprite.position =  CGPointMake(winSize.width/2, playerSprite.contentSize.height/2+20);
        
        [self addChild:playerSprite z:4 tag:kTagPlayer];
        
        
        _enemySprites = [[CCArray alloc]init]; //敌机数组的初始化
        //敌机 随机的出现.
        for (int i = 0; i < NUM_OF_ENEMIES; i ++) {
            CCSprite *enemySprite = [CCSprite spriteWithFile:@"enemy1.png"];
            
            enemySprite.position = ccp(0, winSize.height +enemySprite.contentSize.height + 10);
            
            enemySprite.visible = NO;
            [self addChild:enemySprite z:4];
            
            [_enemySprites addObject:enemySprite];
            
        }
        
        [self performSelector:@selector(spawnEnemy) withObject:nil afterDelay:1.0f];
        //敌机出现的方法,spawnEnemy (敌机出现的效果)
        
        self.isAccelerometerEnabled = YES;  //开启传感器
        
        [self scheduleUpdate];  //更新视图
        
        //玩家的触摸感应
        self.isTouchEnabled = YES;
        
       // CCLOG(@" isTouchEnabled %hhd",self.isTouchEnabled);
        _isTouchToShoot = NO;
        
        _bulletSprite = [CCSprite spriteWithFile:@"bullet1.png"];
        _bulletSprite.visible = NO;
        
        [self addChild:_bulletSprite z:4];
        
        
        //添加声音效果
        
        [[SimpleAudioEngine sharedEngine] preloadEffect:@"bullet.mp3"];
        [[SimpleAudioEngine sharedEngine]playBackgroundMusic:@"game_music.mp3" loop:YES];
        [[SimpleAudioEngine sharedEngine] setBackgroundMusicVolume:0.5];
        
        //生命,分数 的读条和字体设置
        CCLabelTTF *lifeindicator = [CCLabelTTF labelWithString:@"生命值:" fontName:@"Arial" fontSize:20];
        lifeindicator.anchorPoint = ccp(0, 0.5);
        lifeindicator.position = ccp(20, winSize.height - 20);
        
        [self addChild:lifeindicator z:10];
        
        _lifeLabel =[CCLabelTTF labelWithString:@"3" fontName:@"Arial" fontSize:20];
        
        _lifeLabel.position = ccpAdd(lifeindicator.position, ccp(lifeindicator.contentSize.width+10, 0));
        
        [self addChild:_lifeLabel z:10];
        
        
        CCLabelTTF *scoreIndicator = [CCLabelTTF labelWithString:@"分数" fontName:@"Arial" fontSize:20];
        
        scoreIndicator.anchorPoint = ccp(0.0, 0.5f);
        
        scoreIndicator.position = ccp(winSize.width - 100,winSize.height - 20);
        
        [self addChild:scoreIndicator z:10];
        
        _scoreLabel = [CCLabelTTF labelWithString:@"00" fontName:@"Arial" fontSize:20];
        
        _scoreLabel.position = ccpAdd(scoreIndicator.position, ccp(scoreIndicator.contentSize.width + 10, 0));
        
        [self addChild:_scoreLabel z:10];
        
        
        
        _totalLives = 3;
        _totalScore = 0;
        //游戏结束时候的提示
        _gameEndlabel = [CCLabelTTF labelWithString:@"" fontName:@"Arial" fontSize:40];
        _gameEndlabel.position = ccp(winSize.width/2,winSize.height/2);
        _gameEndlabel.visible = NO;
        [self addChild:_gameEndlabel z:10];
        
        
        

	}
	return self;
}



#pragma mark 更新生命值和血量
- (void)updateHUD:(ccTime)dt  //更新当前生命的方法.在 update中刷新60次/s
{
    [_lifeLabel setString:[NSString stringWithFormat:@"%2d",_totalLives]];
    [_scoreLabel setString:[NSString stringWithFormat:@"%04d",_totalScore]];

}

#pragma mark 自动调用的触摸方法



- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CCLOG(@"我开始触摸屏幕");
}

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    _isTouchToShoot = YES;//设置屏幕触摸生效,开启发射子弹
}

#pragma mark 私有的方法

- (void)update:(ccTime)delta
{
     [self updateplayerPosition:delta];  //我方战机位置的刷新
    
     [self updatePlayerShooting:delta];//子弹射击的刷新
    
     [self collisionDetection:delta];//检测碰撞
    
    [self updateHUD:delta];//生命条的读取
    
   // CCLOG(@" isTouchEnabled %hhd",self.isTouchEnabled);
    
    

}

- (void)updatePlayerShooting:(ccTime)dt
{
    if (_bulletSprite.visible || !_isTouchToShoot)
        return;
    
    CCSprite *playerSprite = (CCSprite *)[self getChildByTag:kTagPlayer];
    
    CGPoint pos = playerSprite.position;
    
    CGPoint bulletPos = CGPointMake(pos.x, pos.y + playerSprite.contentSize.height/2 + _bulletSprite.contentSize.height);
    
    _bulletSprite.position = bulletPos;
    
    _bulletSprite.visible = YES;
    
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    
    id moveBy  = [CCMoveBy actionWithDuration:1.0 position:ccp(0, winSize.height - bulletPos.y)];
    
    id callBack = [CCCallFuncN actionWithTarget:self selector:@selector(bulletFinishedMoving:)];
    
    id ac = [CCSequence actions:moveBy,callBack, nil];
    
    [_bulletSprite runAction:ac];
    
    [[SimpleAudioEngine sharedEngine]playEffect:@"bullet.mp3"];

}

- (void)bulletFinishedMoving:(id)sender
{
    _bulletSprite.visible = NO;

}

- (void)updateplayerPosition:(ccTime)dt
{
    
    CCSprite *playerSprite = (CCSprite *)[self getChildByTag:kTagPlayer];
    
    CGPoint pos = playerSprite.position;
    
    pos.x += _playerVelocity.x;
    
    CGSize screenSize = [[CCDirector sharedDirector] winSize];
    
    float imageWidthhavled = playerSprite.texture.contentSize.width*0.5f;
    
    float leftBoderLimit = imageWidthhavled;
    
    float rightboderLimit = screenSize.width - imageWidthhavled;
    
    if (pos.x < leftBoderLimit) {
        pos.x = leftBoderLimit;
        _playerVelocity = CGPointZero;
    }else if(pos.x
              > rightboderLimit)
    {
        pos.x = rightboderLimit;
        _playerVelocity = CGPointZero;
    
    }
    
    playerSprite.position  = pos;

}





- (void)spawnEnemy
{
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    CCSprite *enemySprite = [self getAvaliableEnemySprite];
    
    float durationTime = arc4random()%4 +1;
    
    id moveBy = [CCMoveBy actionWithDuration:durationTime position:ccp(0, -enemySprite.position.y - enemySprite.contentSize.height)];
    
    id callBack = [CCCallBlockN actionWithBlock:^(id sender){
        CCSprite *sp = (CCSprite *)sender;
        
        sp.visible = NO;
        sp.position = ccp(0, winSize.height + sp.contentSize.height + 10);
        
        CCLOG(@"reset enemy plane");
    
    }];
    
    id action = [CCSequence actions:moveBy,callBack, nil];
    
    enemySprite .visible = YES;
    
    enemySprite.position = ccp(arc4random()% (int) (winSize.width -enemySprite.contentSize.width)+ enemySprite.contentSize.width/2, enemySprite.position.y);
    
    CCLOG(@"enemySprite x = %f, y = %f",enemySprite.position.x, enemySprite.position.y);
    
    [enemySprite runAction:action];
    
    [self performSelector:_cmd withObject:nil afterDelay:arc4random()%3 +1];
    

}

- (CCSprite *)getAvaliableEnemySprite
{
    CCSprite *result = nil;
    
    CCARRAY_FOREACH(_enemySprites, result)
    {
        if (!result.visible)
            break;
       
    
    }
    
    return  result;

}


#pragma  mark 如何操作加速计

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    float deceleration = 0.4f;
    float sensitivity = 6.0f;
    
    float maxVelocity = 100;
    
    _playerVelocity.x =_playerVelocity.x *deceleration + acceleration.x *sensitivity;
    
    if (_playerVelocity.x > maxVelocity)
        _playerVelocity.x = maxVelocity;
    else if(_playerVelocity.x < -maxVelocity)
        _playerVelocity.x = -maxVelocity;

    
}

//计算精灵的大小位置
- (CGRect)rectOfSprite: (CCSprite *)sprite
{
    return CGRectMake(sprite.position.x - sprite.contentSize.width/2, sprite.position.y - sprite.contentSize.height/2, sprite.contentSize.width, sprite.contentSize.height);
    

}

//碰撞检测
- (void)collisionDetection:(ccTime)dt
{
    CCSprite *enemy;
    
    CGRect bulletRect = [self rectOfSprite:_bulletSprite];
    
    CCARRAY_FOREACH(_enemySprites, enemy)
    {
        if (enemy.visible) {
            CGRect enemyRect = [self rectOfSprite:enemy];
            
            if (_bulletSprite.visible &&CGRectIntersectsRect(bulletRect, enemyRect)) {
                enemy.visible = NO;
                _bulletSprite.visible = NO;
                
                _totalScore += 100;
                
                if (_totalScore >= 1000) {
                    [_gameEndlabel setString:@"游戏胜利!"];
                    _gameEndlabel.visible = YES;
                    
                    id scaleTo = [CCScaleTo actionWithDuration:1.0 scale:1.2f];
                    
                    [_gameEndlabel runAction:scaleTo];
                    
                    [self unscheduleUpdate];
                    
                    [self performSelector:@selector(onRestartGame) withObject:nil afterDelay:2.0f];
                    
                }
                
                [_bulletSprite stopAllActions];
                [enemy stopAllActions];
                CCLOG(@"collision Bullet");
                break;
            }
            
            CCSprite *playerSprite = (CCSprite *)[self getChildByTag:kTagPlayer];
            CGRect playRect = [self rectOfSprite:playerSprite];
            
            if (playerSprite.visible &&playerSprite.numberOfRunningActions == 0 && CGRectIntersectsRect(enemyRect, playRect)) {
                enemy.visible = NO;
                
                _totalLives -= 1;
                
                if (_totalLives <= 0) {
                    [_gameEndlabel setString:@"游戏失败"];
                    _gameEndlabel.visible = YES;
                    
                    id scaleTo = [CCScaleTo actionWithDuration:1.0 scale:1.2f];
                    [_gameEndlabel runAction:scaleTo];
                    [self unscheduleUpdate];
                    
                    [self performSelector:@selector(onRestartGame) withObject:nil afterDelay:3.0f];
                }
                
                id blink = [CCBlink actionWithDuration:2.0 blinks:4];
                
                [playerSprite stopAllActions];
                
                [playerSprite runAction:blink];
                
                CCLOG(@"collision player");
                
                break;
                
            }
            
        }
    
    
    }


}


- (void)onRestartGame
{
    [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer scene]];

}


// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	// in case you have something to dealloc, do it in this method
	// in this particular example nothing needs to be released.
	// cocos2d will automatically release all the children (Label)
	
	// don't forget to call "super dealloc"
    [_enemySprites release];
    _enemySprites = nil;
	[super dealloc];
}



@end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值