搜索
首页web前端js教程用三分,react和webGL构建游戏

Building a Game with Three.js, React and WebGL

核心要点

  • 使用React驱动游戏开发中的3D场景,具有诸多优势,包括清晰地将场景渲染与游戏逻辑分离,易于理解的组件,游戏资源的实时重载,以及能够使用原生浏览器工具将3D场景作为标记进行检查和调试。
  • react-three-renderer (R3R) 提供了一个声明式API,它封装了Three.js,允许将视图代码与游戏逻辑解耦,并创建小型易于理解的组件。
  • 随着游戏引擎的增长,使用reducer模式将游戏逻辑组织成单独的函数至关重要。这种模式允许创建简洁明了的游戏循环,并轻松地向游戏循环添加更多逻辑。
  • 使用Three.js、React和WebGL构建游戏的过程中,调试和性能方面的考虑是独一无二的。使用Chrome DevTools的时间轴功能对于调试性能来说非常宝贵,而实现诸如最小化React中重新渲染次数之类的策略可以帮助优化性能。

我正在制作一款名为“变色龙魅力”的游戏。它使用Three.js、React和WebGL构建。本文介绍了这些技术如何使用react-three-renderer(缩写为R3R)协同工作。

请查看SitePoint上的《WebGL入门指南》和《React和JSX入门指南》,了解React和WebGL的介绍。本文和随附的代码使用ES6语法。

Building a Game with Three.js, React and WebGL

一切的开始

一段时间前,Pete Hunt在#reactjs IRC频道中开了一个玩笑,说要用React来制作游戏:

我敢打赌我们可以用React制作一款第一人称射击游戏!敌人有

等等。我笑了。他也笑了。大家都玩得很开心。“世界上谁会这么做?”我想。

几年后,我做的正是这件事。

Building a Game with Three.js, React and WebGL

《变色龙魅力》是一款收集增强道具的游戏,这些道具会让你缩小以解决无限分形迷宫。我已经做了几年的React开发者,我很想知道是否有办法使用React驱动Three.js。这时,R3R吸引了我的注意。

为什么选择React?

我知道你在想什么:为什么?请容我解释一下。以下是一些考虑使用React驱动3D场景的原因:

  • “声明式”视图允许你清晰地将场景渲染与游戏逻辑分离。
  • 设计易于理解的组件,例如<player></player><wall></wall><level></level>等等。
  • 游戏资源的“热”(实时)重载。更改纹理和模型,并实时查看它们在场景中的更新!
  • 使用原生浏览器工具(如Chrome检查器)将3D场景作为标记进行检查和调试。
  • 使用Webpack在依赖关系图中管理游戏资源,例如<texture require="" src="%7B"></texture>

让我们设置一个场景来了解这一切是如何工作的。

React和WebGL

我创建了一个示例GitHub存储库来配合本文。克隆存储库并按照README中的说明运行代码并继续学习。它以SitePointy 3D机器人为主角!

Building a Game with Three.js, React and WebGL

警告:R3R仍在测试阶段。其API不稳定,将来可能会发生变化。目前它只处理Three.js的一个子集。我发现它足够完整,可以构建一个完整的游戏,但你的结果可能会有所不同。

组织视图代码

使用React驱动WebGL的主要好处是我们的视图代码与游戏逻辑解耦。这意味着我们渲染的实体是小而易于理解的组件。

R3R公开了一个封装Three.js的声明式API。例如,我们可以编写:

