三消类游戏《万圣大作战》04:添加时间与分数

1. 添加时间

一般消除类游戏,要么关卡,要么限制时间,但是关卡的设计很麻烦,个体创作,没有那么多精力,

所以只能通过限制时间来使游戏有些可玩性,但这种可玩性极低啊,反复挑战同样的东西,很容易疲劳的。

在程序中加时间,如何操作呢?

当然,先要有个时间的全局变量,在初始化游戏界面的时候,显示在屏幕上:

1
2
3
4
5
6
7
// 加载ttf字体  
     TTFConfig config( "fonts/haibaoti.ttf" ,30);  
     // 游戏时间的显示  
     auto labelTime = Label::createWithTTF(config,StringUtils::format( "Time: %d " ,m_time));  
     labelTime -> setPosition(Vec2( labelTime->getContentSize().width , GAME_SCREEN_HEIGHT - labelTime->getContentSize().height ));  
     labelTime -> setTag(11);  
     this  ->addChild(labelTime);

然后还要有个函数,让它每秒都会减少

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void  GameScene::myClock(  float  dt )  
{  
     // 时间变化  
     --m_time;  
     // 如果时间归0,那么执行游戏结束动画,并跳到游戏结束界面  
     if ( m_time == 0 )  
     {  
         Label *labelTime = (Label *) this  -> getChildByTag(11);  
         labelTime->setScale(0);  
   
         // 游戏结束 动画  
         auto gmov = Sprite::create( "pic_gameover.png" );  
         gmov->setPosition(Point(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT*1.5));  
         this ->addChild(gmov);  
   
         auto action = MoveTo::create(3.0f, Point(GAME_SCREEN_WIDTH/2, GAME_SCREEN_HEIGHT/2));    
   
         gmov -> runAction( action );  
   
         // 跳转到游戏结束界面  
         return ;  
     }  
     // 如果还有时间,那么时间减少  
     if ( m_time > 0 ) {  
         Label *labelTime = (Label *) this  -> getChildByTag(11);  
         labelTime -> setString( StringUtils::format( "Time: %d " ,m_time));  
     }  
}

但是,别忘了最重要的一步,要将这个倒计时函数加入到计划任务中,就像之前我们用的检查精灵。

之前检查精灵用的是 scheduleUpdate,每一帧都要执行,

而这次,我们用 schedule 就可以,自己指定函数,并且设定间隔时间。

就放在 scheduleUpdate 下面就可以啦。

1
schedule(schedule_selector(GameScene::myClock),1.0f );

然后运行一下,就可以看到倒计时的实现啦。

然后,我们再建立 游戏结束界面,界面里放返回游戏,返回主界面和退出三个按钮,就可以啦。

代码就不贴出,具体的可以看文章末尾给出的源码。


2. 添加分数

光有时间倒计时可不行,要有分数才有意思!

和时间一样,也要初始化界面中将分数在游戏界面显示出来

1
2
3
4
5
// 分数显示  
     auto labelScore = Label::createWithTTF(config,StringUtils::format( "Score: %d " ,m_score) );  
     labelScore -> setPosition(Vec2( GAME_SCREEN_WIDTH/2 , GAME_SCREEN_HEIGHT - labelScore->getContentSize().height*2.6 ));  
     labelScore -> setTag(10);  
     this ->addChild(labelScore);

但是 分数 就不需要像时间那样,单独弄一个函数,分数是时时刷新的,所以跟随每帧刷新即可,就是在update函数内加上分数的显示

1
2
3
4
5
// GameScene.cpp  update()函数  
   
// 分数变化  
     Label *labelScore = (Label *) this  -> getChildByTag(10);  
     labelScore -> setString( StringUtils::format( "Score: %d " ,m_score));

然后在相应位置,进行分数的加,

我是在 精灵下落处,每消除一个精灵加30分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// GameScene.cpp  修改后的 fillSprite  
   
// 填补空缺位置  
void  GameScene::fillSprite()    {  
   
     // 下落精灵总个数(方便后面分数的计算)  
     int  sum = 0;  
      // 重置移动方向标志  
     isAction =  true ;  
   
     int  *colEmptyInfo = ( int  *) malloc ( sizeof ( int ) * COLS);  
     memset (( void  *)colEmptyInfo, 0,  sizeof ( int ) * COLS);  
       
     // 将存在的精灵降落下来  
     SpriteShape *spr = NULL;  
     for  ( int  c = 0; c < COLS; c++) {  
         int  removedSpriteOfCol = 0;  
         // 自底向上  
         for  ( int  r = 0; r < ROWS; r++ ) {  
             spr = map[r][c];  
             if  ( spr == NULL ) {  
                 ++removedSpriteOfCol;  
             else  {  
                 if  ( removedSpriteOfCol > 0) {  
                     int  newRow = r - removedSpriteOfCol;  
                     map[newRow][c] = spr;  
                     map[r][c] = NULL;  
                     
                     Point startPosition = spr->getPosition();  
                     Point endPosition = positionOfItem(newRow, c);  
                     float  speed = (startPosition.y - endPosition.y) / GAME_SCREEN_HEIGHT*3;  
                     spr->stopAllActions();  
                     spr->runAction(CCMoveTo::create(speed, endPosition));  
                       
                     spr->setRow(newRow);  
                 }  
             }  
         }  
           
         // 记录相应列数移除的数量  
         colEmptyInfo[c] = removedSpriteOfCol;  
         sum+=removedSpriteOfCol;  
     }  
       
     // 新建新的精灵,并降落  
     for  ( int  c = 0; c < COLS; ++c ) {  
         for  ( int  r = ROWS - colEmptyInfo[c]; r < ROWS ; ++r ) {  
             createSprite(r,c);  
         }  
     }  
       
     m_score += sum*30;  
     free (colEmptyInfo);  
}

接下里,就是在游戏结束界面,将自己的分数传递过去。

如果看源码,会发现, 在时间到0时,我用的 scheduleOnce ( 有个动画,要delay一下)

然后跳转到一个游戏结束函数,就是在这个函数,进行了分数的传递。

当然,相应的 GameOverScene中,也要设置相应的函数来接受分数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// GameScene.cpp  
   
// 游戏结束函数  
void  GameScene::gameOver( float  dt)  
{  
     auto scene = Scene::create();  
     auto layer = GameOver::create();  
     // 传递当前游戏获得的分数  
     layer -> setScore( m_score );  
     scene -> addChild( layer );  
   
     CCTransitionScene* reScene= CCTransitionFadeUp::create(1.0f, scene);  
     CCDirector::sharedDirector()->replaceScene(reScene);  
}
1
2
3
4
5
6
7
// GameOverScene.cpp   
   
void  GameOver::setScore(  int  sc )  
{  
     auto labelScore = (Label *) this  -> getChildByTag(13);  
     labelScore -> setString( StringUtils::format( " %d " ,sc));  
}

Ok啦,现在可以运行爽爽啦

现在做的东东已经有基本雏形了,

剩下的就属于额外的东西,往上添加就行了。

后面的文章将会对本游戏进行修饰,比如:

—— 消除的特效

—— 消除4个,产生消除一列 或者 一行的东东

—— 音乐、音效的添加

—— 最高分的记录

等等~


本章资源和代码:点击下载


感谢本文笔者LT大树_的分享,
Cocos引擎中文官网欢迎更多的开发者分享开发经验,来稿请发送至[email protected]

来源网址:http://blog.csdn.net/lttree/article/details/43196817

你可能感兴趣的:(三消类游戏,Cocos2d-x)