展会信息港展会大全

iOS_31_cocos2d_微信飞机
来源:互联网   发布日期:2015-09-27 15:01:51   浏览:2611次  

导读:最终效果图: 纹理素材 场景 // // 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 SimpleAudi...

最终效果图:

纹理素材

场景

//

//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.添加一个按钮,暂停或继续游戏

[self setupPauseButton];

}

// 4.添加一个按钮,暂停或继续游戏

- (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= 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.xself.contentSize.width - _heroWidth*0.5){

return;

}else if (newPosition.yself.contentSize.height - _heroHeight){

return;

}

_hero.position = newPosition;

}

@end

子弹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

敌机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

赞助本站

人工智能实验室
相关内容
AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港