终于效果图:



纹理素材



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

场景

  1. //
  2. // GameScene.m
  3. // 31_cocos2D入门
  4. //
  5. // Created by beyond on 14-9-27.
  6. // Copyright (c) 2014年 com.beyond. All rights reserved.
  7. // 雷电,游戏场景
  8.  
  9. #import "GameScene.h"
  10. #import "Hero.h"
  11. // 背景音乐
  12. //#import "SimpleAudioEngine.h"
  13. #import "OALSimpleAudio.h"
  14. // 子弹精灵
  15. #import "Pellet.h"
  16. // 敌机
  17. #import "Enemy.h"
  18.  
  19. // 一次性初始化的子弹的最大数量
  20. #define kPelletMaxCount 10
  21. // 子弹两次出现之间的总的累计时间间隔
  22. #define kPelletTotalIntervalTime 0.3
  23.  
  24. // 敌机的最大数量
  25. #define kEnemyMaxCount 5
  26.  
  27. @interface GameScene()
  28. {
  29. // 由于一个spriteBatchNode相应一个纹理(图片),因此,从纹理相冊裁剪出来的小精灵(帧),全部交给spriteBatchNode统一管理,场景仅仅须要 与 spriteBatchNode打交道
  30. CCSpriteBatchNode *_batch;
  31. // 背景2图片 始终在背景1图片的头顶上
  32. CCSprite *_bg1, *_bg2;
  33.  
  34. // 英雄,主角
  35. Hero *_hero;
  36. // 标记 是否正在执行
  37. BOOL _isGameRuning;
  38.  
  39. // 重要~~~~子弹缓存
  40. NSMutableArray *_pelletArr;
  41. // 成员变量 用于记住 累加的间隔时间,它当达到一定量时(如0.3秒),才发射一串子弹
  42. // 子弹两次出现之间的总的间隔(累积)时间
  43. CGFloat _pelletTotalIntervalTime;
  44.  
  45. // 重要~~~~敌人缓存
  46. NSMutableArray *_enemyArr;
  47.  
  48. }
  49. @end
  50.  
  51. @implementation GameScene
  52.  
  53. #pragma mark - 覆盖父类方法
  54. -(id)init
  55. {
  56. if (self=[super init]) {
  57.  
  58. // 1.基本初始化
  59. [self setupBasic];
  60.  
  61. // 2.初始化背景
  62. // 初始化背景 ,并加入到batchNode中,统一管理,在时钟方法里,滚动背景
  63. [self setupBg];
  64.  
  65. // 3.初始化英雄
  66. // 初始化英雄 ,并加入到batchNode中,统一管理,在时钟方法里,碰撞检測
  67. [self setupPlayer];
  68.  
  69. // 4.初始化子弹
  70. // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
  71. [self setupPelletArr];
  72.  
  73. // 5.初始化敌机
  74. [self setupEnemyArr];
  75.  
  76. // 6.開始游戏
  77. [self startGame];
  78. }
  79. return self;
  80. }
  81.  
  82. #pragma mark - 初始化
  83.  
  84. #pragma mark 1.基本初始化
  85. - (void)setupBasic
  86. {
  87.  
  88. // 1.载入纹理相冊 到精灵帧缓存
  89. [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"gameArts.plist"];
  90.  
  91. // 2.创建sprite批处理
  92. _batch = [CCSpriteBatchNode batchNodeWithFile:@"gameArts.png"];
  93. [self addChild:_batch];
  94.  
  95. // 3.加入一个button,暂停或继续游戏
  96. [self setupPauseButton];
  97. }
  98. // 4.加入一个button,暂停或继续游戏
  99. - (void)setupPauseButton
  100. {
  101. // 调用父类封装的方法,绑定监听方法:gameControlBtnClicked
  102. [self addBtn:@"暂停/继续" position:ccp(0.5, 0.5) target:self sel:@selector(gameControlBtnClicked)];
  103.  
  104. }
  105. #pragma mark 2.初始化背景
  106. - (void)setupBg
  107. {
  108.  
  109. NSString *bgPicName = @"background_2.png";
  110. _bg1 = [CCSprite spriteWithImageNamed:bgPicName];
  111. _bg1.anchorPoint = CGPointZero;
  112.  
  113. // 背景2图片 始终在背景1图片 的头顶上
  114. _bg2 = [CCSprite spriteWithImageNamed:bgPicName];
  115. _bg2.anchorPoint = CGPointZero;
  116.  
  117. [_batch addChild:_bg1];
  118. [_batch addChild:_bg2];
  119. }
  120. #pragma mark 3.初始化玩家
  121. - (void)setupPlayer
  122. {
  123. _hero = [Hero node];
  124. // 由于是从同一个大纹理中,依据key裁剪出来的,所以能够加到同一个精灵batchNode,由它统一管理
  125. [_batch addChild:_hero];
  126. }
  127. #pragma mark 4.初始化子弹缓存
  128. // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
  129. - (void)setupPelletArr
  130. {
  131. _pelletArr = [NSMutableArray array];
  132. // 初始化指定数量的子弹 ,并加入到batchNode中,统一管理,在时钟方法里,射出子弹
  133. for (int i = 0; i<kPelletMaxCount; i++) {
  134. // 默认 就是先隐藏的
  135. Pellet *b = [Pellet node];
  136. // 类型为:大子弹
  137. b.type = kPelletTypeBig;
  138. // 加入到数组中
  139. [_pelletArr addObject:b];
  140. // 加入到spriteBatchNode
  141. [_batch addChild:b];
  142. }
  143.  
  144. }
  145.  
  146. #pragma mark 5.初始化敌机缓存
  147. // 初始化指定数量的敌机 ,并加入到batchNode中,统一管理,在时钟方法里,安排敌机出场
  148. - (void)setupEnemyArr
  149. {
  150. // 1.初始化 敌机缓存
  151. _enemyArr = [[NSMutableArray alloc] init];
  152.  
  153. for (int i = 0; i<kEnemyMaxCount; i++) {
  154. // 默认 就是先隐藏的
  155. Enemy *e = [Enemy node];
  156. // 类型为:敌机_1
  157. e.type = kEnemyType_1;
  158. // 加入到 敌机数组中
  159. [_enemyArr addObject:e];
  160. // 加入到spriteBatchNode
  161. [_batch addChild:e];
  162. }
  163.  
  164. }
  165. #pragma mark - 游戏控制button点击
  166. - (void)gameControlBtnClicked
  167. {
  168. // 假设 正在游戏,就暂停;反之继续游戏
  169. if (_isGameRuning) {
  170. // _isGameRuning = NO;
  171. [self pauseGame];
  172. } else {
  173. // _isGameRuning = YES;
  174. [self startGame];
  175. }
  176. }
  177. #pragma mark 開始
  178. - (void)startGame
  179. {
  180. // 1.首先置标记为 1
  181. _isGameRuning = YES;
  182. // 同意交互
  183. self.userInteractionEnabled = YES;
  184.  
  185. // 2.播放背景音乐
  186.  
  187. [[OALSimpleAudio sharedInstance] preloadBg:@"game_music.mp3"];
  188. [[OALSimpleAudio sharedInstance] playBgWithLoop:YES];
  189. // [[OALSimpleAudio sharedInstance]playBg:@"game_music.mp3" loop:YES];
  190. // 3.初始化 子弹两次出现 之间须要的总的累计间隔时间,如 0.3秒
  191. // 这样一设置之后,game一開始就有子弹射出去了
  192. _pelletTotalIntervalTime = kPelletTotalIntervalTime;
  193.  
  194. }
  195. #pragma mark 暂停
  196. - (void)pauseGame
  197. {
  198. // 1.首先置标记为 0
  199. _isGameRuning = NO;
  200. // 停止交互(触摸移动)
  201. self.userInteractionEnabled = NO;
  202.  
  203. // 2.停止全部消息调度
  204. // 同一时候,也要让spriteBatchNode中管理的全部成员,执行 unscheduleAllSelectors 方法
  205. [_batch.children makeObjectsPerformSelector:@selector(unscheduleAllSelectors)];
  206.  
  207. // 3.暂停背景音乐
  208.  
  209. [[OALSimpleAudio sharedInstance]stopBg];
  210. [[OALSimpleAudio sharedInstance]stopAllEffects];
  211.  
  212. }
  213. #pragma mark 结束
  214. - (void)endGame
  215. {
  216. // 1.首先置标记为 0
  217. _isGameRuning = NO;
  218. self.userInteractionEnabled = NO;
  219.  
  220. // 2.停止全部消息调度
  221.  
  222. // 同一时候,也要让spriteBatchNode中管理的全部成员,执行 unscheduleAllSelectors 方法
  223. [_batch.children makeObjectsPerformSelector:@selector(unscheduleAllSelectors)];
  224.  
  225. // 3.停止背景音乐
  226.  
  227. }
  228. #pragma mark - 时钟方法
  229. - (void)update:(CCTime)delta
  230. {
  231. // 假设 游戏暂停中,则不更新不论什么状态
  232. if (!_isGameRuning) {
  233. return;
  234. }
  235.  
  236. // 1.背景动画(始终向下滚动)
  237. [self bgAnimation];
  238.  
  239. // 2.子弹动画(射出,执行轨迹)
  240. [self pelletAnimation:delta];
  241.  
  242. // 3.敌机出场作战
  243. [self enemyAnimation:delta];
  244.  
  245. // 4.碰撞\边界检測
  246. [self collsionAndBoundaryCheck];
  247. }
  248.  
  249. #pragma mark 1.滚动背景
  250. // 1.背景动画(始终向下滚动)
  251. - (void)bgAnimation
  252. {
  253. // 2张背景图片,始终相差一张图片的高度(不管屏幕多高)
  254. CGFloat height = _bg1.contentSize.height;
  255. CGFloat bg1_Y = _bg1.position.y;
  256. // 向下走
  257. bg1_Y--;
  258. // 临界点
  259. // 向下走过程中,假设 1 超出屏幕了,将1 拉回去(2的y取决于1的y,因此,仅仅要设置1的y)
  260. if (bg1_Y <= -height) {
  261. bg1_Y = 0;
  262. }
  263. _bg1.position = ccp(0, bg1_Y);
  264. // 2始终在1的头顶上
  265. _bg2.position = ccp(0, bg1_Y + height);
  266. }
  267. #pragma mark 2.子弹动画
  268. - (void)pelletAnimation:(CCTime)delta
  269. {
  270. // 先累加 delta时间,到一定量时,再发射子弹
  271. _pelletTotalIntervalTime += delta;
  272. // 假设累计间隔时间达到了 预订的值:如0.3秒,能够发射子弹,位置是:英雄头顶
  273. if (_pelletTotalIntervalTime >= kPelletTotalIntervalTime) {
  274.  
  275. Pellet *pellet;
  276. for (pellet in _pelletArr) {
  277. // 假设数组中,还有 子弹不可见,说明在屏幕外;因此,可回收循环使用;仅仅需又一次调整位置 发射出去
  278. if (pellet.visible == NO) {
  279. CGPoint from = ccp(_hero.position.x, CGRectGetMaxY(_hero.boundingBox));
  280. [pellet emitFrom:from velocity:ccp(0, 200)];
  281. break;
  282. }
  283. // 假设,数组中没有一个能够用的....那么遍历完后,仅仅能创建新的了,(记得也要加到数组中去哦~)
  284. pellet = nil;
  285. }
  286.  
  287. // 假设,数组中没有一个能够用的....那么遍历完后,仅仅能创建新的发射了,(记得也要加到数组中去哦~)
  288. // 没有可循环利用的子弹
  289. if (pellet == nil) {
  290. // 事实上,内部已经封装了,默认创建出来的新子弹是不可见,仅仅有在发射emit时,才可见
  291. Pellet *p = [Pellet node];
  292. // 大子弹
  293. p.type = kPelletTypeBig;
  294. // 重要~~~一定要,记得,加入到数组中
  295. [_pelletArr addObject:p];
  296.  
  297. // 加入到精灵batchNode
  298. [_batch addChild:p];
  299.  
  300. // 射出新子弹
  301. CGPoint from = ccp(_hero.position.x, CGRectGetMaxY(_hero.boundingBox));
  302. [p emitFrom:from velocity:ccp(0, 200)];
  303. }
  304. // 用于记录的成员变量,清零
  305. _pelletTotalIntervalTime = 0;
  306. }
  307. }
  308.  
  309. #pragma mark 3.敌机出场作战
  310. - (void)enemyAnimation:(CCTime)delta
  311. {
  312. Enemy *enemy;
  313. for (enemy in _enemyArr) {
  314. // 假设数组中,还有 敌机不可见,说明在屏幕外;因此,可回收循环使用;仅仅需又一次调整位置 參加战场
  315. if (enemy.visible == NO) {
  316. // 详细怎样 运动,内部自己决定
  317. [enemy attendTheBattle];
  318. // 一次时钟周期,送一个敌机上战场
  319. break;
  320. }
  321. }
  322.  
  323. }
  324.  
  325. #pragma mark 碰撞\边界检測
  326. - (void)collsionAndBoundaryCheck
  327. {
  328. // 子弹检測
  329. Pellet *pellet;
  330. for (pellet in _pelletArr) {
  331. // 仅仅有在屏幕范围内,可见的,才须要进行碰撞检測;如不可见,直接,分析下一个子弹
  332. if (pellet.visible == NO) continue;
  333.  
  334. // 1.子弹 与 屏幕 检測
  335. // 2.子弹 与 敌机 检測
  336. [self checkPellet:pellet];
  337.  
  338. }// 遍历子弹缓存数组 结束
  339.  
  340. }
  341. // 1.子弹 与 屏幕 检測
  342. // 2.子弹 与 敌机 检測
  343. - (void)checkPellet:(Pellet *)pellet
  344. {
  345. // 子弹边框与屏幕边框 进行交集检測
  346. if (!CGRectIntersectsRect(self.boundingBox, pellet.boundingBox)) {
  347. // 1.离开屏幕了(再无交集),子弹消失
  348. [pellet dismiss];
  349.  
  350. } else {
  351. // 2.子弹还在屏幕内,才要进行,与敌机的 碰撞检測
  352. // 敌机检測
  353. Enemy *enemy;
  354. for (enemy in _enemyArr) {
  355. // 假设不可见,不须要检測
  356. // 仅仅有在屏幕范围内,可见的,才须要进行碰撞检測;如不可见,直接,分析下一个
  357. if (enemy.visible == NO) continue;
  358. // 1.敌机与屏幕rect检測
  359. // 2.敌机与子弹检測
  360. // 3.敌机与英雄检測
  361. [self enemy:enemy checkWithPellet:pellet];
  362.  
  363. }// 遍历子弹缓存数组 结束
  364. }// 子弹 和 敌机的 碰撞检測
  365. }
  366.  
  367. // 1.敌机与屏幕rect检測
  368. // 2.敌机与子弹检測
  369. // 3.敌机与英雄检測
  370. - (void)enemy:(Enemy *)enemy checkWithPellet:(Pellet *)pellet
  371. {
  372. // 敌机 边框与屏幕rect边框 进行交集检測
  373. if (!CGRectIntersectsRect(self.boundingBox, enemy.boundingBox)) {
  374. // 假设 没有交集,代表,敌机 逃离屏幕范围,故隐藏 敌机;
  375. [enemy hide];
  376.  
  377. } else if (CGRectIntersectsRect(pellet.boundingBox, enemy.boundingBox)) {
  378. // 仅仅有在屏幕范围内的敌机,才须要 和 (在屏幕范围内的)子弹 进行交集检測
  379. // 首先,隐藏子弹
  380. [pellet dismiss];
  381.  
  382. // 然后,敌机中弹
  383. [enemy gotHit];
  384. } else {
  385. // 自己定义方法,英雄与敌机 交集检測
  386. [self enemyCheckWithHero:enemy];
  387. }
  388. }
  389. // 自己定义方法,英雄与敌机 交集检測
  390. - (void)enemyCheckWithHero:(Enemy *)enemy
  391. {
  392. // 子弹 尽管 没有打中,可是 英雄与敌机 相撞,结果还是,game over
  393. if (CGRectContainsRect(_hero.boundingBox, enemy.boundingBox)) {
  394. [_hero dieWithEnemyTogether];
  395.  
  396. // game over,结束游戏
  397. [self endGame];
  398. }
  399. }
  400. #pragma mark - 触摸事件
  401. // 必须有 touch began ,否则 不能响应
  402. - (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
  403. {
  404.  
  405. }
  406. - (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
  407. {
  408. // 1.当前点
  409. CGPoint curPoint = [[CCDirector sharedDirector] convertToGL:[touch locationInView:touch.view]];
  410.  
  411. // 2.上一个点
  412. CGPoint prePoint = [[CCDirector sharedDirector] convertToGL:[touch previousLocationInView:touch.view]];
  413.  
  414. // 3.设置飞机的位置
  415. CGPoint newPosition = ccpAdd(_hero.position, ccpSub(curPoint, prePoint));
  416.  
  417. // 4.拖动过程中,边界检測,不能出屏幕
  418. CGFloat _heroWidth = _hero.contentSize.width;
  419. CGFloat _heroHeight = _hero.contentSize.height;
  420. if (newPosition.x < _heroWidth*0.5) {
  421. return;
  422. } else if(newPosition.x > self.contentSize.width - _heroWidth*0.5){
  423. return;
  424. }else if (newPosition.y < 0){
  425. return;
  426. }else if(newPosition.y > self.contentSize.height - _heroHeight){
  427. return;
  428. }
  429. _hero.position = newPosition;
  430. }
  431. @end<span style="font-family:Courier New;color:#393939;"><span style="font-size: 24px; line-height: 32px; background-color: rgb(245, 245, 245);"><strong>
  432. </strong></span></span>

子弹Pellet

  1. //
  2. // Pellet.h
  3. // 31_cocos2D入门
  4. //
  5. // Created by beyond on 14-9-28.
  6. // Copyright (c) 2014年 com.beyond. All rights reserved.
  7. //
  8.  
  9. #import "CCSprite.h"
  10.  
  11. typedef enum {
  12. // 小子弹
  13. kPelletTypeSmall,
  14. // 大子弹
  15. kPelletTypeBig
  16. }PelletType;
  17.  
  18. @interface Pellet : CCSprite
  19. // 子弹类型
  20. @property (nonatomic,assign) PelletType type;
  21. // 子弹速度 (Y方向,和X方向)
  22. @property (nonatomic, assign) CGPoint velocity;
  23.  
  24. // 发射 emit,參数:射出的点 射出的速度
  25. - (void)emitFrom:(CGPoint)from velocity:(CGPoint)velocity;
  26. // 消失/隐藏
  27. - (void)dismiss;
  28.  
  29. @end

  1. //
  2. // Pellet.m
  3. // 31_cocos2D入门
  4. //
  5. // Created by beyond on 14-9-28.
  6. // Copyright (c) 2014年 com.beyond. All rights reserved.
  7. //
  8.  
  9. #import "Pellet.h"
  10.  
  11. // 精灵帧 用到
  12. #import "cocos2d.h"
  13. // 音效
  14. //#import "SimpleAudioEngine.h"
  15. #import "OALSimpleAudio.h"
  16.  
  17. @implementation Pellet
  18.  
  19. #pragma mark - 父类方法
  20.  
  21. -(id)init
  22. {
  23. if (self=[super init]) {
  24. // 子弹创建时,默认隐藏,仅仅有当调用发射emit方法时,才显示
  25. self.visible = NO;
  26. }
  27. return self;
  28. }
  29. #pragma mark - 拦截setter
  30. - (void)setType:(PelletType)type
  31. {
  32. _type = type;
  33.  
  34. // 更换子弹精灵的 图片
  35. NSString *imgName = _type == kPelletTypeSmall ?
  36.  
  37. @"bullet1.png" : @"bullet2.png";
  38. CCSpriteFrame *frame = [CCSpriteFrame frameWithImageNamed:imgName];
  39. [self setSpriteFrame:frame];
  40. }
  41.  
  42. #pragma mark - 供外界调用
  43. // 发射 emit,參数:射出的点 射出的速度
  44. - (void)emitFrom:(CGPoint)from velocity:(CGPoint)velocity{
  45. self.visible = YES;
  46.  
  47. // 设置位置
  48. self.position = from;
  49.  
  50. // 设置速度
  51. self.velocity = velocity;
  52. // 音效播放
  53. // [[SimpleAudioEngine sharedEngine] playEffect:@"Pellet.mp3"];
  54. [[OALSimpleAudio sharedInstance]playEffect:@"bullet.mp3"];
  55. }
  56. // 消失/隐藏
  57. - (void)dismiss
  58. {
  59. self.visible = NO;
  60.  
  61. [self unscheduleAllSelectors];
  62. }
  63.  
  64. #pragma mark - 时钟方法(飞行)
  65. - (void)update:(CCTime)delta
  66. {
  67. // 当子弹消失后,不再更新position...
  68. if (!self.visible) {
  69. return;
  70. }
  71. // deltaTime 时间内,移动(飞行)一段距离
  72. // 路程s = 速度v * 时间t
  73. CGPoint s = ccpMult(self.velocity, delta);
  74. self.position = ccpAdd(self.position, s);
  75. }
  76. @end

英雄Hero

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

  1. //
  2. // Hero.m
  3. // 31_cocos2D入门
  4. //
  5. // Created by beyond on 14-9-27.
  6. // Copyright (c) 2014年 com.beyond. All rights reserved.
  7. // 主角,代表玩家的 英雄
  8.  
  9. #import "Hero.h"
  10. #import "cocos2d.h"
  11. #import "CCDirector.h"
  12. #import "CCAnimation.h"
  13. @implementation Hero
  14.  
  15. // 初始化玩家(的飞机)
  16. - (id)init
  17. {
  18. // 事实上,磁盘里没有hero_fly_1.png 图片,它是到大图片的帧缓存中,依据key取出(裁剪)小图片
  19. if (self = [super initWithImageNamed:@"hero_fly_1.png"]) {
  20. // 1.初始化位置,底部,中间
  21. self.anchorPoint = ccp(0.5, 0);
  22. // 从导演那儿拿到viewSize就是屏幕的size
  23. CGSize fullScreenSize = [[CCDirector sharedDirector] viewSize];
  24. self.position = ccp(fullScreenSize.width * 0.5, 0);
  25.  
  26. // 2.创建 帧动画 须要的两个精灵帧
  27. CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
  28. CCSpriteFrame *frame1 = [cache spriteFrameByName:@"hero_fly_1.png"];
  29. CCSpriteFrame *frame2 = [cache spriteFrameByName:@"hero_fly_2.png"];
  30.  
  31. NSArray *spriteFramesArr = @[frame1, frame2] ;
  32.  
  33. // 3.为精灵加入动画
  34. CCAnimation *animation = [CCAnimation animationWithSpriteFrames:spriteFramesArr delay:0.1];
  35. CCActionAnimate *animate = [CCActionAnimate actionWithAnimation:animation];
  36. // 4.播放帧动画
  37. [self runAction:[CCActionRepeatForever actionWithAction:animate]];
  38. }
  39. return self;
  40. }
  41. // 简单处理,英 雄与敌机 相撞,结果还是,game over
  42. - (void)dieWithEnemyTogether
  43. {
  44. // 停止之前的帧动画
  45. [self stopAllActions];
  46.  
  47. // 直接播放 爆炸 帧动画
  48. NSMutableArray *frames = [NSMutableArray array];
  49.  
  50. for (int i = 1; i<=4; i++) {
  51. NSString *name = [NSString stringWithFormat:@"hero_blowup_%d.png", i];
  52. CCSpriteFrame *f = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
  53. [frames addObject:f];
  54. }
  55.  
  56. CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.1];
  57. [self runAction:[CCActionAnimate actionWithAnimation:animation]];
  58. }
  59. @end

敌机Enemy(有待发散)

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

  1. //
  2. // Enemy.m
  3. // 31_cocos2D入门
  4. //
  5. // Created by beyond on 14-9-28.
  6. // Copyright (c) 2014年 com.beyond. All rights reserved.
  7. //
  8.  
  9. #import "Enemy.h"
  10. #import "cocos2d.h"
  11. #import "OALSimpleAudio.h"
  12. #import "CCAnimation.h"
  13. #import "CCDirector.h"
  14.  
  15. @interface Enemy()
  16. {
  17. // 最大的生命值
  18. int _maxHp;
  19. // 生命值
  20. int _hp;
  21. }
  22. @end
  23.  
  24. @implementation Enemy
  25.  
  26. #pragma mark - 父类方法
  27.  
  28. -(id)init
  29. {
  30. if (self=[super init]) {
  31. // 敌机创建时,默认隐藏,仅仅有当调用出场,參加战斗 时,才显示
  32. self.visible = NO;
  33. }
  34. return self;
  35. }
  36.  
  37. #pragma mark - 拦截setter方法
  38. - (void)setType:(EnemyType)type
  39. {
  40. _type = type;
  41.  
  42. // 依据 敌人类型,设置 敌人显示的图片
  43. [self setEnemyImage];
  44.  
  45. // 依据 敌人类型,设置 敌人最大生命值
  46. switch (type) {
  47. case kEnemyType_1:
  48. _maxHp = 1;
  49. break;
  50. case kEnemyType_2:
  51. _maxHp = 2;
  52. break;
  53. case kEnemyType_3:
  54. _maxHp = 3;
  55. break;
  56. case kEnemyType_4:
  57. _maxHp = 4;
  58. break;
  59. case kEnemyType_5:
  60. _maxHp = 5;
  61. break;
  62.  
  63. default:
  64. break;
  65. }
  66. }
  67.  
  68. #pragma mark - 时钟方法
  69. - (void)update:(CCTime)delta
  70. {
  71. // 同其它的子弹、英雄一样,仅仅有在显示时,才须要更新位置
  72. // 当敌人处于不可见时,说明被打死了,或逃出屏幕了,因此无需更新其位置
  73. if (!self.visible) {
  74. return;
  75. }
  76. // 不断调整敌人的位置 (速度 能够和最大生命值一样,设置不同的...)
  77. self.position = ccpAdd(self.position, ccp( 0, -100 * delta));
  78. }
  79. #pragma mark - 供外部调用
  80. // 出如今游戏中,出场,增加战斗
  81. - (void)attendTheBattle
  82. {
  83. // 出场时,满血
  84. _hp = _maxHp;
  85. // 出场时,显示
  86. self.visible = YES;
  87. // 出场时,位置,从屏幕顶部俯冲下来
  88. self.anchorPoint = ccp(0.5, 0);
  89.  
  90. CGSize winSize = [CCDirector sharedDirector].viewSize;
  91. // 重要~~~之所以要减一,是由于...出场时,要让它一仅仅脚 踏进屏幕,与屏幕窗体的rect有交集
  92. self.position = ccp(winSize.width * CCRANDOM_0_1(), winSize.height - 1);
  93. // 边界检測
  94.  
  95. }
  96. // 被击中
  97. - (void)gotHit
  98. {
  99. _hp--;
  100.  
  101. if (_hp == 0) {
  102. // 1.播放相应的被打中时 的音效
  103. [self playHitSound];
  104. // 2.播放相应的被爆炸动画
  105. [self playExplodeAnimation];
  106.  
  107. }
  108. }
  109. // 消失
  110. - (void)hide
  111. {
  112. self.visible = NO;
  113.  
  114. [self unscheduleAllSelectors];
  115. }
  116.  
  117. #pragma mark - 抽取方法
  118. // 依据 敌人类型,设置 敌人显示的图片
  119. - (void)setEnemyImage
  120. {
  121. // 依据 敌人类型,设置 其图片
  122. NSString *name = [NSString stringWithFormat:@"enemy%d_fly_1.png", _type];
  123. // 从精灵帧缓存中,取出精灵帧,从而设置到精灵身上,显示
  124. CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
  125. [self setSpriteFrame:frame];
  126. }
  127.  
  128. // 播放相应的被打中时 的音效
  129. - (void)playHitSound
  130. {
  131. [[OALSimpleAudio sharedInstance] playEffect:[NSString stringWithFormat:@"enemy%d_down.mp3", _type]];
  132. }
  133. // 播放爆炸动画,爆炸完,隐藏,最后又一次设置显示图片,为參加下一次战斗作准备
  134. - (void)playExplodeAnimation
  135. {
  136. NSMutableArray *frames = [NSMutableArray array];
  137. // 这个爆炸效果的 4 应该动态变化 ....
  138. for (int i = 1; i<=4; i++) {
  139. NSString *name = [NSString stringWithFormat:@"enemy1_blowup_%d.png", i];
  140. CCSpriteFrame *f = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
  141. [frames addObject:f];
  142. }
  143. // 名词,动画
  144. CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.1];
  145. // 动作_1 爆炸
  146. CCActionAnimate *explosion = [CCActionAnimate actionWithAnimation:animation];
  147. // 动作_2 不可见
  148. CCActionHide *hide = [CCActionHide action];
  149. // 动作_3 由于爆炸后,精灵的显示图片变了,所以要又一次设置回来,以便下一次 參加战斗
  150. CCActionCallFunc *func = [CCActionCallFunc actionWithTarget:self selector:@selector(setEnemyImage)];
  151. // 动作_4 用序列包装
  152. CCActionSequence *sequence = [CCActionSequence actions:explosion,hide,func, nil];
  153. // 运行动作
  154. [self runAction:sequence];
  155. }
  156. @end



































