zoukankan      html  css  js  c++  java
  • cocos2dx游戏开发——别踩白块学习笔记(二)——经典模式的实现

    一、创建GameScene以及GameLayer

    就是简单创建一个Scene而已,在此就不多说啦~,可以参照我的打飞机的学习笔记(2)。

    二、添加一个开始栏

    很简单,就是调用Block中的create方法就可以啦~,只是需要传入大小和颜色等等的参数即可。

    void GameLayer::addStartLine()
    {
        auto block = Block::createWithArgs(Color3B::YELLOW, Size(visibleSize.width,visibleSize.height/4), "Touch to start", 40, Color4B::BLACK);                  //调用方法。
        this->addChild(block);        //加入到场景中,如果没有设定Position的话,就是默认在Vec2::ZERO的位置
    }

    然后上图看效果、(记得在init中调用此方法).

     

    三、加入一个结束栏

    void GameLayer::addEndLine()
    {
        auto block = Block::createWithArgs(Color3B::GREEN, visibleSize, "Game Over", 40, Color4B::BLACK);
        block->setBlockCol(4);
        this->addChild(block);
        
    }

    效果如下哈:

    四、添加NormalLine以及实现初始化

    (1)实现NormalLine的方法就是添加4个块,一个黑的,3白的。实现如下

    void GameLayer::addNormalLine(int blockCol)//Col即行
    {             
        int blackRow = CCRANDOM_0_1()*4;   //随机数,随机一个黑色的方块
        for(int i=0;i<4;i++)
        {
            auto block = Block::createWithArgs(blackRow==i?Color3B::BLACK:Color3B::WHITE,
                                               Size(visibleSize.width/4-1,visibleSize.height/4-1), "", 20, Color4B::BLACK);
            block->setPosition(Vec2(i*visibleSize.width/4,blockCol*visibleSize.height/4));
            block->setBlockCol(blockCol);//储存所在的行号
            this->addChild(block);
        }
    }

    (2)初始化界面

    void GameLayer:: startGame()
    {
        this->addStartLine();
        this->addNormalLine(1);
        this->addNormalLine(2);
        this->addNormalLine(3);
        
    }

    于是乎,我们没有WelcomeScene的别踩白块的开始界面就此OK!!

    五、游戏触摸事件的实现。

    游戏的交互很简单,就是点一下黑的就变灰,然后下移(这个放在GameLoop中),点下白的就拜拜。

    实现如下:

    (1)先继承Layer的触摸方法。

    virtual bool onTouchBegan(Touch *touch, Event *unused_event);

    这是一个单点的触摸方法。还有3个,我们这里用不到,就先不多说啦,然后这个方法,可以帮助我们实现触摸交互的功能。

    然后我们还需要在init中,将此加入事件监听器。

        auto touchListener = EventListenerTouchOneByOne::create();   //创建一个单点触控的方法
        touchListener->onTouchBegan=CC_CALLBACK_2(GameLayer::onTouchBegan, this);    //加入方法
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener,this);//设置优先级

    (2)触摸方法的实现

    bool GameLayer::onTouchBegan(Touch *touch, Event *unused_event)
    {
        
        auto bs = Block::getBlocks();      //取出那个存放Block的数组
        Block *b;
       
        for(auto it = bs->begin(); it != bs->end(); it++)
        {
            b = *it;   //it是数组的指针,而*it才是其中存放的内容,即Block类的指针
    
            if(  b->getBlockCol() == 1 && b->getBoundingBox().containsPoint(touch->getLocation()) )
            {
                if(b->getColor()==Color3B::BLACK)
                {
                    
                    b->setColor(Color3B::GRAY);      //变灰
             break;
                }else
                {
                    MessageBox("GameOver","失败");   //失败,失败后可以要强制重新开始。。在此我就默默省了。
                }
            }
        }
    
        return true;
    }

     效果图如下:

                        

    六、GameLoop的实现

     (1)MoveDown的实现

    void GameLayer::moveDown()
    {
        this->addNormalLine(4);     //新加入一栏
       
        auto bs = Block::getBlocks();        
        for(auto it=bs->begin(); it!=bs->end(); it++)
        {
            (*it)->moveDown();     //所有的Block向下移动下。
        }
    }

    (2)GameLoop的实现

    如果仅仅实现(1)的话= =,那你玩到天荒地老都停不下来= =,所以我们要加一个限制,就是啥时候游戏结束。

    要不就是手残点到白的的时候死翘翘,要不就是集满25个Block就可以……(你懂的)。

    所以呢,我们需要加入一个计数变量_lineCount和是否结束的bool变量 _showEndLine,

    1、定义初始化

    在GameLayer.h定义一个int的变量,然后再那个初始化中初始化为0,_showEndline则初始化为false

    2、然后在addNormalLine()方法计数++

    3、然后在MoveDone中进行一个结束的判断。

    if(_lineCount<25)
        {
            this->addNormalLine(4);
        }
        
        else if(!_showEndLine)
        {
           this-> addEndLine();
           _showEndLine = true;
        }

    4、然后在触摸事件中,也要多一个判断,就是结束栏虽然点到,但是不会变成灰色的= =

                if(b->getColor()==Color3B::BLACK)
                {
                    
                    b->setColor(Color3B::GRAY);
                    this->moveDown();break;
                }
                
                else if(b->getColor()==Color3B::GREEN)
                {
                    this->moveDown();
                }
                
                else
                {
                    MessageBox("GameOver","失败");
                }

    5、最后上图

    七、计时间的加入。

    (1)当然是要建立一个Label,嘻嘻,在头文件中定义:

     Label *_timerLabel;       
    
     long _startTime;        //开始的时刻
    
     bool _timeRunning;       //是否在跑

    (2)相关方法

    void GameLayer::update(float dt)     //继承的update方法,会自动一秒60次的更新画面
    {
        long offset = clock()-_startTime;         //计算出时间
         
        _timerLabel->setString(StringUtils::format("%g",((double)offset)/1000000));   //改变Label的值。
    } 
    
    
    void GameLayer::startTimer()    //开始的时刻
    {
        if(!_timeRunning)
        {
            scheduleUpdate();
            _startTime = clock();
            _timeRunning = true;
        }
    }
    
    void GameLayer::stopTimer()    //结束
    {
        if(_timeRunning)
        {
            unscheduleUpdate();
            _timeRunning = false;
        }
    }

    void initTimeLabel() //初始化_timerLabel
    {

    _timerLabel = Label::create();

    _timerLabel->setColor(Color3B::BLUE);

    _timerLabel->setSystemFontSize(50);
    _timerLabel->setString("0.0000");
    _timerLabel->setPosition(visibleSize.width / 2, visibleSize.height - 100);
    this->addChild(_timerLabel,10)
    }

     然后上图。看效果。到此经典模式完成,其他模式,我会以后再分享,因为我也是看别人的学习的,我是个小白,只是把每次学习的通过写博客的方式强化印象,并且希望其他小白有个借鉴。毕竟只有开放,才能更快更好的进步。

     

  • 相关阅读:
    EL表达式(Expression Language)
    JSP简单功能介绍
    MySQL基础使用
    JDBC
    MySQL安装卸载
    stanfordnlp dependencies(依存关系简写表)
    不需要深度学习就能做的文本分类器
    词向量的cbow模型
    pytorch实现自己的textCNN
    OpenCV编译viz模块
  • 原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/3909830.html
Copyright © 2011-2022 走看看