zoukankan      html  css  js  c++  java
  • 4.帧循环(游戏循环),schedule

    

    1 概述

    游戏乃至图形界面的本质是不断地画图,然而画图并非任意的,不论什么游戏都须要遵循一定的规则来呈现出来,这些规则就体现为游戏逻辑。游戏逻辑会控制游戏内容,使其依据用户输入和时间流逝而改变。因此。游戏能够抽象为不断地反复。

    2 下面动作:

    A 处理用户输入

    B 处理定时事件

    C 画图

    游戏主循环就是这种一个循环,它会重复运行以上动作,保持游戏进行下去。直到玩家退出游戏。

    CCDirector::mainLoop()方法,这种方法负责调动定时器,画图,发送全局通知,并处理内存回收池。该方法按帧调用,每帧调用一次。而帧间间隔取决于两个因素,一个是预设的帧率,默觉得60帧每秒:还有一个是每帧的计算大小。

    当逻辑处理与画图计算过大时,设备无法完毕每秒60次绘制,此时帧率就会减少。

    3 实现

    mainLoop()方法是定义在CCDirector中的抽象方法。它的实现位于同一个文件里的CCDisplayLinkDirector类。代码例如以下:

    上述代码主要包括例如以下3个步骤。

    推断是否须要释放CCDirector,假设须要,则删除CCDirector占用的资源,通常。游戏结束时才会运行这个步骤。

    调用drawScene()发方法,绘制当前场景并进行其它必要的处理。

    弹出自己主动回收池,使得这一帧被放入自己主动回收池的对象所有释放。

     

    在主循环中drawScene(),主要进行3个操作:

    调用了定时调度器的update方法,引发定时器事件。

    假设场景须要被切换,则调用setNextStage方法。在显示场景前切换场景。

    调用当前场景的visit方法,绘制当前场景。

    4 定时器

    Schedule.h

    #ifndef __Schedule_H__

    #define __Schedule_H__

     

    #include "cocos2d.h"

    USING_NS_CC;

    class Schedule :public CCLayer {

    public:

        static CCScene * scene();

        CREATE_FUNC(Schedule);

        bool init();

     

        void update(float) override;

     

        void mySchedule(float dt);

    };

     

    #endif

    Schedule.cpp

    #include "Schedule.h"

    #include "AppMacros.h"

     

    CCScene *Schedule::scene()

    {

        CCScene * scene = CCScene::create();

        Schedule * layer = Schedule::create();

        scene->addChild(layer);

        return scene;

    }

     

    bool Schedule::init()

    {

        CCLayer::init();

        //scheduleUpdate();

        //unscheduleUpdate();

     

        //scheduleOnce(schedule_selector(Schedule::mySchedule), 2);

        schedule(schedule_selector(Schedule::mySchedule));

        //功能等同scheduleUpdate();回调函数能够自己定义

        //schedule(schedule_selector(Schedule::mySchedule), 3);

        //CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);

        //schedule(schedule_selector(Schedule::mySchedule),1,10,4);

        //4s以后。每隔1s运行一次回调。共运行10

     

        CCSprite * spr = CCSprite::create("p_2_01.png");

        spr->setPosition(ccp(100,winSize.height / 2));

        addChild(spr);

        spr->setTag(100);

     

        //CCMoveBy * by = CCMoveBy::create(2, ccp(300, 0));

        //CCMoveBy * by1 = (CCMoveBy *)by->reverse();

        //CCSequence *seq = CCSequence::create(by, by1, NULL);

        //spr->runAction(CCRepeatForever::create(seq));

     

        return true;

    }

     

    void Schedule::update(float dt)

    {

        CCLOG("dt = %g",dt);

        static int i = 0;

        i++;

        if (i == 120)

        {

            //结束定时器

            unscheduleUpdate();

            CCLog("schedule is over");

        }

    }

     

    void Schedule::mySchedule(float dt) {

        CCSprite * spr = (CCSprite *)getChildByTag(100);

        float v = 300 / 2;

     

        static int count = 0;

        count++;

     

        static bool flag = true;

        if (flag)

        {

            if ((spr->getPositionX() + v*dt) < 400)

            {

                spr->setPositionX(spr->getPositionX() + v*dt);

            }

            else

            {

                flag = !flag;

            }

        }

        if (!flag)

        {

            if ((spr->getPositionX() - v*dt) > 100)

            {

                spr->setPositionX(spr->getPositionX() - v*dt);

            }

            else

            {

                flag = !flag;

            }

        }

     

        if (count == 1000)

        {

            unschedule(schedule_selector(Schedule::mySchedule));

        }

    }

    执行结果:

     

    5 定时器Schedule

    A 帧循环定时器

    scheduleUpdate();//帧循环定时器。每一帧都会被调动,对实时性要求很高的,比方碰撞检測

    void update(float delta);

    unscheduleUpdate();//关闭定时器

    B 一次性定时器

    參数解析:

    scheduleOnce(SEL_SCHEDULE selector, float delay)

    //第一个參数表示要回调的函数。第二个參数表示延时

    typedef void (CCObject::*SEL_SCHEDULE)(float);

    #define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR);

    scheduleOnce (schedule_selector(Schedule::updateOnce),2);

    void updateOnce(float delta);

     

    C 自己定义定时器

    自己定义定时器有3个重载函数。底层都默认调用了scheduleSelector,它的几个參数分别表示,scheduleSelector回调函数,interval时间间隔,repeat反复次数,delay延时运行。

    void CCNode::schedule(SEL_SCHEDULE selector) {

    this->schedule(selector, 0.0f, kCCRepeatForever, 0.0f);

    }

     

    /本质同scheduleUpdate 可是能够自己写回调函数

    void CCNode::schedule(SEL_SCHEDULE selector, float interval) {

    this->schedule(selector, interval, kCCRepeatForever, 0.0f);

    }

     

    void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay){

    m_pScheduler->scheduleSelector(selector, this, interval , repeat,delay, !m_bRunning);

    }

     

    D 定时器停止

    void CCNode::unschedule(SEL_SCHEDULE selector);

    void CCNode::unscheduleAllSelectors();

    注意:多个定时器,可并存。可彼此開始与停止。

     

     

     

     

     

     

     

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Scons 三
    Scons 二
    vs code插件
    Scons一
    实例演示 C# 中 Dictionary<Key, Value> 的检索速度远远大于 hobbyList.Where(c => c.UserId == user.Id)
    ASP.NET Core 如何用 Cookie 来做身份验证
    如何设计出和 ASP.NET Core 中 Middleware 一样的 API 方法?
    小记编程语言的设计
    解决 VS2019 打开 edmx 文件时没有 Diagram 视图的 Bug
    一款回到顶部的 jQuery 插件,支持 Div 中的滚动条回到顶部
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4631265.html
Copyright © 2011-2022 走看看