current position:Home>Action system of coco2d-x-html5
Action system of coco2d-x-html5
2022-04-29 13:13:00【Sihang 0701】
This article has participated [ New people's creation ceremony ] Activities , Start the road of nuggets creation together .
One 、 Preface
hi , Hello everyone , I'm Sihang . Today, let's take a simple example , Let's study cocos2dx Is the execution process of the action , Finally, implement a custom action class .
Two 、 Code and effects
1、 Code
var pSprite = cc.Sprite.create("src/res/ui/icon.png");
pSprite.setPosition(cc.p(cc.winSize.width/2, cc.winSize.height/2));
cc.director.getRunningScene().addChild(pSprite)
var pMoveByAction = cc.moveBy(1, cc.p(100, 100));
pSprite.runAction(pMoveByAction);
Copy code
2、 effect
We played an abscissa and ordinate to move each 100 Pixel action
3、 ... and 、 analysis
1、 perform CCDirector.js Of drawScene Method
Why does each frame execute drawScene Method ? Refer to previous articles “coco2d-x-html5 And Director analysis ”
// CCDirector.js
drawScene: function () {
var renderer = cc.renderer;
// calculate "global" dt
// Calculate slice time ( The time interval between calls between frames )
this.calculateDeltaTime();
//tick before glClear: issue #533
if (!this._paused) {
// Scheduler execution update function
this._scheduler.update(this._deltaTime);
cc.eventManager.dispatchEvent(this._eventAfterUpdate);
}
Copy code
stay drawScene Function , We see execution CCScheduler.js Of update function
2、 perform CCScheduler.js Of update function
// CCScheduler.js
/** * 'update' the scheduler. (You should NEVER call this method, unless you know what you are doing.) * @param {Number} dt delta time */
update:function (dt) {
this._updateHashLocked = true;
if(this._timeScale !== 1)
dt *= this._timeScale;
var i, list, len, entry;
// The default is cc.ActionManager
for(i=0,list=this._updatesNegList, len = list.length; i<len; i++){
entry = list[i];
if(!entry.paused && !entry.markedForDeletion)
entry.callback(dt);
}
......
}
Copy code
2.1 CCActionManager If entered, add to CCScheduler Of _updatesNegList
From the source code above, we can see that , stay CCScheduler.js Of update In the function , Traverse the execution _updatesNegList The elements of the callback function . That means we need to look at CCActionManager Instantiated object , How it was added to CCActionManager Of _updatesNegList Inside
// CCDirector.js
init: function () {
......
//scheduler
// Instantiation Scheduler
this._scheduler = new cc.Scheduler();
//action manager
if (cc.ActionManager) {
// Instantiation ActionManager
this._actionManager = new cc.ActionManager();
// take actionManager Sign up to scheduler._updatesNegList
this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
} else {
this._actionManager = null;
}
......
}
Copy code
So let's see CCScheduler.js Of scheduleUpdate function
// CCScheduler.js
scheduleUpdate: function(target, priority, paused){
this._schedulePerFrame(function(dt){
// After registration , Execute every frame target.update Method
target.update(dt);
}, target, priority, paused);
},
Copy code
scheduleUpdate Called _schedulePerFrame function , So let's continue to play and see
_schedulePerFrame: function(callback, target, priority, paused){
......
// According to different priorities , Push into different queues
if (priority === 0){
this._appendIn(this._updates0List, callback, target, paused);
}else if (priority < 0){
this._priorityIn(this._updatesNegList, callback, target, priority, paused);
}else{
// priority > 0
this._priorityIn(this._updatesPosList, callback, target, priority, paused);
}
},
Copy code
above CCDirector.js Of init Inside , Yes
this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
Copy code
because cc.Scheduler.PRIORITY_SYSTEM It's a negative number , namely priority It's a negative number , such ActionManager Just sign up for _updatesNegList Inside .
Here we will understand how to execute CCActionManager.js Of update function .
3、 perform CCActionManager.js Of update function
// CCActionManager.js
/** * @param {Number} dt delta time in seconds */
update:function (dt) {
var locTargets = this._arrayTargets , locCurrTarget;
// this._arrayTargets Is an array , The elements inside elt It's a dictionary
// elt The format is {actions: [ action 1, action 2,...], }
for (var elt = 0; elt < locTargets.length; elt++) {
this._currentTarget = locTargets[elt];
locCurrTarget = this._currentTarget;
// There is no pause , And actions Valuable
if (!locCurrTarget.paused && locCurrTarget.actions) {
locCurrTarget.lock = true;
// The 'actions' CCMutableArray may change while inside this loop.
for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
if (!locCurrTarget.currentAction)
continue;
//use for speed
// Here is the specific action , such as cc.MoveBy Instantiated object
locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
locCurrTarget.currentAction.stop();
var action = locCurrTarget.currentAction;
locCurrTarget.currentAction = null;
this.removeAction(action);
}
locCurrTarget.currentAction = null;
}
locCurrTarget.lock = false;
}
// only delete currentTarget i
Copy code
Through the above source code , We found that... Was executed here CCAction Of step function Let's see how the next action is added to _arrayTargets Inside
3.1 How actions are added to CCActionManager.js Of _arrayTargets
Let's look at the code in another way . Let's go back to our top example code .
var pSprite = cc.Sprite.create("src/res/ui/icon.png");
pSprite.setPosition(cc.p(cc.winSize.width/2, cc.winSize.height/2));
cc.director.getRunningScene().addChild(pSprite)
var pMoveByAction = cc.moveBy(1, cc.p(100, 100));
pSprite.runAction(pMoveByAction);
Copy code
Take a look first CCSprite.js Of runAction function , We found that the function was not rewritten , Let's look at the parent class CCNode.js Of runAction function ,
// CCNode.js
runAction: function (action) {
cc.assert(action, cc._LogInfos.Node_runAction);
// To ActionManager management
this.actionManager.addAction(action, this, !this._running);
return action;
},
Copy code
See through the code ,runAction Called actionManager Of addAction Method
// CCActionManager.js
addAction:function (action, target, paused) {
if(!action)
throw new Error("cc.ActionManager.addAction(): action must be non-null");
if(!target)
throw new Error("cc.ActionManager.addAction(): target must be non-null");
//check if the action target already exists
var element = this._hashTargets[target.__instanceId];
//if doesn't exists, create a hashelement and push in mpTargets
if (!element) {
element = this._getElement(target, paused);
this._hashTargets[target.__instanceId] = element;
this._arrayTargets.push(element);
}
else if (!element.actions) {
element.actions = [];
}
// Add to actions Inside
element.actions.push(action);
// Added target object
action.startWithTarget(target);
},
Copy code
4、 perform cc.MoveBy Of step function
We found that cc.MoveBy No rewriting step function Let's look at the parent class cc.ActionInterval Of step function
step: function (dt) {
if (this._firstTick) {
this._firstTick = false;
this._elapsed = 0;
} else
{
// Lost time
this._elapsed += dt;
}
// this._duration The action is duration
//this.update((1 > (this._elapsed / this._duration)) ? this._elapsed / this._duration : 1);
//this.update(Math.max(0, Math.min(1, this._elapsed / Math.max(this._duration, cc.FLT_EPSILON))));
var t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896);
// t The value of is 0 To 1 Between , Current cumulative time / The total action takes time
// t Is the current frame scale , Then this value is multiplied by the total distance to be moved , You can calculate the current offset value
t = (1 > t ? t : 1);
this.update(t > 0 ? t : 0);
Copy code
We see in the step It's called in update function , Let's take a look at cc.MoveBy Of updata function
/** * Called once per frame. Time is the number of seconds of a frame interval. * @param {Number} dt */
update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
// this._positionDelta.x : Total offset x
// dt by 0 To 1 The ratio between
var x = this._positionDelta.x * dt;
var y = this._positionDelta.y * dt;
var locStartPosition = this._startPosition;
// Action superposition
if (cc.ENABLE_STACKABLE_ACTIONS) {
// Comment out the code of action superposition first , First look at the simple branch
......
} else {
this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
}
}
},
Copy code
It can be seen that the animation is essentially refreshing the coordinates of the wizard every frame .
Four 、 Custom action class
Through the above analysis, we know cc.moveBy How did the action take effect , Then let's customize an action class ,cc.rectBy, This action is within the specified time , Move the square with the specified side length .
4.1 Custom action class code
cc.RectBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
_positionDelta: null,
_startPosition: null,
_previousPosition: null,
/** * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. * @param {Number} duration duration in seconds * @param {Number} borderLenght Square side length * @param {Number} [deltaY] */
ctor: function (duration, borderLenght) {
cc.ActionInterval.prototype.ctor.call(this);
cc.ActionInterval.prototype.initWithDuration.call(this, duration)
this._borderLenght = borderLenght;
this._startPosition = cc.p(0, 0);
},
/** * Start the action with target. * @param {cc.Node} target */
startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
var locPosX = target.getPositionX();
var locPosY = target.getPositionY();
this._startPosition.x = locPosX;
this._startPosition.y = locPosY;
},
/** * Called once per frame. Time is the number of seconds of a frame interval. * @param {Number} dt */
update: function (dt) {
dt = this._computeEaseTime(dt);
if (this.target) {
// this._positionDelta.x : Total offset x
// dt by 0 To 1 The ratio between
var x = 0;
var y = 0;
if (dt <= 0.25) { // rising
y = this._borderLenght * dt * 4;
} else if (dt <= 0.5) { // Move right
y = this._borderLenght;
x = this._borderLenght * (dt - 0.25) * 4;
} else if (dt <= 0.75) { // falling
x = this._borderLenght;
y = this._borderLenght - (dt - 0.5) * this._borderLenght * 4;
} else { // Move left
x = this._borderLenght - (dt - 0.75) * this._borderLenght * 4;
}
var locStartPosition = this._startPosition;
this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
}
},
});
cc.rectBy = function (duration, borderLenght) {
return new cc.RectBy(duration, borderLenght);
};
Copy code
4.2 Custom action class representation
var pSprite = cc.Sprite.create("src/res/ui/icon.png");
pSprite.setPosition(cc.p(cc.winSize.width/2, cc.winSize.height/2));
cc.director.getRunningScene().addChild(pSprite)
var pRectByAction = cc.rectBy(2, 100);
pSprite.runAction(pRectByAction);
Copy code
copyright notice
author[Sihang 0701],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/04/202204291312542706.html
The sidebar is recommended
- Element notify notification prompt text wrap
- Belkin: it's too early to talk about real wireless space charging
- JavaScript ES6 set (set) type* ω *
- Understand JavaScript function execution process and scope chain
- Java project: nursing home management system (java + springboot + thymeleaf + HTML + JS + MySQL)
- Java project: drug management system (java + springboot + HTML + layui + bootstrap + seals + MySQL)
- An error is reported when installing hexo during hexo deployment. What is the reason and how to solve it (tag git | keyword path)
- [front end basics] Linux command: Project Automation deployment
- Less than 100 or win Porsche, Maserati "special supply" 3.0T technical analysis
- Introduction to basic methods of math built-in objects in JavaScript
guess what you like
CSS matches the nth element of the parent element
What is the commercialization process of unmanned robotaxi after China allows driverless steering wheel?
A lot of trouble, cook also worried: a quarter less than $8 billion
Ajax realizes no refresh paging (no refresh paging shopping cart source code)
[flutter topic] 101 what is flutter elements Yyds dry goods inventory
What is the commercialization process of unmanned robotaxi after China allows driverless steering wheel?
A lot of trouble, cook also worried: a quarter less than $8 billion
Element acquisition of data structure c language sequence stack
Set video label based on Vue
CSS realizes div width adaptation, and the proportion of height and width is fixed
Random recommended
- How to create JavaScript custom events
- Is there any recommendation for wireless signal and wired signal power amplification circuit?
- Introduction to basic methods of math built-in objects in JavaScript
- 1000km pure electric endurance is meaningless? Then why does the car factory still try its best to extend the endurance?
- [let's implement a simple vite!] Chapter 4 - compiling single file components
- 3-11xss htmlspecialchars bypass demo
- How to conduct architecture design 𞓜 deeply reveal Alibaba cloud serverless kubernetes (2)
- Heapdump performance community special series 7: front door opener of large factory -- Application Practice of fluent
- 1、 HTML base tag
- Don't leave the crane unless necessary! A case of novel coronavirus nucleic acid positive was found in Heshan, Guangdong
- [Architect (Part 20)] self defined template of scaffold and summary of phase I
- How does JavaScript understand this algorithm
- [live review] openharmony knowledge empowerment lesson 2, phase 5 - becoming a community talent
- Understand the basic history and knowledge of HTTP
- Influence of lazy loading of Web front-end training on Web Performance
- Guangxi 2021 Guangxi landscape - blessing Lake Changshou Island
- Responsive gulp Chinese network of web front end
- Twaver-html5 basic learning (26) background
- CSS learning notes [3] floating, not separated from document flow, inheritance and stacking
- Webengine loading local html is invalid, and html is the dynamic address generated by JS, which can be solved
- Event handling of react
- Character coding knowledge that needs to be understood in front-end development
- 05. JavaScript operator
- 06. JavaScript statement
- Vue basics and some components
- Introduction to front-end Er excellent resources
- Node. Summary of methods of outputting console to command line in JS
- The beginning of passion, the ending of carelessness, python anti climbing, Jiageng, friends asked for MIHA's API and arranged y24 for him
- Technology sharing | test platform development - Vue router routing design for front-end development
- Node under windows JS installation detailed steps tutorial
- Layui built-in module (element common element operation)
- Excuse me, my eclipse Exe software has clearly opened to display the number of lines. Why is it useless
- It was revealed that Meila of Sea King 2 had less than ten minutes to appear, which was affected by negative news
- Vue element admin how to modify the height of component El tabs
- Bootstrap navigation bar drop-down menu does not take effect
- Vue Preview PDF file
- Geely joined the hybrid sedan market, and Toyota seemed even more hopeless
- Mustache template engine for exploring Vue source code
- Referer and referer policy and picture anti-theft chain
- Explain the "three handshakes" and "four waves" of TCP connection in detail