Appearance
代码示例
单组件
指定的实体在玩家加入游戏时,会广播欢迎语。
typescript
import { Component, GameObject } from "@dao3fun/component";
/**
* @SayComponent - 实体广播组件
*/
class SayComponent extends Component<GameEntity> {
protected Start(): void {
world.onPlayerJoin(({ entity }) => {
this.gameObject.entity.say(`欢迎${entity.player.name}加入游戏`);
});
}
}
const e = world.querySelector("#实体名称");
if (e) {
const gameObject = new GameObject(e);
gameObject.AddComponent(SayComponent);
}多组件挂载
实体在玩家进入游戏时会进行欢迎播报,同时挂载另一个组件使其跳跃。
typescript
import { Component, GameObject } from "@dao3fun/component";
/**
* @SayComponent - 实体广播组件
*/
class SayComponent extends Component<GameEntity> {
protected Start(): void {
world.onPlayerJoin(({ entity }) => {
this.gameObject.entity.say(`欢迎${entity.player.name}加入游戏`);
});
}
}
/**
* @CaperComponent - 物理跳跃组件
*/
class CaperComponent extends Component<GameEntity> {
protected Start(): void {
this.gameObject.entity.velocity.y++;
}
}
const e = world.querySelector("#实体名称");
if (e) {
const gameObject = new GameObject(e);
gameObject.AddComponent(SayComponent);
gameObject.AddComponent(CaperComponent);
}组件继承
通过组件继承,实现单个组件调用父组件的方法。
typescript
import { Component, GameObject } from "@dao3fun/component";
/**
* @CaperComponent - 物理跳跃组件
*/
class CaperComponent extends Component<GameEntity> {
jump() {
this.gameObject.entity.velocity.y++;
}
}
/**
* @SayComponent - 实体广播并跳跃组件
*/
class SayComponent extends CaperComponent {
protected Start(): void {
world.onPlayerJoin(({ entity }) => {
entity.player.onKeyDown(({ keyCode }) => {
if (keyCode === 32) {
this.gameObject.entity.say(
`${entity.player.name}跳起来了,我也要跳一下`
);
this.jump();
}
});
});
}
}
const e = world.querySelector("#实体名称");
if (e) {
const gameObject = new GameObject(e);
gameObject.AddComponent(SayComponent);
}跨游戏对象调用组件
实现两个实体广播,但由单个组件发起。
typescript
import { Component, GameObject } from "@dao3fun/component";
/**
* @CaperComponent 打印组件。
*/
class CaperComponent extends Component<GameEntity> {
Log(str: string): void {
this.gameObject.entity.say(str, {
hideFloat: true,
});
}
}
/**
* @SayComponent 调用其他组件的组件。
*/
class SayComponent extends Component<GameEntity> {
protected Start(): void {
// 调用本身的游戏对象组件
const caperComponent = this.gameObject.GetComponent(CaperComponent);
if (caperComponent) {
caperComponent.Log(`你好,我是${this.gameObject.entity.id}`);
}
// 调用e2的游戏对象组件
const e2Object = GameObject.Find(e2); // 同理: const e2Object = gameObject2;
const e2CaperComponent = e2Object?.GetComponent(CaperComponent);
if (e2CaperComponent) {
e2CaperComponent.Log(
`你好${this.gameObject.entity.id},我是${e2Object?.entity?.id}`
);
}
}
}
// 查询世界中名为"小明"的元素
const e = world.querySelector("#小明");
// 查询世界中名为"小红"的元素
const e2 = world.querySelector("#小红");
// 如果找到了该元素
if (e && e2) {
// 创建一个新的GameObject实例
const gameObject = new GameObject(e);
const gameObject2 = new GameObject(e2);
// 确保 CaperComponent 在 SayComponent 之前挂载
gameObject2.AddComponent(CaperComponent);
gameObject.AddComponent(CaperComponent);
gameObject.AddComponent(SayComponent);
}较复杂的运用
20 个实体随机生成在地图的不同位置,并且每个实体每隔 2 秒跳跃不同高度。10 秒后销毁组件(停止跳跃)。
typescript
import { Component, GameObject } from "@dao3fun/component";
/**
* @CaperComponent - 管理游戏实体的跳跃行为
* 定期使实体进行跳跃,并在总时间达到限制后自我销毁
*/
class CaperComponent extends Component<GameEntity> {
static readonly JUMP_INTERVAL = 2000; // 跳跃间隔时间(毫秒)
static readonly TOTAL_TIME_LIMIT = 10000; // 总时间限制(毫秒)
time = 0;
totalTime = 0;
protected Start(): void {
console.log(
`跳跃组件已挂载到实例${this.gameObject.entity.id ?? "未知实体"}`
);
}
protected Update(deltaTime: number): void {
this.time += deltaTime;
this.totalTime += deltaTime;
if (this.time >= CaperComponent.JUMP_INTERVAL) {
this.up();
this.time = 0;
}
if (this.totalTime >= CaperComponent.TOTAL_TIME_LIMIT) {
this.remove();
}
}
protected OnDestroy(): void {
console.log(
`实例${this.gameObject.entity.id ?? "未知实体"}的跳跃组件已销毁`
);
}
up() {
this.gameObject.entity.velocity.y += getRandomFloat(0, 1.8);
}
remove() {
this.gameObject.RemoveComponent(CaperComponent);
}
}
function getRandomFloat(min: number, max: number): number {
return Math.random() * (max - min) + min;
}
for (let i = 1; i <= 20; i++) {
const e = world.createEntity({
mesh: "mesh/光谱太阳能.vb",
id: `光谱太阳能${i}号`,
meshScale: new GameVector3(0.05, 0.05, 0.05),
friction: 1,
position: new GameVector3(getRandomFloat(1, 55), 9, getRandomFloat(1, 55)),
});
if (e) {
const gameObject = new GameObject(e);
gameObject.AddComponent(CaperComponent);
}
}