Skip to content

代码示例

单组件

指定的实体在玩家加入游戏时,会广播欢迎语。

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);
  }
}