初始化的工作包括,2.游戏界面类

作者: 编程  发布:2019-08-28

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中),cocos2dx飞机大战

接《基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)》

三、代码分析

1.界面初始化

 1 bool PlaneWarGame::init()
 2 {
 3     bool bRet = false;
 4     do 
 5     {
 6         CC_BREAK_IF(! CCLayer::init());
 7 
 8         _size = CCDirector::sharedDirector()->getWinSize();
 9 
10         // 设置触摸可用
11         this->setIsTouchEnabled(true);
12         // 从窗口中取消息
13         CCDirector::sharedDirector()->getOpenGLView()->SetWin32KeyLayer( this );
14 
15         // 初始化游戏背景
16         CC_BREAK_IF(!initBackground());
17         // 菜单1(暂停/声音/炸弹)
18         CC_BREAK_IF(!initMenu1());
19         // 菜单2(继续/重新开始/返回)
20         CC_BREAK_IF(!initMenu2());
21         // 菜单3(重新开始/返回)
22         CC_BREAK_IF(!initMenu3());
23 
24         // 创建玩家飞机
25         _player = new PlaySprite;
26         _player->setPosition(CCPointZero);
27         addChild(_player);
28 
29         // 调度器:定时调用自定义的回扫函数
30         this->schedule( schedule_selector(PlaneWarGame::gameLoop));
31         this->schedule( schedule_selector(PlaneWarGame::shoot), 0.1 );
32         this->schedule( schedule_selector(PlaneWarGame::addEnemy), 0.3 );
33         this->schedule( schedule_selector(PlaneWarGame::addProp), 5 );
34 
35         // 初始化两个数组
36         _enemys = CCArray::array();
37         _enemys->retain();
38         _bullets = CCArray::array();
39         _bullets->retain();
40         
41         // 背景音乐
42         CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic(
43             "planewar/game_music.wav", true);
44 
45         bRet = true;
46     } while (0);
47 
48     return bRet;
49 }

初始化的工作包括:

  • 设置触摸可用
  •   设置可自定义处理消息
  •       初始化游戏背景
  •   初始化三个菜单(界面菜单/游戏暂停时的菜单/游戏结束时的菜单)
  •   初始化两个CCArray类型的数组,分别用来存储有效的敌机精灵对象和子弹对象
  •       设置需要定时调用函数的调度器
  •       设置背景音乐
  •       添加玩家角色

 

2.初始化游戏背景

 1 bool PlaneWarGame::initBackground()
 2 {
 3     // 显示分数
 4     _label = CCLabelBMFont::labelWithString("0123456789","planewar/font.fnt");
 5     _label->setPosition(ccp(220,_size.height-20));
 6     _label->setColor(ccc3(0,0,0));
 7     this->addChild(_label, 1);
 8 
 9     // 显示炸弹数量
10     CCLabelBMFont* bombcount = CCLabelBMFont::labelWithString("X09","planewar/font.fnt");
11     bombcount->setAnchorPoint(ccp(0,0));
12     bombcount->setPosition(ccp(73,10));
13     bombcount->setColor(ccc3(0,0,0));
14     addChild(bombcount, 10,111);
15 
16     // 添加背景
17     CCSprite* bg1 = CCSprite::spriteWithFile("planewar/bg1.png");
18     if (!bg1)return false;
19     bg1->setAnchorPoint(ccp(0,1));
20     bg1->setPosition( ccp(0, _size.height) );
21     this->addChild(bg1, 0, 11);
22 
23     bg1->runAction(
24         CCSequence::actions(
25         CCMoveBy::actionWithDuration(10,ccp(0,-720)),
26         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg1roll)),NULL));
27 
28     CCSprite* bg2 = CCSprite::spriteWithFile("planewar/bg2.png");
29     if (!bg1)return false;
30     bg2->setAnchorPoint(ccp(0,1));
31     bg2->setPosition( ccp(0, _size.height*2) );
32     this->addChild(bg2, 0, 12);
33 
34     bg2->runAction(
35         CCSequence::actions(
36         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
37         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg2roll)),NULL));
38     return true;
39 }
40 
41 void PlaneWarGame::bg1roll(){
42     //运动出屏幕重设位置,运动
43     CCSprite * bg = (CCSprite *)getChildByTag(11);
44     bg->setPosition(ccp(0,1440));
45     CCAction* seq = CCSequence::actions(
46         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
47         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg1roll)),NULL);
48     bg->runAction(seq);
49 }
50 
51 void PlaneWarGame::bg2roll(){
52     //运动出屏幕重设位置,运动
53     CCSprite * bg = (CCSprite *)getChildByTag(12);
54     bg->setPosition(ccp(0,1440));
55     CCAction* seq = CCSequence::actions(
56         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
57         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg2roll)),NULL);
58     bg->runAction(seq);
59 }

 初始化游戏背景时,需要注意的是:要做出飞机向上走的视觉效果,就要把背景向下滚动,这里使用两个背景bg1和bg2,大小分别为屏幕大小。初始bg1在屏幕内,bg2在屏幕上方,两个同事向下运动;当bg1刚刚运动到屏幕外,bg2刚好盖住屏幕,bg1挪到屏幕上方向下运动...循环操作,就能做出循环滚动的背景效果了。

 

