1. 概述

ActionManager管理所有的action,调度所有的action,删除指定的action。每个action对应一个node对象,action存储在actions中,actions和node绑定在一个element中。

2. 学习

2.1 在哪使用

Director类中有成员ActionManager类单例对象指针_actionManager。

Director类在创建时调用到Director::init(void)方法,有以下操作:

_actionManager = new (std::nothrow) ActionManager();
_scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);

scheduleUpdate方法是执行了schedulePerFrame方法,_actionManager的update方法作为回调函数,故该update方法在每帧被调用。

schedulePerFrame方法执行后,_actionManager作为target,update方法作为回调函数新建优先级最高的Timer。

2.2 一些成员

ActionManager类成员变量:

struct _hashElement *_targets; // Element容器
struct _hashElement *_currentTarget; // 当前的Element
bool _currentTargetSalvaged;

ActionManager类结构体变量:

typedef struct _hashElement
{
struct _ccArray *actions;
Node *target;
int actionIndex;
Action *currentAction; // 当前Action
bool currentActionSalvaged;
bool paused;
UT_hash_handle hh;
} tHashElement;

2.3 update方法

简要的说,update方法是对哈希链表_targets的每个element作为_currentTarget,再把每个element的action作为currentAction,其中包含对action和element的延后release()。

ActionManager的update(float dt)方法执行大致流程:

2.4 addAction方法

addAction(Action *action, Node *target, bool paused)方法执行流程:

新建element时,会对target执行retain()。

action添加到actions时,执行ccArrayAppendObject(element->actions, action),对action执行retain()。

2.5 pause resume

pauseTarget(Node *target)
resumeTarget(Node *target)
resumeTargets(const Vector<Node*>& targetsToResume)

上面这3个方法对target对应的element的paused变量置true或false。

pauseAllRunningActions()方法,对哈希链表_targets的每个element的成员pause置true,并用Vector<Node*> idsWithActions保存暂停了的target。添加到容器时,这些target执行retain(),在手动调用恢复方法resumeTargets(const Vector<Node*>& targetsToResume)后,对Vector容器执行clear()方法,此时对target执行release()。

2.6 remove

删除action操作归纳到以下两种方法:

removeAllActionsFromTarget(Node *target)
removeActionAtIndex(ssize_t index, tHashElement *element)

removeAllActionsFromTarget方法

首先通过target从哈希链表_targets中查找对应的element。如果是element的currentAction且currentActionSalvaged为false,说明该action被target执行,对于这个action要retain(),并currentActionSalvaged置true,下一步的release()延后执行。再执行ccArrayRemoveObjectAtIndex,所有action执行release(),之后只有currentAction没被删除。actions为空就要删除element了,此时若_currentTarget为当前element,即target正在执行,_currentTargetSalvaged置true,暂不删除element。

removeActionAtIndex方法

从element的actions中对指定的action执行release(),若currentAction为当前action则延后release(),并修改标志currentActionSalvaged为true。之后若actions为空,在删除element之前,若_currentTarget为当前element,_currentTargetSalvaged置true并暂不删除。

2.7 currentActionSalvaged _currentTargetSalvaged

currentActionSalvaged属于element,_currentTargetSalvaged属于ActionManager。

在ActionManager的update方法中,在对当前遍历到的element进行所有操作之前,_currentTargetSalvaged置false,在对element的actions遍历结束后,判断_currentTargetSalvaged。若在遍历actions时,有action被remove操作,之后需要判断actions是否为空,为空则置_currentTargetSalvaged为true。即在对element的actions遍历结束后才能对release()无action的element。

在对action执行step(dt)之前,currentActionSalvaged置false,执行step(dt)结束之后,再判断currentActionSalvaged,即对removeAction方法指定的action执行release()需要在step(dt)执行之后真正执行。

