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();

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

4.帧循环(游戏主循环),schedule相关推荐

  1. 游戏主循环(Game Loop)的详细解析

    译自:https://dewitters.com/dewitters-gameloop/ 一. 引言 游戏主循环是每个游戏的心跳,输送着整个游戏需要的养分.不幸的是没有任何一篇好的文章来指导一个菜鸟游 ...

  2. 游戏主循环基础例子 GameLoop

    游戏主循环基础例子 GameLoop 这里比较简单,直接发代码好了 import timefrom loguru import loggerfrom core import GetDeltaTime, ...

  3. 游戏主循环(Game Loop)详解

    每一个复杂的应用程序的核心都是一个循环(Loop) - 贯穿于一个应用程序生活周期的是一部分代码不断的重复执行时间.这个循环(Loop),可以就说是主循环.主循环的主要作用是:协调程序的行为(事件)和 ...

  4. cocos2d-x游戏开发(四)游戏主循环

    欢迎转载:http://blog.csdn.net/fylz1125/article/details/8518737 终于抽时间把这个游戏写完了.由于没有自拍神器,所以把它移植到了Android上,用 ...

  5. [摘抄]游戏主循环逻辑

    1. 最简单的情况 1 bool game_is_running = true; 2 while(game_is_running) 3 { 4 update_game(); // 逻辑帧 5 disp ...

  6. U-boot主循环main_loop分析

    2019独角兽企业重金招聘Python工程师标准>>> 原文在我博客:http://blog.csdn.net/andy_wsj/article/details/8614905 最近 ...

  7. java实现游戏的循环及游戏帧数处理

    引言: 制作游戏对游戏的循环处理无疑是重要的,只有处理对游戏的循环,才不会出现游戏的卡顿现象.我们知道游戏中的动画是由一帧帧的静止的画面形成的,那么如果每一帧的画面因为机器处理的不同使得渲染时间不同, ...

  8. 辛巴学院-Unity-剑英的c#提高篇(一)主循环

    这是测试版 辛巴学院:正大光明的不务正业. 最近刚刚离开了我服务了三年多的公司,因为一个无数次碰到的老问题,没钱了. 之前不知道做什么好的时候,机缘巧合之下和哒嗒网络的吴总聊了一下,发现了vr gam ...

  9. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...

最新文章

  1. 802.1x------2
  2. UVA10341解方程(二分)
  3. 找呀志_ContentResolver操作ContentProvider数据
  4. 利旧IBM X3650m2 安装esxi5.1提供云桌面(备忘)
  5. zk框架_ZK Web框架思想
  6. 【Python AsciiArt】利用命令行打印出字符图案
  7. URL不能过长,否则summit方法提交失败
  8. goldengate for mysql_GoldenGate for mysql to mysql:单向同步
  9. 加强的alert confirm js自定义对话框 多个按钮 ICO自定义
  10. 4.设计包(design package)
  11. Win10窗口拖动时自动最大化的问题,屏幕显示绿框,中间显示1
  12. 新书推荐——Linux系统管理与服务器配置
  13. 维基百科英文语料库下载地址
  14. 算法工程师面试基础题目及答案
  15. 基于labview的打地鼠游戏制作
  16. 看着2022年世界杯,我无比怀念98世界杯
  17. WebApp - 微信浏览器解决安全提示“防盗号或诈骗,请不要输入QQ密码”
  18. C#开发斑马RFID打印机zt410
  19. 计算机基础的课程标准,《计算机基础》课程标准
  20. 2021-03-17

热门文章

  1. 给书配代码-电力经济调度(3):计及网络安全约束的经济调度模型
  2. 爬虫实战:要不是热爱学习,谁会爬小姐姐。分析Ajax来爬取今日头条街拍美图(python)
  3. python打包exe 之打包sklearn模型中的各种坑及其解决方法。
  4. JavaScript实现判断整数是否为2的幂isPowerOfTwo算法(附完整源码)
  5. wxWidgets:wxDialog类用法
  6. boost::spirit模块实现一个复数微生成器的测试程序
  7. boost::mpl模块at相关的测试程序
  8. boost::gil模块数字扩展中的 resample_pixels() 示例
  9. boost::enable_current_exception用法测试程序
  10. boost::callable_traits添加member_cv的测试程序