3.子弹的处理

 1 // 确定子弹类型
 2 void PlaneWarGame::shoot(float dt)
 3 {
 4     if (_isOver)return;
 5     if(_player==NULL) return;
 6 
 7     if(_player->_bulletKind == BK_SINGLE)
 8     {
 9         CCSprite *bullet = CCSprite::spriteWithFile(
10             "planewar/plane.png", CCRectMake(112,2,9,17));
11         addBullet(bullet,_player->getPlayerPt());
12     }else if (_player->_bulletKind == BK_DOUBLE)
13     {
14         CCSprite *bullet = CCSprite::spriteWithFile(
15             "planewar/plane.png", CCRectMake(66,238,8,15));
16         addBullet(bullet,ccp(_player->getPlayerPt().x-20,_player->getPlayerPt().y));
17         CCSprite *bullet1 = CCSprite::spriteWithFile(
18             "planewar/plane.png", CCRectMake(66,238,8,15));
19         addBullet(bullet1,ccp(_player->getPlayerPt().x 20,_player->getPlayerPt().y));
20     }
21 }
22 // 添加子弹
23 void PlaneWarGame::addBullet(CCSprite* bullet, CCPoint pt)
24 {    
25     bullet->setPosition(pt);
26     this->addChild(bullet);
27 
28     bullet->runAction( CCSequence::actions(
29         CCMoveTo::actionWithDuration(0.5, ccp(pt.x,_size.height bullet->getContentSize().height/2)),
30         CCCallFuncN::actionWithTarget(this,callfuncN_selector(PlaneWarGame::spriteMoveFinished)), 
31         NULL) );
32 
33     bullet->setTag(1);
34     _bullets->addObject(bullet);
35 }
36 // 回收
37 void PlaneWarGame::spriteMoveFinished(CCNode* sender)
38 {
39     CCSprite *sprite = (CCSprite *)sender;
40     this->removeChild(sprite, true);
41     if (sprite->getTag()==1)//子弹
42         _bullets->removeObject(sprite);
43 }

 吃道具可改变子弹类型。子弹的回收方式:从飞机坐标处出发,运动到屏幕外被回收。道具的处理类似。

 

4.设置触摸/鼠标点击控制玩家角色的移动

 1 bool PlaneWarGame::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
 2 {
 3     if(_player==NULL) return false;
 4 
 5     CCPoint pt = CCDirector::sharedDirector()->convertToGL(
 6         pTouch->locationInView(pTouch->view()));
 7 
 8     CCRect rt = _player->getRect();
 9     if (CCRect::CCRectContainsPoint(rt,pt))
10         _player->_isDragEnabled = true;
11     return true;
12 }
13 
14 void PlaneWarGame::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
15 {
16     if(_player==NULL) return;
17 
18     CCSize size = CCDirector::sharedDirector()->getWinSize();
19     CCPoint pt = CCDirector::sharedDirector()->convertToGL(
20         pTouch->locationInView(pTouch->view()));
21     
22     CCRect rt = CCRect(0,0,size.width,size.height);
23 
24     if (_player->_isDragEnabled && CCRect::CCRectContainsPoint(rt,pt))
25         _player->setPlayerPt(pt);
26 }
27 
28 void PlaneWarGame::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
29 {
30     _player->_isDragEnabled = false;
31 }

这里重写3个虚函数。移动角色的方式:触摸/鼠标按下时,如果点击位置在角色上,将角色可被拖拽状态置为true;触摸/鼠标移动时,根据角色的可被拖拽状态和屏幕范围确定是否移动;触摸/鼠标弹起时,将角色的可被拖拽状态恢复为false。

 

5.碰撞检测

  1 void PlaneWarGame::updateGame(float dt)
  2 {
  3     CCArray *bulletsToDelete = CCArray::array();
  4     CCObject* it = NULL;
  5     CCObject* jt = NULL;
  6     
  7     if(_player==NULL) return;
  8 
  9     CCRect playerRect = _player->getRect();
 10     // 己方飞机和敌方飞机的碰撞
 11     CCARRAY_FOREACH(_enemys, jt)
 12     {
 13         EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 14         if (!enemy->isNull() && CCRect::CCRectIntersectsRect(playerRect, enemy->getRect()))
 15         {
 16             _player->die();
 17             gameover(false);
 18             return;
 19         }
 20     }
 21 
 22     //////////////////////////////////////////////////////////////////////////
 23         // 道具和角色的碰撞检测
 24     CCSprite* prop = (CCSprite*)getChildByTag(8);//子弹
 25     if (NULL != prop)
 26     {
 27         CCRect propRect = CCRectMake(
 28             prop->getPosition().x - (prop->getContentSize().width/2),
 29             prop->getPosition().y - (prop->getContentSize().height/2),
 30             prop->getContentSize().width,
 31             prop->getContentSize().height);
 32         if (CCRect::CCRectIntersectsRect(playerRect, propRect))
 33         {
 34             _player->_bulletKind = BK_DOUBLE;
 35             removeChild(prop,true);
 36             CocosDenshion::SimpleAudioEngine::sharedEngine()->
 37                 playEffect("planewar/get_double_laser.wav",false);
 38         }
 39     }
 40     CCSprite* prop1 = (CCSprite*)getChildByTag(9);//炸弹
 41     if (NULL != prop1)
 42     {
 43         CCRect prop1Rect = CCRectMake(
 44             prop1->getPosition().x - (prop1->getContentSize().width/2),
 45             prop1->getPosition().y - (prop1->getContentSize().height/2),
 46             prop1->getContentSize().width,
 47             prop1->getContentSize().height);
 48         if (CCRect::CCRectIntersectsRect(playerRect, prop1Rect))
 49         {
 50             _player->_bombCount  ;
 51             removeChild(prop1,true);
 52             CocosDenshion::SimpleAudioEngine::sharedEngine()->
 53                 playEffect("planewar/get_bomb.wav",false);
 54         }
 55     }
 56 
 57     //////////////////////////////////////////////////////////////////////////
 58         // 子弹和敌机的碰撞检测
 59     CCARRAY_FOREACH(_bullets, it)
 60     for (int i=0; i<_bullets->count(); i  )
 61     {
 62         CCSprite *bullet = dynamic_cast<CCSprite*>(_bullets->objectAtIndex(i));
 63         CCRect bulletRect = CCRectMake(
 64             bullet->getPosition().x - (bullet->getContentSize().width/2),
 65             bullet->getPosition().y - (bullet->getContentSize().height/2),
 66             bullet->getContentSize().width,
 67             bullet->getContentSize().height);
 68 
 69         CCArray* enemysToDelete =CCArray::array();
 70 
 71         CCARRAY_FOREACH(_enemys, jt)
 72         {
 73             EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 74             if (!enemy->_die && CCRect::CCRectIntersectsRect(bulletRect, enemy->getRect()))
 75             {
 76                 if (enemy->_hp>0)
 77                 {
 78                     enemy->_hp--;
 79                     //bulletsToDelete->addObject(bullet);
 80                     _bullets->removeObject(bullet);
 81                     removeChild(bullet,true);
 82                 }
 83                 else if (enemy->_hp<=0)
 84                 {
 85                     //bulletsToDelete->addObject(bullet);
 86                     _bullets->removeObject(bullet);
 87                     removeChild(bullet,true);
 88                     enemysToDelete->addObject(enemy);
 89                 }
 90             }
 91         }
 92 
 93         CCARRAY_FOREACH(enemysToDelete, jt)
 94         {
 95             EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 96             enemy->_die = true;
 97             enemy->die();
 98             _bulletsDestroyed  ;
 99         }
100 
101         enemysToDelete->release();
102     }
103 
104     // 释放已死亡的子弹
105     CCARRAY_FOREACH(bulletsToDelete, it)
106     {
107         CCSprite* projectile = dynamic_cast<CCSprite*>(it);
108         _bullets->removeObject(projectile);
109         this->removeChild(projectile, true);
110     }
111     bulletsToDelete->release();
112 }          

 碰撞检测使用最简单的矩形检测。

 

