魔法师游戏

Starter pack

在这节课中,我们将结合我们的 VFX 引擎与本课程中学到的许多知识来创建一个简单的 3D 游戏:一个使用法术和魔法与邪恶兽人作战的魔法师。🧙‍♂️

为您自己的网页游戏开发项目打下坚实基础!

启动项目

启动项目包含:

魔法师游戏启动项目

启动项目的外观如下所示。

准备开始了吗?🪄

欢迎来到霍格沃茨 🏰

在实现任何游戏逻辑之前,让我们通过在霍格沃茨练习魔法技能来创造使用我们在专门课程中构建的VFX引擎的咒语。

正如我们在烟花课程中所做的那样,我们可以使用VFX引擎的发布版本。让我们将其添加到我们的项目中:

yarn add wawa-vfx@^1.0.0

通过使用 @^1.0.0,我们确保始终使用包的主要版本1,但包括最新的小版本和补丁版本。这样,我们可以在不发生破坏性更改的情况下受益于最新的功能和错误修复。

现在在 Magic.jsx 文件中,让我们创建一个 <VFXS /> 组件来包含我们项目中的所有 <VFXParticles /> 组件。

import { VFXParticles } from "wawa-vfx";

export const Magic = ({ ...props }) => {
  // ...

  return (
    <group {...props}>
      <VFXS />
      {/* ... */}
    </group>
  );
};

const VFXS = () => {
  return (
    <>
      <VFXParticles
        name="sparks"
        settings={{
          nbParticles: 100000,
          renderMode: "billboard",
          intensity: 3,
          fadeSize: [0.1, 0.1],
        }}
      />
  );
};

接下来是一个 Spells 组件,它将包含我们咒语的渲染部分。

// ...
export const Magic = ({ ...props }) => {
  // ...

  return (
    <group {...props}>
      <VFXS />
      <Spells />
      {/* ... */}
    </group>
  );
};

const Spells = () => {
  return <></>;
};

我喜欢将多个组件混合在同一个文件中,当它们关系紧密时。这使得理解文件的逻辑变得更容易。如果你愿意,可以将它们分成单独的文件夹/文件。

让我们准备我们的第一个咒语,Void 咒语。

Void Spell

让我们创建一个名为 Void 的组件,该组件将在 Spells 组件中渲染。

// ...
import { VFXEmitter } from "wawa-vfx";

// ...

const Spells = () => {
  return (
    <>
      <Void />
    </>
  );
};

const Void = ({ ...props }) => {
  return (
    <group {...props}>
      <VFXEmitter debug emitter="sparks" />
    </group>
  );
};

VFXEmitter 组件将从我们在 VFXS 组件中创建的 sparks 发射器发射粒子。

debug 设置为 true,我们将拥有可视化控件以塑造我们想要实现的效果。

好的,让我们创造一个让兽人颤抖的法术!

一个好的 VFX 效果是正确设置和正确时机的结合。

让我们分解一下我们希望通过 Void 法术实现的目标。

首先,我们需要一个能量蓄积阶段。这是施法前能量聚集的时刻。做好这一步,玩家会感受到更多的期待,法术看起来会更强大。

我们的能量蓄积将包括:

  • 粒子缓慢向上发射
  • 增大中的球体
  • 地板上旋转的符文仿佛法术正在施展

然后,我们需要爆发阶段。这是法术施放和能量释放的时刻。做好这一步,玩家会感受到更加满足。

我们的爆发将包括:

  • 球体爆炸(使其消失)
  • 粒子向各个方向扩散

对于每个视觉效果,我们将添加一个声音效果以使其更加沉浸。

让我们调整 VFXEmitter 组件的设置,以实现能量蓄积阶段粒子的期望效果。

这是我想到的设置:

<VFXEmitter
  emitter="sparks"
  settings={{
    duration: 0.5,
    delay: 0,
    nbParticles: 20,
    spawnMode: "time",
    loop: false,
    startPositionMin: [-0.5, 0, -0.5],
    startPositionMax: [0.5, 1, 0.5],
    startRotationMin: [0, 0, 0],
    startRotationMax: [0, 0, 0],
    particlesLifetime: [0.5, 1],
    speed: [0, 1],
    directionMin: [0, 0, 0],
    directionMax: [0, 0.1, 0],
    rotationSpeedMin: [0, 0, 0],
    rotationSpeedMax: [0, 0, 0],
    colorStart: ["#4902ff"],
    colorEnd: ["#ffffff"],
    size: [0.1, 0.4],
  }}
/>

我们可以看到粒子缓慢向上移动。

让我们使用三角形而不是方形粒子。为此,我们可以使用具有适当设置的 cone geometry

// ...

const VFXS = () => {
  return (
    <>
      <VFXParticles
        name="sparks"
        geometry={<coneGeometry args={[0.5, 1, 8, 1]} />}
        settings={{
          nbParticles: 100000,
          renderMode: "billboard",
          intensity: 3,
          fadeSize: [0.1, 0.1],
        }}
      />
    </>
  );
};

// ...

现在粒子看起来像三角形。

接下来让我们添加增大的球体。为此,我们需要向 VFXS 组件添加一个新的 VFXParticles 组件:

const VFXS = () => {
  return (
    <>
      {/* ... */}
      <VFXParticles
        name="spheres"
        geometry={<sphereGeometry args={[1, 32, 32]} />}
        settings={{
          nbParticles: 1000,
          renderMode: "mesh",
          intensity: 5,
          fadeSize: [0.7, 0.9],
          fadeAlpha: [0, 1],
        }}
      />
    </>
  );
};

通过将 fadeSize 设置为 [0.7, 0.9],我们让球体在其生命周期的 70% 慢慢增大,然后在最后的 10% 快速消失。

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.