iOS_31_cocos2d_微信飞机的更多相关文章

  1. 用DIV+Css+Jquery 实现的旧版微信飞机大战。

    用jquery 实现的旧版微信飞机大战. 以前一直都是做后台和业务逻辑,前端很少去做, 现在个小游戏. 方向键控制方向,Ctrl 键 放炸弹(当然你的有炸弹,哈哈)! 主要都是用div+Css实现的, ...

  2. 【一】仿微信飞机大战cocos2d-x3.0rc1

    參考 [偶尔e网事] 的 [cocos2d-x入门实战]微信飞机大战  cocos2dx 2.0版本号,偶尔e网事他写的很具体,面面俱到,大家很有必要看下.能够通过以下链接跳转: cocos2d-x入 ...

  3. Cocos2d-x 3.0final 终结者系列教程16-《微信飞机大战》实现

    看到cocos2d-x推出了3.1版本号,真是每月一次新版本号,速度. 另一个好消息就是http://cn.cocos2d-x.org/上线了,祝贺!啥时候把我的视频和教程放上去呢?!! . 视频下载 ...

  4. 用Javascript模拟微信飞机大战游戏

    最近微信的飞机大战非常流行,下载量非常高. 利用JS进行模拟制作了一个简单的飞机大战[此源码有很多地方可以进行重构和优化] [此游戏中没有使用HTML5 任何浏览器都可以运行]. 效果图: 原理:利用 ...

  5. 500行代码,教你用python写个微信飞机大战

    这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手. 帮助蹲厕族.YP族.饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右 ...

  6. [置顶] 【cocos2d-x入门实战】微信飞机大战之六:子弹层的处理

    这一篇将会处理完子弹层的其他要点. 1.子弹的初始位置 子弹的初始位置在飞机的机头位置,因为飞机在游戏的过程中会随着玩家的触摸而改变其位置,所以,子弹的初始位置只能以当前飞机位置为基准进行添加. CC ...

  7. [置顶] 【cocos2d-x入门实战】微信飞机大战之三:飞机要起飞了

    转载请表明地址:http://blog.csdn.net/jackystudio/article/details/11730601 不过明眼人一看就知道起飞的不是飞机,是背景,相对运动引起的错觉. 1 ...

  8. [置顶] 【cocos2d-x入门实战】微信飞机大战之四:飞机登场咯

    转载请表明地址:http://blog.csdn.net/jackystudio/article/details/11757175 昨天收到了电子工业出版社寄过来的<cocos2d-x游戏开发之 ...

  9. Html5 の 微信飞机大战

    (function () { var imageUrl = "images/"; //获取画布对象 var c = $("#game-box").get(0); ...

随机推荐

  1. Mac系统下安装pip

    Mac下 pip的安装 编译 Python3.7 终端输入: curl https://bootstrap.pypa.io/get-pip.py | python3 1 安装完成,检查版本信息 pip ...

  2. HTML学习----------DAY2第四节

    HTML 文档是由 HTML 元素定义的. HTML 元素 HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码. 注释:开始标签常被称为开放标签(opening ...

  3. bug14052601

    AppDelegate.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall cocos2d::ui::Margin::Margin(void ...

  4. easyui combobox 取值

    easyui combobox 取值 var zhudaoci = $.trim($('#spanZhudaociId').combobox('getValue')); 学习了:http://blog ...

  5. 使用maven运行单元測试总结

    maven本身没有单元測试框架,可是maven的default生命周期的test阶段绑定了maven-surefire-plugin插件,该插件能够调用Junit3.Junit4.TestNG等Jav ...

  6. Centos7 网络出错(failed to start LSB: Bring up/down networking )

    这是我更换了VM虚拟机内存,重启后无法连接网络. 然后这是因为NetworkManager.service这个程序造成 解决方法: systemctl disable NetworkManager.s ...

  7. 方便查看线程状况的jsp页面

    此方法来自深入理解java虚拟机一书,用作管理员页面,可以随时用浏览器查看线程堆栈 <%@ page language="java" import="java.ut ...

  8. epson 630打印机驱动安装不上

    1号机: 连接到630打印机的电脑 2号机: 通过网络连接到630打印机 *现状: 直接将数据线插在2号机上安装打印机时,驱动安装不上,设备管理器中有“!”号 *原因: 可能是已有一台通过网络连接到1 ...

  9. BZOJ5408: string(广义后缀自动机,LCT)

    传送门 解题思路: 首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内. 那么考虑一个新的点在串中对串答案的贡献在一条树链 ...

  10. WP8 学习笔记(002_应用程序结构)

    下图是微软官方给出的WP8应用程序执行顺序: 在App.XAML.CS中,有程序主要步骤的函数 // 应用程序启动(例如,从“开始”菜单启动)时执行的代码 // 此代码在重新激活应用程序时不执行 pr ...