6.玩家角色的添加和操作

  1 void PlaySprite::onEnter()
  2 {
  3     CCNode::onEnter();
  4 
  5     CCSize size = CCDirector::sharedDirector()->getWinSize();
  6     _sprite = CCSprite::spriteWithFile("planewar/hero1.png");
  7     _sprite->setContentSize(CCSize(62,68));
  8     _sprite->setPosition( ccp(size.width/2,_sprite->getContentSize().height/2) );
  9     addChild(_sprite,10);
 10 
 11     CCAnimation * animation = CCAnimation::animation();
 12     animation->addFrameWithFileName("planewar/hero1.png");
 13     animation->addFrameWithFileName("planewar/hero2.png");
 14     CCAction* action = CCRepeatForever::actionWithAction(
 15         CCAnimate::actionWithDuration(0.1f, animation, false));
 16     action->setTag(11);
 17     _sprite->runAction(action);
 18 
 19     // 调度器
 20     schedule( schedule_selector(PlaySprite::move), 0.002 );
 21 }
 22 
 23 CCRect PlaySprite::getRect()
 24 {
 25     if (_sprite!=NULL)
 26         return CCRect(
 27         _sprite->getPosition().x - (_sprite->getContentSize().width/2),
 28         _sprite->getPosition().y - (_sprite->getContentSize().height/2),
 29         _sprite->getContentSize().width,
 30         _sprite->getContentSize().height);
 31 }    
 32 
 33 CCPoint PlaySprite::getPlayerPt()
 34 {
 35     if (_sprite!=NULL)
 36         return _sprite->getPosition();
 37 }
 38 
 39 void PlaySprite::setPlayerPt(CCPoint pt)
 40 {
 41     if (_sprite!=NULL)
 42         return _sprite->setPosition(pt);
 43 }
 44 
 45 void  PlaySprite::setMoveMode( UINT  message, WPARAM  wParam) 
 46 {
 47     if (message == WM_KEYDOWN)
 48     {// 控制飞机移动
 49         if (wParam == VK_UP)
 50             _mode = MM_UP;
 51         else if (wParam == VK_DOWN)
 52             _mode = MM_DOWN;
 53         else if (wParam == VK_LEFT)
 54             _mode = MM_LEFT;
 55         else if (wParam == VK_RIGHT)
 56             _mode = MM_RIGHT;
 57     }else if (message == WM_KEYUP)
 58     {
 59         if (wParam == VK_UP || wParam == VK_DOWN ||wParam == VK_LEFT||wParam == VK_RIGHT)
 60             _mode = MM_NONE;
 61     }
 62 }
 63 
 64 void PlaySprite::move(float dt)
 65 {
 66     CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 67 
 68     switch(_mode)
 69     {
 70     case MM_NONE:
 71         break;
 72     case MM_UP:
 73         if (getPlayerPt().y<winSize.height)
 74             setPlayerPt(ccp(getPlayerPt().x,getPlayerPt().y 1));
 75         break;
 76     case MM_DOWN:
 77         if (getPlayerPt().y>0)
 78             setPlayerPt(ccp(getPlayerPt().x,getPlayerPt().y-1));
 79         break;
 80     case MM_LEFT:
 81         if (getPlayerPt().x>0)
 82             setPlayerPt(ccp(getPlayerPt().x-1,getPlayerPt().y));
 83         break;
 84     case  MM_RIGHT:
 85         if (getPlayerPt().x<winSize.width)
 86             setPlayerPt(ccp(getPlayerPt().x 1,getPlayerPt().y));
 87         break;
 88     }
 89 }
 90 
 91 void PlaySprite::die()
 92 {
 93     if (_sprite==NULL)return;
 94 
 95     _sprite->stopActionByTag(11);
 96     CCAnimation * animation = CCAnimation::animation();
 97     animation->addFrameWithFileName("planewar/hero_blowup_n1.png");
 98     animation->addFrameWithFileName("planewar/hero_blowup_n2.png");
 99     animation->addFrameWithFileName("planewar/hero_blowup_n3.png");
100     animation->addFrameWithFileName("planewar/hero_blowup_n4.png");
101     _sprite->runAction(CCSequence::actions(
102         CCAnimate::actionWithDuration(0.1f, animation, false),
103         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaySprite::destroy)),NULL));
104 }
105 
106 void PlaySprite::destroy()
107 {
108     if (_sprite==NULL)return;
109     
110     removeChild(_sprite,true);
111     _sprite = NULL;
112 }
  • 玩家角色类是派生自CCNode类,用组合的方式包含一个CCSprite类的成员对象,在玩家角色类内部封装对精灵的操作。
  • 重写onEnter函数初始化_sprite成员,设置位置、大小、图片和帧动画等。
  • 玩家的方向键控制移动和鼠标拖拽移动方式类似,在操作时设置移动状态,在schedule定时调用的函数move中根据移动状态来移动玩家角色。
  • 关于碰撞之后的动画和销毁,参照上面的die和destroy函数,对象被碰撞时调用die函数运行爆炸的帧动画,动画结束后自动调用destroy函数销毁对象。
  • 敌机对象的操作和玩家角色类似。

 

