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

feat: GameObject active/active and Component enable/disable #192

Open
wants to merge 2 commits into
base: v1.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions examples/src/enable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import { Game, GameObject, resource, RESOURCE_TYPE, Component, System } from "@eva/eva.js";
import { RendererSystem } from "@eva/plugin-renderer";
import { Img, ImgSystem } from "@eva/plugin-renderer-img";
export const name = 'Enable';
export async function init(canvas) {

class Move extends Component<{ speed: { x: number, y: number }, myName: string }> {
static componentName = 'Move';
myName = ''

speed = {
// 移动速度
x: 100,
y: 200,
};
oldSpeed: { x: number, y: number }
init(obj) {
Object.assign(this, obj);
console.log('init', this.myName);
}
onEnable() {
console.log('onEnable', this.myName)
}
onDisable(): void {
console.log('onDisable', this.myName)
}
awake() {
console.log('awake', this.myName);
}
start() {
console.log('start', this.myName);
}
update(e) {
// console.log('update', this.myName)
}
onPause() {
this.oldSpeed = this.speed;
this.speed = {
x: 0,
y: 0,
};
}
onResume() {
this.speed = this.oldSpeed;
}
}

// class DemoSystem extends System {
// init() {
// console.log('system init');
// }
// awake() {
// console.log('system awake');
// }
// start() {
// console.log('system start');
// }
// update() {
// // console.log()
// }
// onPause() {
// console.log('system onPause');
// }
// onResume() {
// console.log('system onResume');
// }
// }

resource.addResource([
{
name: 'heart',
type: RESOURCE_TYPE.IMAGE,
src: {
image: {
type: 'png',
url: '//gw.alicdn.com/bao/uploaded/TB1lVHuaET1gK0jSZFhXXaAtVXa-200-200.png',
},
},
preload: false,
},
]);

const game = new Game({
systems: [
new RendererSystem({
canvas,
width: 750,
height: 1000,
}),
new ImgSystem(),
],
});
window.game = game
// game.addSystem(new DemoSystem());
{
const image = new GameObject('image', {
size: { width: 200, height: 200 },
origin: { x:0, y:0 },
position: {
x: 0,
y: 0,
},
});
window.image = image
image.addComponent(
new Move({
speed: {
x: 250,
y: 200,
},
myName: 'aaa'
}),
)

image.addComponent(
new Img({
resource: 'heart'
})
)

game.scene.addChild(image)
const image1 = new GameObject('image1', {
size: { width: 200, height: 200 },
origin: { x: 0, y: 0 },
position: {
x: 100,
y: 100,
},
});

image1.addComponent(
new Img({
resource: 'heart'
})
)
image.addChild(image1);

image1.addComponent(
new Move({
speed: {
x: 250,
y: 200,
},
myName: 'bbb'
}),
)

setTimeout(() => {
image.setActive(false)
console.log('0 0')
}, 1000)

setTimeout(() => {
image1.setActive(false)
console.log('0 0')
}, 1500)

setTimeout(() => {
image.setActive(true)
console.log('1 0')
}, 2000)

setTimeout(() => {
image.setActive(false)
console.log('0 0')
}, 2500)

setTimeout(() => {
try {
image1.setActive(true)
} catch(e) {
console.error(e)
}
console.log('error')
}, 3000)

setTimeout(() => {
image.setActive(true)
console.log('1 0')
}, 3500)

setTimeout(() => {
image1.setActive(true)
console.log('1 1')
}, 4000)

setTimeout(() => {
image.setActive(false)
console.log('0 0')
}, 4500)

setTimeout(() => {
image.setActive(true)
console.log('1 1')
}, 5000)
}

document.addEventListener('visibilitychange', () => {
if (document.hidden) {
game.pause();
} else {
game.resume();
}
});
}
24 changes: 22 additions & 2 deletions packages/eva.js/lib/core/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ export function getComponentName<T extends Component<ComponentParams>>(component
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ComponentParams {}
export interface ComponentParams { }

export interface ComponentConstructor<T extends Component<ComponentParams>> {
componentName: string;
new (params?: ComponentParams): T;
new(params?: ComponentParams): T;
}

/**
Expand All @@ -61,6 +61,8 @@ class Component<T extends ComponentParams = {}> extends EventEmitter {
/** Name of this component */
public readonly name: string;

private _enable = false;

/**
* Represents the status of the component, If component has started, the value is true
* @defaultValue false
Expand All @@ -85,6 +87,20 @@ class Component<T extends ComponentParams = {}> extends EventEmitter {
this.__componentDefaultParams = params;
}

get enable() {
return this._enable;
}

set enable(val: boolean) {
if (this._enable === val) return
this._enable = val;
if (this._enable) {
this.onEnable?.()
} else {
this.onDisable?.()
}
}

/**
* Called during component construction
* @param params - optional initial parameters
Expand All @@ -98,6 +114,8 @@ class Component<T extends ComponentParams = {}> extends EventEmitter {
*/
awake?(): void;

onEnable?(): void;

/**
* Called after all component's `awake` method has been called
* @override
Expand Down Expand Up @@ -131,6 +149,8 @@ class Component<T extends ComponentParams = {}> extends EventEmitter {
*/
onPause?(): void;

onDisable?(): void;

/**
* Called while component be destroyed.
* @override
Expand Down
75 changes: 74 additions & 1 deletion packages/eva.js/lib/core/GameObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class GameObject {
private _name: string;

/** Scene is an abstraction, represent a canvas layer */
private _scene: Scene;
public _scene: Scene;

/** A key-value map for components on this gameObject */
private _componentCache: Record<string, Component<ComponentParams>> = {};
Expand All @@ -32,6 +32,12 @@ class GameObject {
/** GameObject has been destroyed */
public destroyed: boolean = false;

protected _active: boolean = false;

static _needKeepInactiveGameObjects: number[] = []

static _currentProcessGameObjectId: number

/**
* Consruct a new gameObject
* @param name - the name of this gameObject
Expand Down Expand Up @@ -69,6 +75,7 @@ class GameObject {
return this._name;
}


set scene(val: Scene) {
if (this._scene === val) return;
const scene = this._scene;
Expand All @@ -94,6 +101,66 @@ class GameObject {
return this._scene;
}

get active() {
return this._active;
}

_setActive(val) {
const parent = this.transform?.parent?.gameObject
if (val) {
if (this._active === true) return;
if (parent?.active === false) {
throw `Can't make gameObject ${this.name} active, because parent is inactive.`
return
}
const index = GameObject._needKeepInactiveGameObjects.indexOf(this.id)

// 这个元素被直接设置成false了,需要直接设置成true才能通过根据父级变化来变化
if (GameObject._currentProcessGameObjectId !== this.id && index > -1) {
return
}

if (index > -1) {
GameObject._needKeepInactiveGameObjects.splice(index, 1)
}

this._active = true

for (const component of this.components) {
component.enable = true
}
const children = this.transform.children.map(({ gameObject }) => gameObject)
for (const child of children) {
child._setActive(true)
}
} else {
// 直接设置的要放到一个数组里,防止跟随父级变化
if (GameObject._currentProcessGameObjectId === this.id) {
const index = GameObject._needKeepInactiveGameObjects.indexOf(this.id)
if (index === -1) {
GameObject._needKeepInactiveGameObjects.push(this.id)
}
}
if (this._active === false) return;

this._active = false

for (const component of this.components) {
component.enable = false
}
const children = this.transform.children.map(({ gameObject }) => gameObject)
for (const child of children) {
child._setActive(false)
}
}
}
setActive(val) {
if (!this.scene) return
GameObject._currentProcessGameObjectId = this.id
this._setActive(val)
GameObject._currentProcessGameObjectId = undefined
}

/**
* Add child gameObject
* @param gameObject - child gameobject
Expand All @@ -110,6 +177,8 @@ class GameObject {
}
gameObject.transform.parent = this.transform;
gameObject.scene = this.scene;

gameObject.setActive(this.active)
}

/**
Expand Down Expand Up @@ -161,6 +230,10 @@ class GameObject {

component.awake && component.awake();

if (this.active) {
component.onEnable?.()
}

return component;
}

Expand Down
Loading