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();
注意:多个定时器,可并存。可彼此開始与停止。
版权声明:本文博客原创文章,博客,未经同意,不得转载。