四、完成效果图

经过不到一周的时间,从什么都没有,到游戏正常运行、功能完整,体会了cocos2dx的调用机制。

下面是运行效果图:

9159.com 19159.com 2

9159.com 39159.com 4

9159.com 5

 

如果实现中有什么问题,欢迎大家在评论中指教!

 

接《基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)》

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上),cocos2dx飞机大战

最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下。本实例模仿微信5.0版本中的飞机大战游戏,如图:

9159.com 6

 

一、工具

1.素材:飞机大战的素材(图片、声音等)来自于网络

2.引擎:cocos2d-1.0.1-x-0.9.2

3.环境:vs2010

二、使用的类

1.游戏菜单界面类:PlaneWarMenu——派生自CCLayer类。

 1 // 游戏菜单界面类
 2 class PlaneWarMenu: public CCLayer
 3 {
 4 public:
 5     virtual bool init();  
 6     static cocos2d::CCScene* scene();
 7 
 8     virtual void menuStartCallback(CCObject* pSender);
 9     virtual void menuManualCallback(CCObject* pSender);
10     virtual void menuAboutCallback(CCObject* pSender);
11     virtual void menuBackCallback(CCObject* pSender);
12 
13     LAYER_NODE_FUNC(PlaneWarMenu);
14 };

 

2.游戏界面类:PlaneWarGame——派生自CCLayer类。

 1 // 游戏界面类
 2 class PlaneWarGame :public CCLayer
 3 {
 4 public:
 5     PlaneWarGame();
 6     ~PlaneWarGame();
 7     static CCScene* scene();
 8     virtual bool init();
 9     
10     // 游戏界面的初始化
11     bool initBackground();
12     void bg1roll();
13     void bg2roll();
14     bool initMenu1();
15     bool initMenu2();
16     bool initMenu3();
17 
18     // 游戏界面内的菜单项回调
19     void menuPauseCallback(CCObject* pSender);
20     void menuSoundCallback(CCObject* pSender);
21     void menuBombCallback(CCObject* pSender);
22     void menuResumeCallback(CCObject* pSender);
23     void menuRestartCallback(CCObject* pSender);
24     void menuBackCallback(CCObject* pSender);
25 
26     LAYER_NODE_FUNC(PlaneWarGame);
27 
28     // 敌机产生
29     void addEnemy(float dt);
30     // 玩家发射子弹
31     void shoot(float dt);
32     // 游戏逻辑的循环
33     void gameLoop(float dt);
34     void addBullet(CCSprite* bullet, CCPoint pt);
35     // 道具的产生
36     void addProp(float dt);
37     // 游戏的碰撞检测
38     void updateGame(float dt);
39     // 数据显示
40     void show();
41     // 游戏结束
42     void gameover(bool isWin);
43 
44     void spriteMoveFinished(CCNode* sender);
45     void killAllEnemys();
46     void releaseEnemys();
47 
48     // 键盘消息处理
49     void processWin32KeyPress(UINT message, WPARAM wParam, LPARAM lParam);
50     // 触摸操作
51     void registerWithTouchDispatcher();
52     virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
53     virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
54     virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
55 protected:
56     
57     // 游戏成员
58     PlaySprite*         _player;            // 玩家飞机
59     CCArray*            _enemys;            // 敌方飞机数组
60     CCArray*            _bullets;           // 子弹数组
61     int                 _bulletsDestroyed;  // 子弹击中目标个数
62 
63     // 游戏控件
64     CCLabelBMFont*      _label;             // 分数标签
65     CCMenuItemSprite*   _pause;             // 暂停按钮
66     CCMenu*             _menu;              // 游戏界面内的菜单(暂停/声音/炸弹)
67     
68     // 主要游戏属性
69     bool                _issound;           // 背景音乐开关
70     CCSize              _size;              // 游戏界面大小(屏幕大小)
71     int                 _score;             // 分数
72     bool                _isOver;            // 游戏结束标志
73 };

 

 

3.游戏介绍类:PlaneWarInfoboard——派生自CCLayer类。

 1 // 游戏介绍类
 2 class PlaneWarInfoboard: public CCLayer
 3 {
 4 public:
 5     virtual bool init();  
 6     static cocos2d::CCScene* scene();
 7 
 8     virtual void menuBackCallback(CCObject* pSender);
 9 
10     LAYER_NODE_FUNC(PlaneWarInfoboard);
11 };

 

4.玩家角色类:PlaySprite——由于直接继承CCSprite类使用不方便,所以从CCNode类派生,使用组合的方式使用CCSprite类。

 1 // 玩家飞机的运动模式
 2 enum moveMode{
 3     MM_NONE = 0,
 4     MM_UP,
 5     MM_DOWN,
 6     MM_LEFT,
 7     MM_RIGHT
 8 };
 9 // 子弹类型
10 enum bulletKind{
11     BK_SINGLE=0,
12     BK_DOUBLE
13 };
14 
15 // 玩家角色类
16 class PlaySprite: public CCNode
17 {
18 public:
19     virtual void onEnter();
20 
21     PlaySprite();
22     ~PlaySprite();
23 
24     CCRect    getRect();
25     CCPoint getPlayerPt();
26     void    setPlayerPt(CCPoint pt);
27 
28     void    setMoveMode( UINT  message, WPARAM  wParam) ;
29     void    move(float dt);
30     void    die();
31     void    destroy();
32 
33 public:
34     // 属性
35     moveMode    _mode;             // 运动方式(方向按键)
36     bool        _isDragEnabled;   // 可否被鼠标拖拽(鼠标移动)
37 
38     bulletKind  _bulletKind;       // 子弹类型(吃道具可变双发)
39     int         _bombCount;        // 炸弹数量(吃道具获得)
40 
41 protected:
42     CCSprite*   _sprite;           // 代表精灵
43 };

 

 

