Trò Chơi Pháp Sư

Starter pack

Trong bài học này, chúng ta sẽ kết hợp động cơ VFX với nhiều điều đã học trong khóa học này để tạo ra một trò chơi 3D đơn giản: Một pháp sư chiến đấu với bọn yêu tinh độc ác bằng phép thuật và ma thuật. 🧙‍♂️

Nền tảng vững chắc cho các dự án phát triển trò chơi web của riêng bạn!

Dự Án Khởi Động

Dự án khởi động bao gồm:

Wizard Game Starter Project

Đây là hình dáng của dự án khởi động.

Sẵn sàng để bắt đầu chưa? 🪄

Chào mừng đến với Hogwarts 🏰

Trước khi triển khai bất kỳ loại logic trò chơi nào, hãy luyện tập kỹ năng phép thuật của chúng ta tại Hogwarts bằng cách tạo ra các phép thuật sử dụng động cơ VFX mà chúng ta đã xây dựng trong bài học chuyên biệt.

Giống như chúng ta đã làm trong bài học pháo hoa, chúng ta có thể sử dụng phiên bản đã phát hành của động cơ VFX. Hãy thêm nó vào dự án của chúng ta:

yarn add wawa-vfx@^1.0.0

Bằng cách sử dụng @^1.0.0, chúng ta đảm bảo rằng luôn sử dụng phiên bản chính số 1 của gói nhưng bao gồm các phiên bản phụ và phiên bản vá mới nhất. Cách này, chúng ta có thể tận dụng những tính năng mới nhất và sửa lỗi mà không bị thay đổi đột phá.

Bây giờ trong tệp Magic.jsx, hãy tạo một component <VFXS /> mà sẽ chứa tất cả các component <VFXParticles /> cho dự án của chúng ta.

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],
        }}
      />
  );
};

Và bên cạnh nó là một component Spells sẽ chịu trách nhiệm cho phần render của các phép thuật.

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

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

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

Tôi thích kết hợp nhiều component trong cùng một tệp khi chúng liên quan mật thiết với nhau. Điều này giúp dễ hiểu hơn logic của tệp. Hãy thoải mái tách chúng thành các thư mục/tệp riêng nếu bạn thích.

Hãy chuẩn bị phép thuật đầu tiên của chúng ta, phép thuật Void.

Bùa Thần Rỗng

Hãy tạo một component tên là Void sẽ được render trong component Spells.

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

// ...

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

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

Component VFXEmitter sẽ phát ra các hạt từ emitter sparks mà chúng ta đã tạo trong component VFXS.

Với debug được đặt thành true, chúng ta sẽ có các điều khiển trực quan để định hình hiệu ứng mà chúng ta muốn đạt được.

Tốt, hãy tạo một bùa thần khiến lũ orc phải run sợ!

Một hiệu ứng VFX tốt là sự kết hợp giữa cài đặt đúng và thời điểm chuẩn xác.

Hãy phân tích điều mà chúng ta muốn đạt được với bùa Void.

Trước tiên, chúng ta cần một giai đoạn tích lũy năng lượng. Đây là lúc năng lượng được thu thập trước khi bùa được tung ra. Càng làm tốt phần này, người chơi càng cảm thấy hồi hộp và bùa càng có vẻ mạnh mẽ.

Sự tích lũy của chúng ta sẽ bao gồm:

  • Các hạt phát ra từ từ lên trên
  • Một quả cầu đang lớn dần
  • Những ký tự rune xoay tròn trên sàn cứ như bùa đang được phát động

Sau đó, chúng ta muốn có giai đoạn bùng nổ. Đây là lúc bùa được tung ra và năng lượng được giải phóng. Làm phần này càng tốt thì người chơi càng thấy thỏa mãn.

Giai đoạn bùng nổ của chúng ta sẽ bao gồm:

  • Quả cầu nổ tung (làm nó biến mất)
  • Các hạt đi theo mọi hướng

Và cho mỗi hiệu ứng hình ảnh, chúng ta sẽ thêm hiệu ứng âm thanh để tăng tính nhập vai.

Hãy chơi với các cài đặt của component VFXEmitter để đạt được hiệu ứng mong muốn cho các hạt tích lũy.

Đây là những gì tôi đã tạo ra:

<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],
  }}
/>

Chúng ta có thể thấy các hạt từ từ bay lên.

Thay vì dùng các hạt vuông, hãy sử dụng các hình tam giác. Để làm điều này, chúng ta có thể sử dụng hình nón với các cài đặt thích hợp.

// ...

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],
        }}
      />
    </>
  );
};

// ...

Các hạt trông như những hình tam giác bây giờ.

Bây giờ hãy thêm quả cầu đang lớn dần. Để làm điều này, chúng ta cần thêm một component VFXParticles mới vào component VFXS:

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],
        }}
      />
    </>
  );
};

Bằng cách đặt fadeSize thành [0.7, 0.9], chúng ta làm cho quả cầu lớn dần một cách chậm rãi cho đến 70% thời gian sống của nó và sau đó nhanh chóng biến mất trong 10% còn lại.

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.