<code><scene>></scene>
  <perspectivecamera>    position={ new THREE.Vector3( 1, 1, 1 )
  />
>
</perspectivecamera></code>

现在我们有一个带有摄像机的空3D场景。向场景添加网格就像包含<mesh></mesh>组件并赋予它<geometry></geometry><material></material>一样简单。

<code><scene>></scene>
  …
  <mesh>></mesh>
    <boxgeometry></boxgeometry>      width={ 1 }
      height={ 1 }
      depth={ 1 }
    />
    <meshbasicmaterial></meshbasicmaterial>      color={ 0x00ff00 }
    />
>
</code>

在幕后,这将创建一个THREE.Scene并自动添加一个带有THREE.BoxGeometry的网格。R3R处理旧场景与任何更改的差异。如果你向场景添加一个新的网格,则不会重新创建原始网格。就像使用普通的React和DOM一样,3D场景只更新差异。

因为我们在React中工作,所以我们可以将游戏实体分离到组件文件中。示例存储库中的Robot.js文件演示了如何使用纯React视图代码表示主要角色。它是一个“无状态函数”组件,这意味着它不保存任何本地状态:

<code>const Robot = ({ position, rotation }) => <group></group>  position={ position }
  rotation={ rotation }
>
  <mesh> rotation={ localRotation }></mesh>
    <geometryresource></geometryresource>      resourceId="robotGeometry"
    />
    <materialresource></materialresource>      resourceId="robotTexture"
    />
  >
>;
</code>

现在我们将<robot></robot>包含在我们的3D场景中!

<code><scene>></scene>
  …
  <mesh>></mesh>…>
  <robot></robot>    position={…}
    rotation={…}
  />
>
</code>

你可以在R3R GitHub存储库上查看更多API示例,或者在随附的项目中查看完整的示例设置。

组织游戏逻辑

等式的另一半是处理游戏逻辑。让我们给我们的机器人SitePointy添加一些简单的动画。

Building a Game with Three.js, React and WebGL

传统的游戏循环是如何工作的?它们接受用户输入,分析旧的“世界状态”,并返回新的世界状态以进行渲染。为方便起见,让我们将“游戏状态”对象存储在组件状态中。在一个更成熟的项目中,你可以将游戏状态移动到Redux或Flux存储中。

我们将使用浏览器的requestAnimationFrame API回调来驱动我们的游戏循环,并在GameContainer.js中运行循环。为了动画化机器人,让我们根据传递给requestAnimationFrame的时间戳计算一个新的位置,然后将新的位置存储在状态中。

<code><scene>></scene>
  <perspectivecamera>    position={ new THREE.Vector3( 1, 1, 1 )
  />
>
</perspectivecamera></code>

调用setState()将触发子组件的重新渲染,并更新3D场景。我们将状态从容器组件传递到演示性<game></game>组件:

<code><scene>></scene>
  …
  <mesh>></mesh>
    <boxgeometry></boxgeometry>      width={ 1 }
      height={ 1 }
      depth={ 1 }
    />
    <meshbasicmaterial></meshbasicmaterial>      color={ 0x00ff00 }
    />
>
</code>

我们可以应用一个有用的模式来帮助组织这段代码。更新机器人位置是一个简单的基于时间的计算。将来,它还可能考虑来自先前游戏状态的先前机器人位置。一个接受一些数据、处理它并返回新数据的函数通常被称为reducer。我们可以将移动代码抽象成一个reducer函数!

现在我们可以编写一个简洁明了的游戏循环,其中只包含函数调用:

<code>const Robot = ({ position, rotation }) => <group></group>  position={ position }
  rotation={ rotation }
>
  <mesh> rotation={ localRotation }></mesh>
    <geometryresource></geometryresource>      resourceId="robotGeometry"
    />
    <materialresource></materialresource>      resourceId="robotTexture"
    />
  >
>;
</code>

要向游戏循环添加更多逻辑,例如处理物理,请创建另一个reducer函数并将其传递给先前reducer的结果:

<code><scene>></scene>
  …
  <mesh>></mesh>…>
  <robot></robot>    position={…}
    rotation={…}
  />
>
</code>

随着游戏引擎的增长,将游戏逻辑组织成单独的函数变得至关重要。使用reducer模式,这种组织非常简单。

资源管理

这仍然是R3R的一个发展领域。对于纹理,你可以在JSX标签上指定一个url属性。使用Webpack,你可以要求本地图像路径:

<code>// …
gameLoop( time ) {
  this.setState({
    robotPosition: new THREE.Vector3(
      Math.sin( time * 0.01 ), 0, 0
    )
  });
}
</code>

有了这个设置,如果你更改磁盘上的图像,你的3D场景将实时更新!这对于快速迭代游戏设计和内容非常宝贵。

对于其他资源(如3D模型),你仍然必须使用Three.js的内置加载器(如JSONLoader)来处理它们。我尝试过使用自定义Webpack加载器来加载3D模型文件,但最终工作量太大,没有好处。将模型视为二进制数据并使用文件加载器加载它们更容易。这仍然可以实现模型数据的实时重载。你可以在示例代码中看到这一点。

调试

R3R支持Chrome和Firefox的React开发者工具扩展。你可以像检查普通DOM一样检查你的场景!将鼠标悬停在检查器中的元素上会在场景中显示它们的边界框。你还可以将鼠标悬停在纹理定义上以查看场景中哪些对象使用这些纹理。

Building a Game with Three.js, React and WebGL

你还可以加入react-three-renderer Gitter聊天室,以获得有关调试应用程序的帮助。

性能注意事项

在构建《变色龙魅力》时,我遇到了一些此工作流程特有的性能问题。

  • 我使用Webpack的热重载时间长达30秒!这是因为每次重载都必须将大型资源写入包中。解决方案是实现Webpack的DLLPlugin,这将重载时间缩短到5秒以下。
  • 理想情况下,你的场景每帧渲染应该只调用一次setState()。在分析我的游戏后,React本身是主要的瓶颈。每帧调用setState()多次会导致双重渲染并降低性能。
  • 超过一定数量的对象后,R3R的性能将比普通的Three.js代码差。对我来说,大约是1000个对象。你可以在示例中的“基准测试”中比较R3R和Three.js。

Chrome DevTools的时间轴功能是调试性能的绝佳工具。你可以轻松地直观地检查游戏循环,而且它比DevTools的“配置文件”功能更易于阅读。

就是这样!

查看《变色龙魅力》以了解使用此设置可以实现的功能。虽然此工具链还很年轻,但我发现使用R3R的React对于清晰地组织我的WebGL游戏代码至关重要。你还可以查看小型但不断增长的R3R示例页面,以查看一些组织良好的代码示例。

本文由Mark Brown和Kev Zettler进行同行评审。感谢所有SitePoint的同行评审人员,使SitePoint的内容达到最佳状态!

使用ReactJS和WebGL构建游戏的常见问题解答(FAQ)

使用ReactJS和WebGL构建游戏的先决条件是什么?

要开始使用ReactJS和WebGL构建游戏,你需要对JavaScript、HTML和CSS有基本的了解。还需要了解ReactJS(一个流行的用于构建用户界面的JavaScript库)。此外,了解WebGL(Web图形库)(一个用于渲染交互式3D和2D图形的JavaScript API)至关重要。熟悉ES6语法、npm(Node包管理器)和命令行也将大有裨益。

如何将Unity与ReactJS集成?

可以使用react-unity-webgl包将Unity与ReactJS集成。此包允许你将Unity WebGL构建嵌入到ReactJS应用程序中。你可以使用npm安装它并将其导入到你的项目中。然后,你可以使用包提供的Unity组件将你的Unity游戏嵌入到你的ReactJS应用程序中。

使用React创建3D应用程序的不同方法有哪些?

有几种方法可以使用React创建3D应用程序。最流行的方法之一是使用Three.js,这是一个用于创建和显示动画3D计算机图形的跨浏览器JavaScript库。另一种方法是直接使用WebGL,但这可能更复杂。其他库(如react-three-fiber和react-unity-webgl)也可以用于使用React创建3D应用程序。

如何使用WebGL创建交互式3D图形?

WebGL允许你直接在浏览器中创建交互式3D图形,无需插件。你可以使用WebGL的API创建复杂的3D图形、动画和游戏。但是,WebGL的API是低级的,直接使用可能很复杂。因此,许多开发人员更喜欢使用像Three.js这样的库,这些库为WebGL提供了更高级别的接口。

react-unity-webgl在游戏开发中的作用是什么?

react-unity-webgl包允许你将Unity WebGL构建嵌入到ReactJS应用程序中。这意味着你可以使用Unity创建复杂的3D游戏,然后轻松地将它们集成到你的ReactJS应用程序中。如果你想创建一个基于Web的游戏或交互式3D应用程序,这将特别有用。

如何优化我的ReactJS和WebGL游戏以提高性能?

优化使用ReactJS和WebGL构建的游戏可能涉及多种策略。这些策略包括最小化React中的重新渲染次数,使用WebGL的内置性能功能(如requestAnimationFrame)实现流畅的动画,以及为Web优化3D模型和纹理。

我可以使用ReactJS和WebGL构建手机游戏吗?

是的,你可以使用ReactJS和WebGL构建在移动设备上的Web浏览器中运行的游戏。但是,对于原生移动游戏,你可能需要考虑使用Unity或Unreal Engine等游戏开发平台,这些平台可以直接导出到iOS和Android。

如何在我的ReactJS和WebGL游戏中处理用户输入?

可以使用标准JavaScript事件处理程序在ReactJS和WebGL游戏中处理用户输入。你可以监听键盘、鼠标和触摸事件,然后相应地更新游戏状态。ReactJS还提供合成事件,可以用来以一致的方式跨不同浏览器处理用户输入。

我可以将其他JavaScript库与ReactJS和WebGL一起使用吗?

是的,你可以将其他JavaScript库与ReactJS和WebGL一起使用。例如,你可能会使用Three.js进行3D图形处理,使用Howler.js进行音频处理,或使用Matter.js进行物理处理。关键是确保这些库可以在你的游戏中无缝协同工作。

如何调试我的ReactJS和WebGL游戏?

可以使用Web浏览器中的开发者工具调试使用ReactJS和WebGL构建的游戏。这些工具允许你检查HTML、CSS和JavaScript代码,查看控制台日志,并逐步调试代码。此外,React开发者工具是一个浏览器扩展,允许你检查React组件层次结构、道具和状态。

以上是用三分,react和webGL构建游戏的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10个JQuery Fun and Games插件10个JQuery Fun and Games插件Mar 08, 2025 am 12:42 AM

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

如何创建和发布自己的JavaScript库?如何创建和发布自己的JavaScript库?Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

jQuery视差教程 - 动画标题背景jQuery视差教程 - 动画标题背景Mar 08, 2025 am 12:39 AM

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

使用jQuery和Ajax自动刷新DIV内容使用jQuery和Ajax自动刷新DIV内容Mar 08, 2025 am 12:58 AM

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

Matter.js入门:简介Matter.js入门:简介Mar 08, 2025 am 12:53 AM

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

如何在浏览器中优化JavaScript代码以进行性能?如何在浏览器中优化JavaScript代码以进行性能?Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
2 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器