5.敌机类:EnemySprite——由于直接继承CCSprite类使用不方便,所以从CCNode类派生,使用组合的方式使用CCSprite类。

 1 enum EnemyKind{
 2     EK_SMALL=0,
 3     EK_MIDDLE,
 4     EK_BIG
 5 };
 6 
 7 // 敌机类
 8 class EnemySprite: public CCNode
 9 {//敌机可有三种类型
10 public:
11     EnemySprite();
12     ~EnemySprite();
13 
14     virtual void onEnter();
15 
16     CCRect getRect();
17 
18     void spriteMoveFinished(CCNode* sender);
19 
20     void die();
21     void destroy();
22 
23     bool isNull();
24 public:
25     // 属性
26     int         _hp;            // 血量
27     EnemyKind   _enemyKind;     // 敌机种类
28     bool        _die;           // 已死亡
29     bool        _destroy;       // 已释放
30 
31 protected:
32     CCSprite*   _sprite;        // 代表精灵
33 };

还有谁记得儿时游戏机上的经典游戏-飞机大战,那是陪伴我们一个又一个寒暑假的伙伴。今天小编闲来写了飞机大战的游戏demo,给大家分享一下我的思路。

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

三、代码分析

 

9159.com 7

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

接《基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)》 三、代码分析 1...

1.界面初始化

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

9159.com 8

 1 bool PlaneWarGame::init()
 2 {
 3     bool bRet = false;
 4     do 
 5     {
 6         CC_BREAK_IF(! CCLayer::init());
 7 
 8         _size = CCDirector::sharedDirector()->getWinSize();
 9 
10         // 设置触摸可用
11         this->setIsTouchEnabled(true);
12         // 从窗口中取消息
13         CCDirector::sharedDirector()->getOpenGLView()->SetWin32KeyLayer( this );
14 
15         // 初始化游戏背景
16         CC_BREAK_IF(!initBackground());
17         // 菜单1(暂停/声音/炸弹)
18         CC_BREAK_IF(!initMenu1());
19         // 菜单2(继续/重新开始/返回)
20         CC_BREAK_IF(!initMenu2());
21         // 菜单3(重新开始/返回)
22         CC_BREAK_IF(!initMenu3());
23 
24         // 创建玩家飞机
25         _player = new PlaySprite;
26         _player->setPosition(CCPointZero);
27         addChild(_player);
28 
29         // 调度器:定时调用自定义的回扫函数
30         this->schedule( schedule_selector(PlaneWarGame::gameLoop));
31         this->schedule( schedule_selector(PlaneWarGame::shoot), 0.1 );
32         this->schedule( schedule_selector(PlaneWarGame::addEnemy), 0.3 );
33         this->schedule( schedule_selector(PlaneWarGame::addProp), 5 );
34 
35         // 初始化两个数组
36         _enemys = CCArray::array();
37         _enemys->retain();
38         _bullets = CCArray::array();
39         _bullets->retain();
40         
41         // 背景音乐
42         CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic(
43             "planewar/game_music.wav", true);
44 
45         bRet = true;
46     } while (0);
47 
48     return bRet;
49 }

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

 

最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下。本实...

9159.com 9

初始化的工作包括:

9159.com 10

  • 设置触摸可用
  •   设置可自定义处理消息
  •       初始化游戏背景
  •   初始化三个菜单(界面菜单/游戏暂停时的菜单/游戏结束时的菜单)
  •   初始化两个CCArray类型的数组,分别用来存储有效的敌机精灵对象和子弹对象
  •       设置需要定时调用函数的调度器
  •       设置背景音乐
  •       添加玩家角色

首先原生JS写游戏,必须将每个游戏的部分分为对象来写。

 

第一,将我的飞机和游戏引擎当做对象;

2.初始化游戏背景

第二,将子弹和敌机当做构造函数;

 1 bool PlaneWarGame::initBackground()
 2 {
 3     // 显示分数
 4     _label = CCLabelBMFont::labelWithString("0123456789","planewar/font.fnt");
 5     _label->setPosition(ccp(220,_size.height-20));
 6     _label->setColor(ccc3(0,0,0));
 7     this->addChild(_label, 1);
 8 
 9     // 显示炸弹数量
10     CCLabelBMFont* bombcount = CCLabelBMFont::labelWithString("X09","planewar/font.fnt");
11     bombcount->setAnchorPoint(ccp(0,0));
12     bombcount->setPosition(ccp(73,10));
13     bombcount->setColor(ccc3(0,0,0));
14     addChild(bombcount, 10,111);
15 
16     // 添加背景
17     CCSprite* bg1 = CCSprite::spriteWithFile("planewar/bg1.png");
18     if (!bg1)return false;
19     bg1->setAnchorPoint(ccp(0,1));
20     bg1->setPosition( ccp(0, _size.height) );
21     this->addChild(bg1, 0, 11);
22 
23     bg1->runAction(
24         CCSequence::actions(
25         CCMoveBy::actionWithDuration(10,ccp(0,-720)),
26         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg1roll)),NULL));
27 
28     CCSprite* bg2 = CCSprite::spriteWithFile("planewar/bg2.png");
29     if (!bg1)return false;
30     bg2->setAnchorPoint(ccp(0,1));
31     bg2->setPosition( ccp(0, _size.height*2) );
32     this->addChild(bg2, 0, 12);
33 
34     bg2->runAction(
35         CCSequence::actions(
36         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
37         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg2roll)),NULL));
38     return true;
39 }
40 
41 void PlaneWarGame::bg1roll(){
42     //运动出屏幕重设位置,运动
43     CCSprite * bg = (CCSprite *)getChildByTag(11);
44     bg->setPosition(ccp(0,1440));
45     CCAction* seq = CCSequence::actions(
46         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
47         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg1roll)),NULL);
48     bg->runAction(seq);
49 }
50 
51 void PlaneWarGame::bg2roll(){
52     //运动出屏幕重设位置,运动
53     CCSprite * bg = (CCSprite *)getChildByTag(12);
54     bg->setPosition(ccp(0,1440));
55     CCAction* seq = CCSequence::actions(
56         CCMoveBy::actionWithDuration(20,ccp(0,-1440)),
57         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaneWarGame::bg2roll)),NULL);
58     bg->runAction(seq);
59 }

