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
~~~
';