Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add timeScale and pause()/resume() to cc.Tween #16098

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
79 changes: 45 additions & 34 deletions cocos/tween/actions/action-interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
THE SOFTWARE.
*/

import { FiniteTimeAction, Action } from './action';
import { macro, logID, errorID } from '../../core';
import { errorID, logID, macro } from '../../core';
import { Action, FiniteTimeAction } from './action';
import { ActionInstant } from './action-instant';

/**
Expand All @@ -50,16 +50,23 @@
export class ActionInterval extends FiniteTimeAction {
protected MAX_VALUE = 2;
protected _elapsed = 0;
protected _firstTick = false;

// eslint-disable-next-line @typescript-eslint/ban-types
protected _easeList: Function[] = [];

protected _speed = 1;
protected _repeatForever = false;
_repeatMethod = false; // Compatible with repeat class, Discard after can be deleted
protected _speedMethod = false; // Compatible with repeat class, Discard after can be deleted

// for pausing the action
paused = false;
// for time scale
timeScale = 1;

constructor (d?: number) {
super();
if (d !== undefined && !isNaN(d)) {
if (d !== undefined && !Number.isNaN(d)) {
this.initWithDuration(d);
}
}
Expand All @@ -82,8 +89,10 @@
// prevent division by 0
// This comparison could be in step:, but it might decrease the performance
// by 3% in heavy based action games.
this._elapsed = 0;
this._firstTick = true;

// _elapsed = -1 means it's the first tick
this._elapsed = -1;

return true;
}

Expand Down Expand Up @@ -128,7 +137,7 @@
easing (easeObj: any): ActionInterval {
if (this._easeList) this._easeList.length = 0;
else this._easeList = [];
for (let i = 0; i < arguments.length; i++) this._easeList.push(arguments[i]);

Check failure on line 140 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Function`
return this;
}

Expand All @@ -142,16 +151,20 @@
}

step (dt: number): void {
if (this._firstTick) {
this._firstTick = false;
// _elapsed = -1 means it's the first tick
if (this._elapsed === -1) {
this._elapsed = 0;
} else this._elapsed += dt;
} else if (this.paused) {
return;
} else {
this._elapsed += dt * this.timeScale;
}

// 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.macro.FLT_EPSILON))));
let t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896);
t = (t < 1 ? t : 1);
this.update(t > 0 ? t : 0);
t = t > 0 ? (t < 1 ? t : 1) : 0;
SantyWang marked this conversation as resolved.
Show resolved Hide resolved
this.update(t);

// Compatible with repeat class, Discard after can be deleted (this._repeatMethod)
if (this._repeatMethod && this._timesForRepeat > 1 && this.isDone()) {
Expand All @@ -169,8 +182,8 @@

startWithTarget (target: any): void {
Action.prototype.startWithTarget.call(this, target);
this._elapsed = 0;
this._firstTick = true;
// _elapsed = -1 means it's the first tick
this._elapsed = -1;
}

reverse (): ActionInterval {
Expand Down Expand Up @@ -256,7 +269,7 @@
*/
repeat (times: number): ActionInterval {
times = Math.round(times);
if (isNaN(times) || times < 1) {
if (Number.isNaN(times) || times < 1) {
logID(1014);
return this;
}
Expand Down Expand Up @@ -285,7 +298,7 @@
* Runs actions sequentially, one after another.
*/
export class Sequence extends ActionInterval {
static _actionOneTwo = function (actionOne: ActionInterval, actionTwo: ActionInterval): Sequence {
static _actionOneTwo (actionOne: ActionInterval, actionTwo: ActionInterval): Sequence {
const sequence = new Sequence();
sequence.initWithTwoActions(actionOne, actionTwo);
return sequence;
Expand Down Expand Up @@ -323,7 +336,7 @@
for (let i = 1; i < last; i++) {
if (paramArray[i]) {
action1 = prev;
prev = Sequence._actionOneTwo(action1, paramArray[i]);

Check failure on line 339 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `ActionInterval`

Check failure on line 339 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `ActionInterval`
}
}
this.initWithTwoActions(prev, paramArray[last]);
Expand All @@ -346,7 +359,7 @@
durationOne *= actionOne._repeatMethod ? actionOne._timesForRepeat : 1;
durationTwo *= actionTwo._repeatMethod ? actionTwo._timesForRepeat : 1;
const d = durationOne + durationTwo;
this.initWithDuration(d);

Check failure on line 362 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `number`

this._actions[0] = actionOne;
this._actions[1] = actionTwo;
Expand All @@ -355,7 +368,7 @@

clone (): any {
const action = new Sequence();
this._cloneDecoration(action as any);

Check failure on line 371 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `ActionInterval`
action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone());
return action as any;
}
Expand All @@ -378,7 +391,6 @@
const locSplit = this._split;
const locActions = this._actions;
const locLast = this._last;
let actionFound: ActionInterval;

dt = this._computeEaseTime(dt);
if (dt < locSplit) {
Expand Down Expand Up @@ -411,7 +423,8 @@
}
}

actionFound = locActions[found];
const actionFound: ActionInterval = locActions[found];

// Last action found and it is done.
if (locLast === found && actionFound.isDone()) return;

Expand All @@ -438,8 +451,7 @@
* The created action will run actions sequentially, one after another.
* @zh 顺序执行动作,创建的动作将按顺序依次运行。
* @method sequence
* @param {FiniteTimeAction|FiniteTimeAction[]} actionOrActionArray
* @param {FiniteTimeAction} ...tempArray
* @param {FiniteTimeAction[]} actionArray
* @return {ActionInterval}
* @example
* import { sequence } from 'cc';
Expand All @@ -451,21 +463,20 @@
* const seq = sequence(actArray);
*/
// todo: It should be use new
export function sequence (/* Multiple Arguments */tempArray: any): ActionInterval {
const paramArray = (tempArray instanceof Array) ? tempArray : arguments;
if (paramArray.length === 1) {
export function sequence (actionArray: Action[]): ActionInterval | null {
if (actionArray.length === 1) {
errorID(1019);
return null as any;
return null;
}
const last = paramArray.length - 1;
if ((last >= 0) && (paramArray[last] == null)) logID(1015);
const last = actionArray.length - 1;
if ((last >= 0) && (actionArray[last] == null)) logID(1015);

let result: any = null;
let result: ActionInterval | null = null;
if (last >= 0) {
result = paramArray[0];
result = actionArray[0] as ActionInterval;
for (let i = 1; i <= last; i++) {
if (paramArray[i]) {
result = Sequence._actionOneTwo(result, paramArray[i]);
if (actionArray[i]) {
result = Sequence._actionOneTwo(result, actionArray[i] as ActionInterval);
}
}
}
Expand Down Expand Up @@ -493,7 +504,7 @@

constructor (action?: any, times?: any) {
super();
times !== undefined && this.initWithAction(action, times);

Check warning on line 507 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Expected an assignment or function call and instead saw an expression

Check failure on line 507 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `FiniteTimeAction`

Check failure on line 507 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `number`
}

/*
Expand Down Expand Up @@ -635,7 +646,7 @@

constructor (action?: ActionInterval) {
super();
action && this.initWithAction(action);

Check warning on line 649 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Expected an assignment or function call and instead saw an expression
}

/*
Expand Down Expand Up @@ -666,7 +677,7 @@

step (dt: any): void {
const locInnerAction = this._innerAction!;
locInnerAction.step(dt);
locInnerAction.step(dt * this.timeScale);
if (locInnerAction.isDone()) {
// var diff = locInnerAction.getElapsed() - locInnerAction._duration;
locInnerAction.startWithTarget(this.target);
Expand Down Expand Up @@ -727,7 +738,7 @@
* @extends ActionInterval
*/
export class Spawn extends ActionInterval {
static _actionOneTwo = function (action1: any, action2: any): Spawn {
static _actionOneTwo (action1: any, action2: any): Spawn {
const pSpawn = new Spawn();
pSpawn.initWithTwoActions(action1, action2);
return pSpawn;
Expand Down Expand Up @@ -775,12 +786,12 @@
const d1 = action1._duration;
const d2 = action2._duration;

if (this.initWithDuration(Math.max(d1, d2))) {

Check failure on line 789 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `number`

Check failure on line 789 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `number`
this._one = action1;
this._two = action2;

if (d1 > d2) {
this._two = Sequence._actionOneTwo(action2, delayTime(d1 - d2));

Check failure on line 794 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `ActionInterval`
} else if (d1 < d2) {
this._one = Sequence._actionOneTwo(action1, delayTime(d2 - d1));
}
Expand Down Expand Up @@ -835,15 +846,15 @@
* const action = spawn(jumpBy(2, new Vec2(300, 0), 50, 4), rotateBy(2, 720));
* todo: It should be the direct use new
*/
export function spawn (/* Multiple Arguments */tempArray: any): FiniteTimeAction {
export function spawn (/* Multiple Arguments */tempArray: any): FiniteTimeAction | null {
const paramArray = (tempArray instanceof Array) ? tempArray : arguments;
if (paramArray.length === 1) {
errorID(1020);
return null as any;
return null;
}
if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null)) logID(1015);

let prev = paramArray[0];
let prev: FiniteTimeAction = paramArray[0];
for (let i = 1; i < paramArray.length; i++) {
if (paramArray[i] != null) prev = Spawn._actionOneTwo(prev, paramArray[i]);
}
Expand Down Expand Up @@ -905,7 +916,7 @@

constructor (action?: any) {
super();
action && this.initWithAction(action);

Check warning on line 919 in cocos/tween/actions/action-interval.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Expected an assignment or function call and instead saw an expression
}

/*
Expand Down
75 changes: 64 additions & 11 deletions cocos/tween/tween.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
THE SOFTWARE.
*/

import { TweenSystem } from './tween-system';
import { warn } from '../core';
import { ActionInterval, sequence, repeat, repeatForever, reverseTime, delayTime, spawn } from './actions/action-interval';
import { removeSelf, show, hide, callFunc } from './actions/action-instant';
import { legacyCC } from '../core/global-exports';
import { Action, FiniteTimeAction } from './actions/action';
import { callFunc, hide, removeSelf, show } from './actions/action-instant';
import { ActionInterval, delayTime, repeat, repeatForever, reverseTime, sequence, spawn } from './actions/action-interval';
import { ITweenOption } from './export-api';
import { TweenAction } from './tween-action';
import { SetAction } from './set-action';
import { legacyCC } from '../core/global-exports';
import { TweenAction } from './tween-action';
import { TweenSystem } from './tween-system';

// https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c
type FlagExcludedType<Base, Type> = { [Key in keyof Base]: Base[Key] extends Type ? never : Key };
Expand Down Expand Up @@ -60,6 +60,27 @@ export class Tween<T> {
private _target: T | null = null;
private _tag = Action.TAG_INVALID;

// for time scale
private _timeScale = 1;

/**
* !#en set/get time scale for tween
* !#zh 设置/读取 tween 的 time scale (时间缩放参数)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use @en and @zh instead

* @property timeScale
* @type {Number}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to specify property name and type, it's automatically detected

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update all API comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to specify property name and type, it's automatically detected

改好了. 但是我发现你们原先的代码里 在这方面也有一些问题. 比如有的方法会写@method @return , 有的不写.

* @default 1
*/
get timeScale (): number {
return this._timeScale;
}

set timeScale (value: number) {
this._timeScale = value;
SantyWang marked this conversation as resolved.
Show resolved Hide resolved
if (this._finalAction) {
(this._finalAction as ActionInterval).timeScale = value;
}
}

constructor (target?: T | null) {
this._target = target === undefined ? null : target;
}
Expand Down Expand Up @@ -138,6 +159,38 @@ export class Tween<T> {
return this;
}

/**
* !#en
* Pause this tween
* !#zh
* 暂停当前 tween
* @method pause
* @return {Tween}
* @typescript pause(): Tween<T>
*/
pause (): Tween<T> {
if (this._finalAction) {
(this._finalAction as ActionInterval).paused = true;
}
return this;
}

/**
* !#en
* Resume this tween
* !#zh
* 从暂停状态恢复当前 tween
* @method resume
* @return {Tween}
* @typescript resume(): Tween<T>
*/
resume (): Tween<T> {
if (this._finalAction) {
SantyWang marked this conversation as resolved.
Show resolved Hide resolved
(this._finalAction as ActionInterval).paused = false;
}
return this;
}

/**
* @en
* Clone a tween.
Expand Down Expand Up @@ -261,7 +314,7 @@ export class Tween<T> {
*/
sequence (...args: Tween<T>[]): Tween<T> {
const action = Tween._wrappedSequence(...args);
this._actions.push(action);
this._actions.push(action as Action);
return this;
}

Expand All @@ -275,7 +328,7 @@ export class Tween<T> {
*/
parallel (...args: Tween<T>[]): Tween<T> {
const action = Tween._wrappedParallel(...args);
this._actions.push(action);
this._actions.push(action as Action);
return this;
}

Expand Down Expand Up @@ -437,7 +490,7 @@ export class Tween<T> {
if (actions.length === 1) {
action = actions[0];
} else {
action = sequence(actions);
action = sequence(actions) as Action;
}

return action;
Expand All @@ -449,7 +502,7 @@ export class Tween<T> {

private static readonly _tmp_args: Tween<any>[] | Action[] = [];

private static _wrappedSequence (...args: Action[] | Tween<any>[]): ActionInterval {
private static _wrappedSequence (...args: Action[] | Tween<any>[]): ActionInterval | null {
const tmp_args = Tween._tmp_args;
tmp_args.length = 0;
for (let l = args.length, i = 0; i < l; i++) {
Expand All @@ -459,10 +512,10 @@ export class Tween<T> {
}
}

return sequence.apply(sequence, tmp_args as any);
return sequence(tmp_args as Action[]);
}

private static _wrappedParallel (...args: Action[] | Tween<any>[]): FiniteTimeAction {
private static _wrappedParallel (...args: Action[] | Tween<any>[]): FiniteTimeAction | null {
const tmp_args = Tween._tmp_args;
tmp_args.length = 0;
for (let l = args.length, i = 0; i < l; i++) {
Expand Down
Loading