第三,游戏中小的功能全部写进游戏引擎当中去,比如,敌机遇到子弹爆炸的效果,敌机撞到我的飞机时我的飞机爆炸的效果。

 初始化游戏背景时,需要注意的是:要做出飞机向上走的视觉效果,就要把背景向下滚动,这里使用两个背景bg1和bg2,大小分别为屏幕大小。初始bg1在屏幕内,bg2在屏幕上方,两个同事向下运动;当bg1刚刚运动到屏幕外,bg2刚好盖住屏幕,bg1挪到屏幕上方向下运动...循环操作,就能做出循环滚动的背景效果了。

接下来,就是将我的分数传给服务器,当我的飞机被撞毁,页面显示成绩并跳转至一个成绩排行榜的页面。在这个页面里,我将获取服务器传过来的数据并显示。

 

9159.com 11

3.子弹的处理

在这个游戏中首先创建html文件中加点击事件,即选择困难程度后就决定了子弹的发射频率。点击后移除ul节点,并进入游戏加载界面,即进入游戏引擎。游戏引擎以对象的形式创建,分为属性和方法。游戏引擎主要方法有开始游戏、加载游戏、监听键盘(即通过键盘控制我的飞机移动)、创建敌机、碰撞检测。

 1 // 确定子弹类型
 2 void PlaneWarGame::shoot(float dt)
 3 {
 4     if (_isOver)return;
 5     if(_player==NULL) return;
 6 
 7     if(_player->_bulletKind == BK_SINGLE)
 8     {
 9         CCSprite *bullet = CCSprite::spriteWithFile(
10             "planewar/plane.png", CCRectMake(112,2,9,17));
11         addBullet(bullet,_player->getPlayerPt());
12     }else if (_player->_bulletKind == BK_DOUBLE)
13     {
14         CCSprite *bullet = CCSprite::spriteWithFile(
15             "planewar/plane.png", CCRectMake(66,238,8,15));
16         addBullet(bullet,ccp(_player->getPlayerPt().x-20,_player->getPlayerPt().y));
17         CCSprite *bullet1 = CCSprite::spriteWithFile(
18             "planewar/plane.png", CCRectMake(66,238,8,15));
19         addBullet(bullet1,ccp(_player->getPlayerPt().x 20,_player->getPlayerPt().y));
20     }
21 }
22 // 添加子弹
23 void PlaneWarGame::addBullet(CCSprite* bullet, CCPoint pt)
24 {    
25     bullet->setPosition(pt);
26     this->addChild(bullet);
27 
28     bullet->runAction( CCSequence::actions(
29         CCMoveTo::actionWithDuration(0.5, ccp(pt.x,_size.height bullet->getContentSize().height/2)),
30         CCCallFuncN::actionWithTarget(this,callfuncN_selector(PlaneWarGame::spriteMoveFinished)), 
31         NULL) );
32 
33     bullet->setTag(1);
34     _bullets->addObject(bullet);
35 }
36 // 回收
37 void PlaneWarGame::spriteMoveFinished(CCNode* sender)
38 {
39     CCSprite *sprite = (CCSprite *)sender;
40     this->removeChild(sprite, true);
41     if (sprite->getTag()==1)//子弹
42         _bullets->removeObject(sprite);
43 }

加载游戏的方法是个回调函数,即当游戏加载完毕,回调再进行其他处理,比如创建我的飞机、监听键盘、创建敌机、碰撞检测。

 吃道具可改变子弹类型。子弹的回收方式:从飞机坐标处出发,运动到屏幕外被回收。道具的处理类似。

9159.com 12

 

9159.com 13

9159.com,4.设置触摸/鼠标点击控制玩家角色的移动

9159.com 14

 1 bool PlaneWarGame::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
 2 {
 3     if(_player==NULL) return false;
 4 
 5     CCPoint pt = CCDirector::sharedDirector()->convertToGL(
 6         pTouch->locationInView(pTouch->view()));
 7 
 8     CCRect rt = _player->getRect();
 9     if (CCRect::CCRectContainsPoint(rt,pt))
10         _player->_isDragEnabled = true;
11     return true;
12 }
13 
14 void PlaneWarGame::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
15 {
16     if(_player==NULL) return;
17 
18     CCSize size = CCDirector::sharedDirector()->getWinSize();
19     CCPoint pt = CCDirector::sharedDirector()->convertToGL(
20         pTouch->locationInView(pTouch->view()));
21     
22     CCRect rt = CCRect(0,0,size.width,size.height);
23 
24     if (_player->_isDragEnabled && CCRect::CCRectContainsPoint(rt,pt))
25         _player->setPlayerPt(pt);
26 }
27 
28 void PlaneWarGame::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
29 {
30     _player->_isDragEnabled = false;
31 }

9159.com 15

这里重写3个虚函数。移动角色的方式:触摸/鼠标按下时,如果点击位置在角色上,将角色可被拖拽状态置为true;触摸/鼠标移动时,根据角色的可被拖拽状态和屏幕范围确定是否移动;触摸/鼠标弹起时,将角色的可被拖拽状态恢复为false。

9159.com 16

 

9159.com 17

5.碰撞检测

