Advanced Scripting
By starting this Advanced Scripting section it is assumed one is already familiar with the scripting system, including decorators and so on. Otherwise, please refer to the following documents to get up to speed first:
Instantiation
Define a Foo
class and a Bar
class through a script. The Foo
class needs to use the properties defined by the Bar
class, to allow directly issuing new
the Bar
class to an object in the Foo
class:
class Foo {
public bar: Bar = null;;
constructor() {
this.bar = new Bar();
}
}
let bar = new Foo();
Instance Methods
Instance methods should be declared in the prototype object:
class Foo {
public text!: string;
constructor() {
this.text = "this is sprite"
}
// Declare an instance method named "print"
print() {
console.log(this.text);
}
}
let obj = new Foo();
// Call the instance method
obj.print();
Type Determination
When making a type determination, use TypeScript’s native instanceof
.
class Sub extends Base {
}
let sub = new Sub();
console.log(sub instanceof Sub); //true
console.log(sub instanceof Base); //true
let base = new Base();
console.log(base instanceof Sub); // false
Static Variables and Static Methods
Static variables or static methods can be declared with static
:
class Foo {
static count = 0;
static getBounds() {
}
}
Static members are inherited by subclasses, and Creator gives a shallow copy of the parent’s static variables to the subclass when inherited, so that:
class Object {
static count = 11;
static range: { w: 100, h: 100 }
}
class Foo extends Object {
}
console.log(Foo.count); // The result is 11, because `count` inherits from the `Object` class
Foo.range.w = 200;
console.log(Object.range.w); // The result is 200 because 'Foo.range' and 'Object.range' refer to the same object
Private static members can also be defined directly outside of the class if inheritance is not a concern:
// Local methods
doLoad(sprite) {
// ...
};
// Local variables
let url = "foo.png";
class Sprite {
public url = '';
load() {
this.url = url;
doLoad(this);
};
};
Inheritance
Parent constructor
Note: the constructor of the parent class is automatically called before the subclass is instantiated, regardless of whether the subclass has a defined constructor or not.
class Node {
name: string;
constructor() {
this.name = "node";
}
}
class Sprite extends Node {
constructor() {
super();
// The parent constructor has already been called before the child constructor is called, so `this.name` has already been initialized
console.log(this.name); // "node"
// Reset `this.name`
this.name = "sprite";
}
}
let obj = new Sprite();
console.log(obj.name); // "sprite"
Rewrite
All member methods are dummy methods, and subclass methods can override parent methods directly:
class Shape {
getName() {
return "shape";
}
};
class Rect extends Shape {
getName () {
return "rect";
}
};
let obj = new Rect();
console.log(obj.getName()); // "rect"
get/set
Methods
If get
/set
is defined in a property, then the predefined get
/set
methods can be triggered when the property is accessed.
get
Define the get
method in the property:
@property
get num() {
return this._num;
}
@property
private _num = 0;
The get
method can return a value of any type.
Properties that have a get
method defined can be displayed in the Inspector panel and can be accessed directly in the code.
class Sprite {
@property
get width() {
return this._width;
}
@property
private _width = 0;
print(){
console.log(this.width);
}
};
Notes:
Properties cannot be serialized after the
get
method is defined, i.e. theserializable
parameter is not available.For example, the
width
property will neither be displayed in the editor nor serialized as shown below:get width() {
return this._width;
}
@property({ type: CCInteger, tooltip: "The width of sprite" })
private _width = 0;
Properties that have a
get
method defined need to haveproperty
defined if they need to be displayed by the editor, otherwise they won’t be rendered.For example, the
width
property will not be rendered on the editor if the@property
is removed, and the_width
property will be serialized:@property
get width() {
return this._width;
}
@property({ type: CCInteger, tooltip: "The width of sprite" })
private _width = 0;
The property itself that defines the
get
method is read-only, but the returned object is not read-only. The developer can still modify the properties inside the object through code, for example:get num() {
return this._num;
}
@property
private _num = 0;
start() {
console.log(this.num);
}
set
Define the set
method in the property:
set width(value) {
this._width = value
}
private _width = 0;
start() {
this.width = 20;
console.log(this.width);
}
The set
method takes an incoming parameter, which can be of any type. The set
method is generally used in conjunction with the get
method:
@property
get width() {
return this._width;
}
set width(value) {
this._width = value;
}
@property
private _width = 0;
Note: the
set
method does not define properties.