2:我的第一个Cocoa-2d游戏—打飞机

最后更新于:2022-04-01 20:14:56

这一下午边翻书边写代码,效果还是很不错的.先和大家分享下图片~ ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-22_57bab557cd404.jpg) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-22_57bab557f3937.jpg) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-22_57bab55828840.jpg) 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 ~~~
';