9159.com 18

  1 void PlaneWarGame::updateGame(float dt)
  2 {
  3     CCArray *bulletsToDelete = CCArray::array();
  4     CCObject* it = NULL;
  5     CCObject* jt = NULL;
  6     
  7     if(_player==NULL) return;
  8 
  9     CCRect playerRect = _player->getRect();
 10     // 己方飞机和敌方飞机的碰撞
 11     CCARRAY_FOREACH(_enemys, jt)
 12     {
 13         EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 14         if (!enemy->isNull() && CCRect::CCRectIntersectsRect(playerRect, enemy->getRect()))
 15         {
 16             _player->die();
 17             gameover(false);
 18             return;
 19         }
 20     }
 21 
 22     //////////////////////////////////////////////////////////////////////////
 23         // 道具和角色的碰撞检测
 24     CCSprite* prop = (CCSprite*)getChildByTag(8);//子弹
 25     if (NULL != prop)
 26     {
 27         CCRect propRect = CCRectMake(
 28             prop->getPosition().x - (prop->getContentSize().width/2),
 29             prop->getPosition().y - (prop->getContentSize().height/2),
 30             prop->getContentSize().width,
 31             prop->getContentSize().height);
 32         if (CCRect::CCRectIntersectsRect(playerRect, propRect))
 33         {
 34             _player->_bulletKind = BK_DOUBLE;
 35             removeChild(prop,true);
 36             CocosDenshion::SimpleAudioEngine::sharedEngine()->
 37                 playEffect("planewar/get_double_laser.wav",false);
 38         }
 39     }
 40     CCSprite* prop1 = (CCSprite*)getChildByTag(9);//炸弹
 41     if (NULL != prop1)
 42     {
 43         CCRect prop1Rect = CCRectMake(
 44             prop1->getPosition().x - (prop1->getContentSize().width/2),
 45             prop1->getPosition().y - (prop1->getContentSize().height/2),
 46             prop1->getContentSize().width,
 47             prop1->getContentSize().height);
 48         if (CCRect::CCRectIntersectsRect(playerRect, prop1Rect))
 49         {
 50             _player->_bombCount  ;
 51             removeChild(prop1,true);
 52             CocosDenshion::SimpleAudioEngine::sharedEngine()->
 53                 playEffect("planewar/get_bomb.wav",false);
 54         }
 55     }
 56 
 57     //////////////////////////////////////////////////////////////////////////
 58         // 子弹和敌机的碰撞检测
 59     CCARRAY_FOREACH(_bullets, it)
 60     for (int i=0; i<_bullets->count(); i  )
 61     {
 62         CCSprite *bullet = dynamic_cast<CCSprite*>(_bullets->objectAtIndex(i));
 63         CCRect bulletRect = CCRectMake(
 64             bullet->getPosition().x - (bullet->getContentSize().width/2),
 65             bullet->getPosition().y - (bullet->getContentSize().height/2),
 66             bullet->getContentSize().width,
 67             bullet->getContentSize().height);
 68 
 69         CCArray* enemysToDelete =CCArray::array();
 70 
 71         CCARRAY_FOREACH(_enemys, jt)
 72         {
 73             EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 74             if (!enemy->_die && CCRect::CCRectIntersectsRect(bulletRect, enemy->getRect()))
 75             {
 76                 if (enemy->_hp>0)
 77                 {
 78                     enemy->_hp--;
 79                     //bulletsToDelete->addObject(bullet);
 80                     _bullets->removeObject(bullet);
 81                     removeChild(bullet,true);
 82                 }
 83                 else if (enemy->_hp<=0)
 84                 {
 85                     //bulletsToDelete->addObject(bullet);
 86                     _bullets->removeObject(bullet);
 87                     removeChild(bullet,true);
 88                     enemysToDelete->addObject(enemy);
 89                 }
 90             }
 91         }
 92 
 93         CCARRAY_FOREACH(enemysToDelete, jt)
 94         {
 95             EnemySprite *enemy = dynamic_cast<EnemySprite*>(jt);
 96             enemy->_die = true;
 97             enemy->die();
 98             _bulletsDestroyed  ;
 99         }
100 
101         enemysToDelete->release();
102     }
103 
104     // 释放已死亡的子弹
105     CCARRAY_FOREACH(bulletsToDelete, it)
106     {
107         CCSprite* projectile = dynamic_cast<CCSprite*>(it);
108         _bullets->removeObject(projectile);
109         this->removeChild(projectile, true);
110     }
111     bulletsToDelete->release();
112 }          

当游戏加载完成后就需要创建我的飞机了。首先需要初始化,即创建飞机节点并实现移动,飞机移动有拖拽和键盘事件两种实现方式,需要注意的是移动需要控制左右边界。另外我的飞机创建好之后,就需要发射子弹了。发射子弹通过定时器实现,同时需要创建子弹这一构造函数。

 碰撞检测使用最简单的矩形检测。

9159.com 19

 

9159.com 20

6.玩家角色的添加和操作

9159.com 21

  1 void PlaySprite::onEnter()
  2 {
  3     CCNode::onEnter();
  4 
  5     CCSize size = CCDirector::sharedDirector()->getWinSize();
  6     _sprite = CCSprite::spriteWithFile("planewar/hero1.png");
  7     _sprite->setContentSize(CCSize(62,68));
  8     _sprite->setPosition( ccp(size.width/2,_sprite->getContentSize().height/2) );
  9     addChild(_sprite,10);
 10 
 11     CCAnimation * animation = CCAnimation::animation();
 12     animation->addFrameWithFileName("planewar/hero1.png");
 13     animation->addFrameWithFileName("planewar/hero2.png");
 14     CCAction* action = CCRepeatForever::actionWithAction(
 15         CCAnimate::actionWithDuration(0.1f, animation, false));
 16     action->setTag(11);
 17     _sprite->runAction(action);
 18 
 19     // 调度器
 20     schedule( schedule_selector(PlaySprite::move), 0.002 );
 21 }
 22 
 23 CCRect PlaySprite::getRect()
 24 {
 25     if (_sprite!=NULL)
 26         return CCRect(
 27         _sprite->getPosition().x - (_sprite->getContentSize().width/2),
 28         _sprite->getPosition().y - (_sprite->getContentSize().height/2),
 29         _sprite->getContentSize().width,
 30         _sprite->getContentSize().height);
 31 }    
 32 
 33 CCPoint PlaySprite::getPlayerPt()
 34 {
 35     if (_sprite!=NULL)
 36         return _sprite->getPosition();
 37 }
 38 
 39 void PlaySprite::setPlayerPt(CCPoint pt)
 40 {
 41     if (_sprite!=NULL)
 42         return _sprite->setPosition(pt);
 43 }
 44 
 45 void  PlaySprite::setMoveMode( UINT  message, WPARAM  wParam) 
 46 {
 47     if (message == WM_KEYDOWN)
 48     {// 控制飞机移动
 49         if (wParam == VK_UP)
 50             _mode = MM_UP;
 51         else if (wParam == VK_DOWN)
 52             _mode = MM_DOWN;
 53         else if (wParam == VK_LEFT)
 54             _mode = MM_LEFT;
 55         else if (wParam == VK_RIGHT)
 56             _mode = MM_RIGHT;
 57     }else if (message == WM_KEYUP)
 58     {
 59         if (wParam == VK_UP || wParam == VK_DOWN ||wParam == VK_LEFT||wParam == VK_RIGHT)
 60             _mode = MM_NONE;
 61     }
 62 }
 63 
 64 void PlaySprite::move(float dt)
 65 {
 66     CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 67 
 68     switch(_mode)
 69     {
 70     case MM_NONE:
 71         break;
 72     case MM_UP:
 73         if (getPlayerPt().y<winSize.height)
 74             setPlayerPt(ccp(getPlayerPt().x,getPlayerPt().y 1));
 75         break;
 76     case MM_DOWN:
 77         if (getPlayerPt().y>0)
 78             setPlayerPt(ccp(getPlayerPt().x,getPlayerPt().y-1));
 79         break;
 80     case MM_LEFT:
 81         if (getPlayerPt().x>0)
 82             setPlayerPt(ccp(getPlayerPt().x-1,getPlayerPt().y));
 83         break;
 84     case  MM_RIGHT:
 85         if (getPlayerPt().x<winSize.width)
 86             setPlayerPt(ccp(getPlayerPt().x 1,getPlayerPt().y));
 87         break;
 88     }
 89 }
 90 
 91 void PlaySprite::die()
 92 {
 93     if (_sprite==NULL)return;
 94 
 95     _sprite->stopActionByTag(11);
 96     CCAnimation * animation = CCAnimation::animation();
 97     animation->addFrameWithFileName("planewar/hero_blowup_n1.png");
 98     animation->addFrameWithFileName("planewar/hero_blowup_n2.png");
 99     animation->addFrameWithFileName("planewar/hero_blowup_n3.png");
100     animation->addFrameWithFileName("planewar/hero_blowup_n4.png");
101     _sprite->runAction(CCSequence::actions(
102         CCAnimate::actionWithDuration(0.1f, animation, false),
103         CCCallFunc::actionWithTarget(this, callfunc_selector(PlaySprite::destroy)),NULL));
104 }
105 
106 void PlaySprite::destroy()
107 {
108     if (_sprite==NULL)return;
109     
110     removeChild(_sprite,true);
111     _sprite = NULL;
112 }