Cocos2d-x 学习笔记(8) ActionManager的更多相关文章

  1. 【Cocos2d-x】学习笔记目录

    从2019年7月开始学习游戏引擎Cocos2dx,版本3.17. 学习笔记尽量以白话的形式表达自己对源码的理解,而不是大篇幅复制粘贴源码. 本人水平有限,欢迎批评指正! Cocos2d-x 学习笔记 ...

  2. cocos2dx游戏开发——微信打飞机学习笔记(三)——WelcomeScene的搭建

    一.场景与层的关系: cocos2dx的框架可以说主要由导演,场景,层,精灵来构成: 1.其中导演,意如其名,就是操控整个游戏的一个单例,管理着整个游戏. 2.场景就像电影的一幕剧情,所以说,懂得如何 ...

  3. android cocos2d-x for Android安装和学习笔记(请用adt-bundle21.1或以上导入)

    引用:http://weimingtom.iteye.com/blog/1483566 (20121108)注意:这篇文章用cdt编译ndk工程的内容已过时(现在可以用adt-bundle,避免配置繁 ...

  4. [Cocos2d-x for WP8学习笔记] HelloWorld结构分析

    先来看一下目录结构: Assets:游戏资源文件,图片音频等,Resource文件夹也有类似功能 include:用于放置游戏头文件 Shaders:渲染器着色器文件(大雾) cocos2dorig. ...

  5. cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类

    前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类  __String . 使用cocos2d::__Str ...

  6. Cocos2d-x学习笔记(17)(TestCpp源代码分析-1)

    TestCpp源代码基于Cocos2d-x2.1.3版本号,部分资源来自红孩儿的游戏编程之路CSDN博客地址http://blog.csdn.net/honghaier/article/details ...

  7. 《Cocos2d-x游戏开发实战精解》学习笔记4--实战一个简单的钢琴

    上一节学习了使用Cocos2d-x播放音乐的方法,但是那种方法一般只适合于播放较大的音乐,而一般比较短小的音乐(如游戏中的打斗.按键音效等)则要通过playEffect来播放.本节使用该方法以及之前学 ...

  8. 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音

    <Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...

  9. cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug

    cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug http://blog.csdn.net/allenice1/article/details/ ...

随机推荐

  1. MySQL查看当前用户

    mysql> select current_user();+----------------+| current_user() |+----------------+| root@localho ...

  2. charles 映射到本地文件/文件夹

    本文参考:charles 映射到本地文件/文件夹 本地映射/Map Local Settings 功能:把需要请求网络的文件映射为请求本地文件 本地映射工具 本地映射工具使您能够使用本地文件,就好比他 ...

  3. mybatis源码专题(1)--------复习jdbc操作,编译mybatis源码,准备为你的简历加分吧

    本文是作者原创,版权归作者所有.若要转载,请注明出处.文章中若有错误和疏漏之处,还请各位大佬不吝指出,谢谢大家. 1.mybatis的底层是jdbc操作,我们来回顾一下,如下  运行以后的结果如下图: ...

  4. CentOS安装TeamViewer

    在https://www.teamviewer.com/en/download/linux/ 选择合适的host版本. wget https://download.teamviewer.com/dow ...

  5. Linux之正则表达式grep

    真好!

  6. at org.apache.jsp.WEB_002dINF.pages.login_jsp._jspInit( login_jsp.java:22)

    SEVERE: Servlet.service() for servlet jsp threw exception java.lang.NullPointerException at org.apac ...

  7. 微信小程序中scroll-view的几个坑

    微信小程序中scroll-view的几个坑 1:设置scroll-x时,却不能横向滚动,因为view是block组件,但是这里用了flex就不能滚动了(想用flex布局,请开启属性enable-fle ...

  8. shell管道与重定向

    输出重定向 $ ls -l > lsoutput 这条命令将ls命令执行后的结果输入出到lsoutput文件中. 在linux shell中使用符号 > ,< 来完成输入输出的重定向 ...

  9. 限制页面被pc端访问

    在需要被pc端访问的页面的脚本里加上如下代码即可: <script>var system = {}; var p = navigator.platform; var u = navigat ...

  10. ajax技术实现登录判断用户名是否重复以及利用xml实现二级下拉框联动,还有从数据库中获得

    今天学了ajax技术,特地在此写下来作为复习. 一.什么是ajax? 客户端(特指PC浏览器)与服务器,可以在[不必刷新整个浏览器]的情况下,与服务器进行异步通讯的技术  即,AJAX是一个[局部刷新 ...