• Cocos2d-x 3.4 之 消灭星星 > 第三篇(终) <


    ***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************



    满满的泪啊。

    从5月22日写的第一篇,于6月6日结束。

    中间各种课程、上机、大作业穿插。焦头烂额的。

    最后最终做出来几乎相同的样子了。。

    PS:写博客这几天。宿舍一直停电状态。。

    。真是醉了。。




    本篇实现的功能:

    > 粒子特效

    > 音乐音效

    > 漂浮文字

    > combo特效 及 每关结束后星星的消除(小于等于10个的一个个消除。剩余的一齐消除)

    > 最高分存储、场景的简单存储

    > 消除星星的Hint




    一、粒子特效

    粒子特效,主要是星星消除后的爆炸效果。

                         

    这里主要用了两个函数:

    ▪ 产生爆炸粒子特效

    ▪ 获取点击星星的颜色

    void starSpecialEffect(Star* sta,Point position,Node* node,int staNum)
    {
    	// 创建爆炸粒子效果,粒子数量为 staNum 个
    	ParticleExplosion* effect = ParticleExplosion::createWithTotalParticles(staNum);
    	// 设置此粒子特效的纹理图片
        effect->setTexture(Director::getInstance()->getTextureCache()->addImage("star.png"));
    	// 设置開始时候的粒子颜色
    	effect->setStartColor(getColor4F(sta->getImgIndex()));
    	effect->setStartColorVar(Color4F(0,0,0,1));
        effect->setEndColor(getColor4F(sta->getImgIndex()));
        effect->setEndColorVar(Color4F(0,0,0,1));
    	// 设置開始时的粒子大小
        effect->setStartSize(20.0f);
        effect->setGravity(Point(0,-300));
    	// 设置粒子生命周期
        effect->setLife(2.0f);
    	// 设置粒子速度
        effect->setSpeed(200);
        effect->setSpeedVar(10);
    	// 设置粒子位置
        effect->setPosition(position);
        node->addChild(effect,2);
    }
     
    Color4F getColor4F(int imgIndex)
    {
    	switch(imgIndex){
    	case 0:
    		//red
    		return Color4F::RED;
        case 1:
    		//blue
    		return Color4F::BLUE;
        case 2:
    		//green
    		return Color4F::GREEN;
        case 3:
    		//purple
    		return Color4F(128.0f,0,128.0f,1.0f);
        case 4:
    		//yellow
    		return Color4F::YELLOW;
        }
        return Color4F(1,1,1,0);
    }

    详细粒子特效的应用,等有时间做一个单独的博文发出来。。




    二、音乐音效

    这里用了UserDefault进行存储,音乐音效的开关,

    音乐和音效同一开关。没有分开。

    主要就是 Android对于 ogg 格式的音乐支持是最好的。

    可是在Windows平台不好測试。由于Windows自带的WMP(Windows Media Player)不支持这个格式的音乐播放。即使没有路,我们自己创造路来走,有大牛就开发了一款解码软件—— K-Lite Codec Pack,

    我的WMP是能够播放ogg了,cocos2d-x 还是须要修改一下,临时没改好,

    于是。。。阉割了。。

    我是在Windows用 mp3格式 測试,然后在Android用ogg格式的,效果挺好

    之前的三消游戏中。非常多人就说音乐播放不出来。没有效果,

    可是我自己试的是没问题的。偶尔还真有一两个音效不好用。我认为还是格式问题,

    各个音效部分,我就不多说了。在对应位置插入即可,

    背景音乐。须要 重载虚函数 

    virtual void onEnterTransitionDidFinish();
    virtual void cleanup();

    onEnterTransitionDidFinish是在场景载入完毕后进行,

    不同于onEnter。onEnter是场景開始载入就进行,

    cleanup 函数。是在场景被消除时的动作,

    我们的背景音乐就是要在这两个函数中增加:

    void WelcomeScene::onEnterTransitionDidFinish()
    {
    	Layer::onEnterTransitionDidFinish();  
    	if ( userDefault->getBoolForKey("MusicKey") ) {                      
            SimpleAudioEngine::getInstance()->playBackgroundMusic("Music/music.ogg", true);  
        } 
    }
    void WelcomeScene::cleanup()
    {
    	Layer::cleanup();
    	SimpleAudioEngine::getInstance()->stopBackgroundMusic();
    }

    对于音乐音效说的也就这么多了




    三、漂浮文字

    漂浮文字效果,单独开了一个类,

    基本的创建函数:

    FloatWord* FloatWord::create( const std::string& word,const int fontSize,Vec2 begin )
    {
    	FloatWord* fw = new FloatWord();
    	if( !fw->init(word,fontSize,begin) )	{
    		return NULL;
    	}
    	
    	fw->autorelease();
    	return fw;
    }

    几个基本的工具函数:

    void FloatWord::floatInOut(const float speed,const float delayTime,std::function<void()> callback){
    	
    	MoveTo* moveIn = MoveTo::create(speed,Vec2(GAME_SCREEN_WIDTH/2,fw_begin.y));
    	MoveTo* moveOut = MoveTo::create(speed,Vec2(-fw_label->getContentSize().width,fw_begin.y));
    
    	CallFunc* call = CallFunc::create(callback);
    
    	Sequence* action = Sequence::create(moveIn,DelayTime::create(delayTime),moveOut,call,NULL);
    	fw_label->runAction(action);
    }
    
    void FloatWord::floatIn(const float speed){
    	
    	MoveTo* moveIn = MoveTo::create(speed,Vec2(GAME_SCREEN_WIDTH/2,fw_begin.y));
    
    	Sequence* action = Sequence::create(moveIn,NULL);
    	fw_label->runAction(action);
    }
    
    void FloatWord::floatOut(const float speed,const float delayTime){
    	
    	MoveTo* moveOut = MoveTo::create(speed,Vec2(-fw_label->getContentSize().width,fw_begin.y));
    
    	Sequence* action = Sequence::create(DelayTime::create(delayTime),moveOut,NULL);
    	fw_label->runAction(action);
    }

    就是将动作 Sequence起来了,按顺序播放即可了

                                    




    四、combo特效 及  每关结束后星星的消除

    首先是 combo 特效,做一个函数,然后每次消除的时候,推断消除的个数是否满足combo特效触发条件就可以。

    void comboEffect(int num,Node* node){
    	
    	if( num < 5 )
    		return;
    
    	Sprite* comboSprite;
    	if( num >= 10 ){
    		comboSprite = Sprite::create("combo_3.png");
    	}else if( num >= 7 ){
    		comboSprite = Sprite::create("combo_2.png");
    	}else{
    		comboSprite = Sprite::create("combo_1.png");
    	}
    
    	comboSprite->setPosition(Vec2(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT/2));
    	node->addChild(comboSprite,4);
    
    	Blink* blink = Blink::create(1.0f,5);
    	CallFunc* remove = CallFunc::create([=](){comboSprite->removeFromParentAndCleanup(true);});
    	Sequence* action = Sequence::create(blink,remove,nullptr);
    	comboSprite->runAction(action);
    }

    最后星星的消除。这里我的处理比較麻烦:

    1.推断此关卡结束(没有能够消除的星星),然后将 全局的 关卡结束 变量 设置为 true,获得剩余星星的数量,假设剩余星星数量大于10 则 设置为10(由于一个一个消除的效果,最多10个)

    2.在 update函数中(每一帧都会调用的函数),会推断关卡是否结束,若结束。会调用 消除函数,10个以内,每消除一个都会返回,不会继续消除。并且记录消除时间,消除一次后一定时间间隔再进行下一次消除

    3.消除完10个(或者小于10个)以后,不会再返回,会一次性将剩余星星消除完成,将 关卡结束 变量设置为false。

    这里的: 关卡结束一系列操作:

    if( isFinish() )	{
        isLevelFinish = true;
        int temp = totalStarNum();
    
        if( temp <= 10 )	{
            needDelOneByOne = temp;
        }
    }
    else
    {
        needDelOneByOne = 10;
    }

    update函数:

    void GameScene::update( float dt )
    {
    	// 分数变化
    	Label *labelScore = (Label *)this -> getChildByTag(6);
    	labelScore -> setString( StringUtils::format("Score: %d ",_score));
    
    	// 假设当前关卡结束  星星一个个消除的实现
    	if( isLevelFinish )	{
    
    		deleteTime += dt;
    		if( deleteTime > DELSTAR_ONEBYONE_TIME )	{
    			popFinishStar(needDelOneByOne);
    			needDelOneByOne--;
    			deleteTime = 0;
    		}
    	}
    }

    消除结束星星函数:

    void GameScene::popFinishStar( int n )
    {
    	int r,c;
    	Star* sta;
    
    	for( r = ROWS-1 ; r >= 0 ; r-- )	{
    		for( c = 0 ; c < COLS ; c++ )	{
    			sta = map[r][c];
    			if( sta )	{
    					starSpecialEffect(sta,sta->getPosition(),this,5);
    					map[r][c]=NULL;
    					sta->removeFromParentAndCleanup(true);
    					return;
    				}
    				else
    				{
    					starSpecialEffect(sta,sta->getPosition(),this,totalStarNum()*4);
    					map[r][c]=NULL;
    					sta->removeFromParentAndCleanup(true);
    				}
    			}
    		}
    	}
    
    
    	isLevelFinish = false;
    	scheduleOnce(schedule_selector(GameScene::levelOver),2.0f);
    }

                                                                            





    五、最高分的存储。场景的简单存储

    最高分的存储,还是用了userdefault,

    就是在游戏结束的时候。推断一下是否破纪录:

    if( userDefault->getIntegerForKey("HightScore") < _score )
    		userDefault->setIntegerForKey("HightScore",_score);

    场景的存储。用了 push 和 pop,

    在主界面定义一个变量,来推断能否够继续,

    刚进入主界面时,场景栈是没有场景存储的,此时点击 继续游戏 就会退出游戏,

    所以要在场景栈没有场景时,不同意点击 继续游戏 button。

    这个变量,在从游戏界面跳转到主界面(通过返回函数跳转)时。会设置为true。就是能够点击。




    六、消除星星Hint

    当消除几个星星,我们都要有提示。加了几分。

    游戏结束,假设剩余星星数量小于10个,都要有额外分数的添加。

    星星消除函数是这种:

    一个等差数列,第一个星星 5分,第二个15分,第三个25分(首项为5,公差为10的等差数列)

    所以,假设消除n个星星,就是用到等差数列的求和公式了:

    n*5+n*(n-1)*10/2

    剩余星星数量。所获得的额外分数则建立了一个数组,放在GameDefine头文件,

    // 剩余星星所奖励的分数
    static const int rewardScore[11] = {
    	2000,
    	1980,
    	1920,
    	1820,
    	1680,
    	1500,
    	1280,
    	1020,
    	720,
    	380,
    	0
    };


                                      





    到这里,消灭星星系列完美结束啦~~~

    撒花。。。

    接下来把历史遗留下的问题——别踩白块 剩下部分搞定,

    然后要做第一款自己想的游戏了,

    敬请期待呀~~~





    本文源代码:    >  这里  <

    终于APK:    > here <


    ***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

  • 相关阅读:
    JAVA_OA管理系统(三):Spring参数注入
    JAVA_OA管理系统(二):SpringMVC笔记基础篇01注入方法
    java_OA管理系统(一):Servlet总结案例仿网络聊天室
    探秘Java中String、StringBuilder以及StringBuffer
    详解Java中的注解
    详解Java中的注解
    JSP中文乱码问题(get,post篇)
    JSP中文乱码问题(get,post篇)
    98%的人没解出的德国面试逻辑题(离散数学篇)!?
    哈希函数
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6978436.html
Copyright © 2020-2023  润新知