子弹是功能是撞击敌机,即让它运动起来。在这之前也需要将子弹初始化,将它定位到我的飞机的正中靠上位置。

  • 玩家角色类是派生自CCNode类,用组合的方式包含一个CCSprite类的成员对象,在玩家角色类内部封装对精灵的操作。
  • 重写onEnter函数初始化_sprite成员,设置位置、大小、图片和帧动画等。
  • 玩家的方向键控制移动和鼠标拖拽移动方式类似,在操作时设置移动状态,在schedule定时调用的函数move中根据移动状态来移动玩家角色。
  • 关于碰撞之后的动画和销毁,参照上面的die和destroy函数,对象被碰撞时调用die函数运行爆炸的帧动画,动画结束后自动调用destroy函数销毁对象。
  • 敌机对象的操作和玩家角色类似。

9159.com 22

 

9159.com 23

四、完成效果图

子弹创建完后,需要创建敌机。敌机也需要当做构造函数来创建,敌机所具备的属性是它的速度和血量。

经过不到一周的时间,从什么都没有,到游戏正常运行、功能完整,体会了cocos2dx的调用机制。

不同大小的敌机速度和血量都是不同的,我这里的敌机类型有三种,分别为大中小型敌机,我们给每种敌机添加不同的类型、血量、速度,并将这些属性放在原型中。首先初始化时需要判断敌机类型,并赋给它属性。同样再用定时器让敌机也运动起来。

下面是运行效果图:

9159.com 24

9159.com 259159.com 26

9159.com 27

9159.com 289159.com 29

9159.com 30

9159.com 31

9159.com 32

 

9159.com 33

如果实现中有什么问题,欢迎大家在评论中指教!

接下来,我们需要判断子弹碰撞敌机时的动作。在游戏引擎中添加一个判断碰撞的方法,并给个定时器,每隔30毫秒判断一次。要判断碰撞,即需要判断屏幕上的所有敌机节点和所有子弹节点是否有重叠,首先需要获取屏幕上所有的子弹对象和敌机对象,我们就用数组分别保存子弹对象和敌机对象,在子弹和敌机这两个构造函数中,每创建一个对象节点,就需要将该对象用push的方式存入数组中。另外,当子弹或敌机运动超出边界,将该超出边界的对象从数组中用splice的方式移除。除此之外,还需要判断是否发生重叠,重叠可以用以下的方式判断,将其封装成一个函数isCrash。

 

话说回来,用两个for循环分别遍历子弹数组和敌机数组,判断一下当发生碰撞时,首先子弹爆炸,在子弹这一构造函数中需加一个爆炸的动画boom。爆炸完后将其移除,然后敌机掉血,并进入敌机构造函数中的hurt方法判断敌机的血量是否减为0。如果血量是0,则键入敌机爆炸的函数(boom)中,给一个定时器实现爆炸的动画。

最后,还需要判断敌机是否碰撞了我的飞机,即在for循环遍历敌机数组时,加上判断敌机与我的飞机碰撞的语句。如果发生碰撞,首先在我的飞机中加个爆炸的动画效果的函数,在判断语句中调用该函数实现爆炸效果,当动画完成后,用callback回调回去。在回调函数中,再用prompt提示游戏结束,并显示成绩(成绩的计算我是根据打了多少敌机来算的,比如大型敌机40分,中型敌机20分,小型敌机10分,最后将总分相加),还需要用ajax将成绩和姓名等数据传给(post)服务器(这里我将ajax直接封装成一个函数),传输数据成功后,还要用location.href跳转页面至“飞机大战成绩排行榜”。

9159.com 34

最后,完成页面跳转,在另外一个页面中再用ajax获取(get)服务器传过来的数据。并创建ul,li节点使其信息显示在页面上。

这样,一个完整的飞机大战游戏就做完了!

本文由9159.com发布于编程,转载请注明出处:初始化的工作包括,2.游戏界面类

关键词: 9159.com