最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Three.js 進(jìn)階之旅:物理效果-3D乒乓球小游戲

2023-05-16 19:55 作者:unlexx  | 我要投稿

聲明:本文涉及圖文和模型素材僅用于個(gè)人學(xué)習(xí)、研究和欣賞,請(qǐng)勿二次修改、非法傳播、轉(zhuǎn)載、出版、商用、及進(jìn)行其他獲利行為。


摘要

本文在專(zhuān)欄上一篇內(nèi)容《Three.js 進(jìn)階之旅:物理效果-碰撞和聲音》的基礎(chǔ)上,將使用新的技術(shù)棧?React Three Fiber?和?Cannon.js?來(lái)實(shí)現(xiàn)一個(gè)具有物理特性的小游戲,通過(guò)本文的閱讀,你將學(xué)習(xí)到的知識(shí)點(diǎn)包括:了解什么是?React Three Fiber?及它的相關(guān)生態(tài)、使用?React Three Fiber?搭建基礎(chǔ)三維場(chǎng)景、如何使用新技術(shù)棧給場(chǎng)景中對(duì)象的添加物理特性等,最后利用上述知識(shí)點(diǎn),將開(kāi)發(fā)一個(gè)簡(jiǎn)單的乒乓球小游戲。

效果

在正式學(xué)習(xí)之前,我們先來(lái)看看本文示例最終實(shí)現(xiàn)效果:頁(yè)面主體內(nèi)容是一個(gè)手握乒乓球拍的模型和一個(gè)乒乓球???,對(duì)球拍像現(xiàn)實(shí)生活中一樣進(jìn)行顛球施力操作,乒乓球可以在球拍上彈起,乒乓球彈起的高度隨著施加在球拍上的力的大小的變化而變化,球拍中央顯示的是連續(xù)顛球次數(shù)?5??,當(dāng)乒乓球從球拍掉落時(shí)一局游戲結(jié)束,球拍上的數(shù)字歸零?0?????靵?lái)試試你一次可以顛多少個(gè)球吧???。

打開(kāi)以下鏈接,在線預(yù)覽效果,大屏訪問(wèn)效果更佳。

  • ??????在線預(yù)覽地址:https://dragonir.github.io/physics-pingpong/

本專(zhuān)欄系列代碼托管在?Github?倉(cāng)庫(kù)【threejs-odessey】,后續(xù)所有目錄也都將在此倉(cāng)庫(kù)中更新。

???代碼倉(cāng)庫(kù)地址:git@github.com:dragonir/threejs-odessey.git

原理

React-Three-Fiber

React Three Fiber?是一個(gè)基于?Three.js?的?React?渲染器,簡(jiǎn)稱?R3F。它像是一個(gè)配置器,把?Three.js?的對(duì)象映射為?R3F?中的組件。以下是一些相關(guān)鏈接:

  • 倉(cāng)庫(kù):?https://github.com/pmndrs/react-three-fiber

  • 官網(wǎng):?https://docs.pmnd.rs/react-three-fiber/getting-started/introduction

  • 示例:?https://docs.pmnd.rs/react-three-fiber/getting-started/examples

特點(diǎn)

  • 使用可重用的組件以聲明方式構(gòu)建動(dòng)態(tài)場(chǎng)景圖,使?Three.js?的處理變得更加輕松,并使代碼庫(kù)更加整潔。這些組件對(duì)狀態(tài)變化做出反應(yīng),具有開(kāi)箱即用的交互性。

  • Three.js?中所有內(nèi)容都能在這里運(yùn)行。它不針對(duì)特定的?Three.js?版本,也不需要更新以修改,添加或刪除上游功能。

  • 渲染性能與?Three.js?和?GPU?相仿。組件參與?React?之外的?render loop?時(shí),沒(méi)有任何額外開(kāi)銷(xiāo)。

寫(xiě)?React Three Fiber?比較繁瑣,我們可以寫(xiě)成?R3F?或簡(jiǎn)稱為?Fiber。讓我們從現(xiàn)在開(kāi)始使用?R3F?吧。

生態(tài)系統(tǒng)

R3F?有充滿活力的生態(tài)系統(tǒng),包括各種庫(kù)、輔助工具以及抽象方法:

  • @react-three/drei?– 有用的輔助工具,自身就有豐富的生態(tài)

  • @react-three/gltfjsx?– 將?GLTFs?轉(zhuǎn)換為?JSX?組件

  • @react-three/postprocessing?– 后期處理效果

  • @react-three/test-renderer?– 用于在?Node?中進(jìn)行單元測(cè)試

  • @react-three/flex?–?react-three-fiber?的?flex?盒子布局

  • @react-three/xr?–?VR/AR?控制器和事件

  • @react-three/csg?– 構(gòu)造實(shí)體幾何

  • @react-three/rapier?– 使用?Rapier?的?3D?物理引擎

  • @react-three/cannon?– 使用?Cannon?的?3D?物理引擎

  • @react-three/p2?– 使用?P2?的?2D?物理引擎

  • @react-three/a11y?– 可訪問(wèn)工具

  • @react-three/gpu-pathtracer?– 真實(shí)的路徑追蹤

  • create-r3f-app next?–?nextjs?啟動(dòng)器

  • lamina?– 基于?shader materials?的圖層

  • zustand?– 基于?flux?的狀態(tài)管理

  • jotai?– 基于?atoms?的狀態(tài)管理

  • valtio?– 基于?proxy?的狀態(tài)管理

  • react-spring?– 一個(gè)?spring-physics-based?的動(dòng)畫(huà)庫(kù)

  • framer-motion-3d?–?framer motion,一個(gè)很受歡迎的動(dòng)畫(huà)庫(kù)

  • use-gesture?– 鼠標(biāo)/觸摸手勢(shì)

  • leva?– 創(chuàng)建?GUI?控制器

  • maath?– 數(shù)學(xué)輔助工具

  • miniplex?–?ECS?實(shí)體管理系統(tǒng)

  • composer-suite?– 合成著色器、粒子、特效和游戲機(jī)制、

安裝

第一個(gè)場(chǎng)景

在一個(gè)新建的?React?項(xiàng)目中,我們通過(guò)以下的步驟使用?R3F?來(lái)創(chuàng)建第一個(gè)場(chǎng)景。

初始化Canvas

首先,我們從?@react-three/fiber?引入?Canvas?元素,將其放到?React?樹(shù)中:

Canvas?組件在幕后做了一些重要的初始化工作:

  • 它初始化了一個(gè)場(chǎng)景?Scene?和一個(gè)相機(jī)?Camera,它們都是渲染所需的基本模塊。

  • 它在頁(yè)面每一幀更新中都渲染場(chǎng)景,我們不需要再到頁(yè)面重繪方法中循環(huán)調(diào)用渲染方法。

???Canvas 大小響應(yīng)式自適應(yīng)于父節(jié)點(diǎn),我們可以通過(guò)改變父節(jié)點(diǎn)的寬度和高度來(lái)控制渲染場(chǎng)景的尺寸大小。

添加一個(gè)Mesh組件

為了真正能夠在場(chǎng)景中看到一些物體,現(xiàn)在我們添加一個(gè)小寫(xiě)的?<mesh />?元素,它直接等效于?new THREE.Mesh()。

???可以看到我們沒(méi)有特地去額外引入mesh組件,我們不需要引入任何元素,所有Three.js中的對(duì)象都將被當(dāng)作原生的JSX元素,就像在?ReactDom?中寫(xiě)?<div />?及?<span />?元素一樣。R3F Fiber組件的通用規(guī)則是將Three.js中的它們的名字寫(xiě)成駝峰式的DOM元素即可。

一個(gè)?Mesh?是?Three.js?中的基礎(chǔ)場(chǎng)景對(duì)象,需要給它提供一個(gè)幾何對(duì)象?geometry?以及一個(gè)材質(zhì)?material?來(lái)代表一個(gè)三維空間的幾何形狀,我們將使用一個(gè)?BoxGeometry?和?MeshStandardMaterial?來(lái)創(chuàng)建一個(gè)新的網(wǎng)格?Mesh,它們會(huì)自動(dòng)關(guān)聯(lián)到它們的父節(jié)點(diǎn)。

上述代碼和以下?Three.js?代碼是等價(jià)的:

構(gòu)造函數(shù)參數(shù)

根據(jù)?BoxGeometry?的文檔,我們可以選擇給它傳遞三個(gè)參數(shù):width、length?及?depth

為了實(shí)現(xiàn)相同的功能,我們可以在?R3F?中使用?args?屬性,它總是接受一個(gè)數(shù)組,其項(xiàng)目表示構(gòu)造函數(shù)參數(shù):

添加光源

接著,我們通過(guò)像下面這樣添加光源組件來(lái)為我們的場(chǎng)景添加一些光線。

屬性

這里介紹關(guān)于?R3F?的最后一個(gè)概念,即?React?屬性是如何在?Three.js?對(duì)象中工作的。當(dāng)你給一個(gè)?Fiber?組件設(shè)置任意屬性時(shí),它將對(duì)?Three.js?設(shè)置一個(gè)相同名字的屬性。我們關(guān)注到?ambientLight?上,由它的文檔可知,我們可以選擇?color?和?intensity?屬性來(lái)初始化它:

等價(jià)于

快捷方法

在?Three.js?中對(duì)于很多屬性的設(shè)置如?colors、vectors?等都可以使用?set()?方法進(jìn)行快捷設(shè)置:

在?JSX?中也是相同的:

結(jié)果

查看React Three Fiber完整API文檔

實(shí)現(xiàn)

到這里,我們已經(jīng)掌握了?R3F?的基本知識(shí),我們?cè)俳Y(jié)合專(zhuān)欄上篇關(guān)于物理特性的內(nèi)容,來(lái)實(shí)現(xiàn)如文章開(kāi)頭介紹的乒乓球????小游戲。

???本文乒乓球小游戲基礎(chǔ)版及乒乓球三維模型資源來(lái)源于R3F官網(wǎng)示例。

〇 搭建頁(yè)面基本結(jié)構(gòu)

首先,我們創(chuàng)建一個(gè)?Experience?文件作為渲染三維場(chǎng)景的組件,并在其中添加?Canvas?組件搭建基本頁(yè)面結(jié)構(gòu)。

① 場(chǎng)景初始化

接著我們開(kāi)啟?Canvas?的陰影并設(shè)置相機(jī)參數(shù),然后添加環(huán)境光?ambientLight?和點(diǎn)光源?pointLight?兩種光源:

如果需要修改?Canvas?的背景色,可以在其中添加一個(gè)?color?標(biāo)簽并設(shè)置參數(shù)?attach?為?background,在?args?參數(shù)中設(shè)置顏色即可。

② 添加輔助工具

接著,我們?cè)陧?yè)面頂部引入?Perf,它是?R3F?生態(tài)中查看頁(yè)面性能的組件,它的功能和?Three.js?中?stats.js?是類(lèi)似的,像下面這樣添加到代碼中設(shè)置它的顯示位置,頁(yè)面對(duì)應(yīng)區(qū)域就會(huì)出現(xiàn)可視化的查看工具,在上面可以查看?GPU、CPU、FPS?等性能參數(shù)。

如果想使用網(wǎng)格作為輔助線或用作裝飾,可以使用?gridHelper?組件,它支持配置?positionrotation、args?等參數(shù)。

③ 創(chuàng)建乒乓球和球拍

我們創(chuàng)建一個(gè)名為?PingPong.jsx?的乒乓球組件文件,然后在文件頂部引入以下依賴,其中?Physics、useBox、usePlane、useSphere?用于創(chuàng)建物理世界;useFrame?是用來(lái)進(jìn)行頁(yè)面動(dòng)畫(huà)更新的?hook,它將在頁(yè)面每幀重繪時(shí)執(zhí)行,我們可以在它里面執(zhí)行一些動(dòng)畫(huà)函數(shù)和更新控制器,相當(dāng)于?Three.js?中用原生實(shí)現(xiàn)的?requestAnimationFrame;useLoader?用于加載器的管理,使用它更方便進(jìn)行加載錯(cuò)誤管理和回調(diào)方法執(zhí)行;lerp?是一個(gè)插值運(yùn)算函數(shù),它可以計(jì)算某一數(shù)值到另一數(shù)值的百分比,從而得出一個(gè)新的數(shù)值,常用于移動(dòng)物體、修改透明度、顏色、大小、模擬動(dòng)畫(huà)等。

創(chuàng)建物理世界

然后創(chuàng)建一個(gè)?PingPong?類(lèi),在其中添加?<Physics>?組件來(lái)創(chuàng)建物理世界,像直接使用?Cannon.js?一樣,可以給它設(shè)置?iterations、tolerancegravity、allowSleep?等參數(shù)來(lái)分別設(shè)置物理世界的迭代次數(shù)、容錯(cuò)性、引力以及是否支持進(jìn)入休眠狀態(tài)等,然后在其中添加一個(gè)平面幾何體和一個(gè)平面剛體?ContactGround。

創(chuàng)建乒乓球

接著,我們創(chuàng)建一個(gè)球體類(lèi)?Ball,在其中添加球體????,可以使用前面介紹的?useLoader?來(lái)管理它的貼圖加載,為了方便觀察到乒乓球的轉(zhuǎn)動(dòng)情況,貼圖中央加了一個(gè)十字交叉圖案??。然后將其放在?<Physics>?標(biāo)簽下。

創(chuàng)建球拍

球拍????采用的是一個(gè)?glb?格式的模型,在?Blender?中我們可以看到模型的樣式和詳細(xì)的骨骼結(jié)構(gòu),對(duì)于模型的加載,我們同樣使用?useLoader?來(lái)管理,此時(shí)的加載器需要使用?GLTFLoader。

我們創(chuàng)建一個(gè)?Paddle?類(lèi)并將其添加到?<Physics>?標(biāo)簽中,在這個(gè)類(lèi)中我們實(shí)現(xiàn)模型加載,模型加載完成后綁定骨骼,并在?useFrame?頁(yè)面重繪方法中,根據(jù)鼠標(biāo)所在位置更新乒乓球拍模型的位置?position,并根據(jù)是否一開(kāi)始游戲狀態(tài)以及鼠標(biāo)的位置來(lái)更新球拍的?x軸?和?y軸?方向的?rotation?值。

到這里,我們已經(jīng)實(shí)現(xiàn)乒乓球顛球的基本功能了???

顛球計(jì)數(shù)

為了顯示每次游戲可以顛球的次數(shù),現(xiàn)在我們?cè)谄古仪蚺闹醒爰由蠑?shù)字顯示?5???。我們可以像下面這樣創(chuàng)建一個(gè)?Text?類(lèi),在文件頂部引入?TextGeometry、FontLoaderfontJson?作為字體幾何體、字體加載器以及字體文件,添加一個(gè)?geom?作為創(chuàng)建字體幾何體的方法,當(dāng)?count?狀態(tài)值發(fā)生變化時(shí),實(shí)時(shí)更新創(chuàng)建字體幾何體模型。

然后將?Text?字體類(lèi)放入球拍幾何體中,其中?count?字段需要在物理世界中剛體發(fā)生碰撞時(shí)進(jìn)行更新,該方法加載下節(jié)內(nèi)容添加碰撞音效時(shí)一起實(shí)現(xiàn)。

④ 頁(yè)面裝飾

到這里,整個(gè)小游戲的全部流程都開(kāi)發(fā)完畢了,現(xiàn)在我們來(lái)加一些頁(yè)面提示語(yǔ)、顛球時(shí)的碰撞音效,頁(yè)面的光照效果等,使?3D?場(chǎng)景看起來(lái)更加真實(shí)。

音效

實(shí)現(xiàn)音效????前,我們先像下面這樣添加一個(gè)狀態(tài)管理器????,來(lái)進(jìn)行頁(yè)面全局狀態(tài)的管理。zustand?是一個(gè)輕量級(jí)的狀態(tài)管理庫(kù);_.clamp(number, [lower], upper)?用于返回限制在?lower?和?upper?之間的值;pingSound?是需要播放的音頻文件。我們?cè)谄渲刑砑右粋€(gè)?pong?方法用來(lái)更新音效顛球計(jì)數(shù),添加一個(gè)?reset?方法重置顛球數(shù)字。count?字段表示每次的顛球次數(shù),welcome?表示是否在歡迎界面。

然后我們可以在上述?Paddle?乒乓球拍類(lèi)中像這樣在物體發(fā)生碰撞時(shí)觸發(fā)?pong?方法:

光照

為了是場(chǎng)景更加真實(shí),我們可以開(kāi)啟?Canvas?的陰影,然后添加多種光源????來(lái)優(yōu)化場(chǎng)景,如?spotLight?就能起到視覺(jué)聚焦的作用。

提示語(yǔ)

為了提升小游戲的用戶體驗(yàn),我們可以添加一些頁(yè)面文字提示來(lái)指引使用者和提升頁(yè)面視覺(jué)效果,需要注意的是,這些額外的元素不能添加到?<Canvas />?標(biāo)簽內(nèi)哦???。

???源碼地址:?https://github.com/dragonir/threejs-odessey

總結(jié)

本文中主要包含的知識(shí)點(diǎn)包括:

  • 了解什么是?React Three Fiber?及相關(guān)生態(tài)。

  • React Three Fiber?基礎(chǔ)入門(mén)。

  • 使用?React Three Fiber?開(kāi)發(fā)一個(gè)乒乓球小游戲,學(xué)會(huì)如何場(chǎng)景構(gòu)建、模型加載、物理世界關(guān)聯(lián)、全局狀態(tài)管理等。

想了解其他前端知識(shí)或其他未在本文中詳細(xì)描述的Web 3D開(kāi)發(fā)技術(shù)相關(guān)知識(shí),可閱讀我往期的文章。如果有疑問(wèn)可以在評(píng)論中留言,如果覺(jué)得文章對(duì)你有幫助,不要忘了一鍵三連哦 ??。

附錄

  • [1].??? Three.js 打造繽紛夏日3D夢(mèng)中情島

  • [2].??? Three.js 實(shí)現(xiàn)炫酷的賽博朋克風(fēng)格3D數(shù)字地球大屏

  • [3].??? Three.js 實(shí)現(xiàn)2022冬奧主題3D趣味頁(yè)面,含冰墩墩

  • [4].??? Three.js 實(shí)現(xiàn)3D開(kāi)放世界小游戲:阿貍的多元宇宙

  • [5].??? 掘金1000粉!使用Three.js實(shí)現(xiàn)一個(gè)創(chuàng)意紀(jì)念頁(yè)面

  • 【Three.js 進(jìn)階之旅】系列專(zhuān)欄訪問(wèn) ??

  • 更多往期【3D】專(zhuān)欄訪問(wèn) ??

  • 更多往期【前端】專(zhuān)欄訪問(wèn) ??

參考

  • [1].?React Three Fiber

  • [2].?threejs.org


Three.js 進(jìn)階之旅:物理效果-3D乒乓球小游戲的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
永清县| 阿拉善盟| 高要市| 台北市| 建平县| 深水埗区| 红桥区| 茌平县| 胶州市| 鹤岗市| 湘潭县| 金昌市| 皋兰县| 英超| 行唐县| 东方市| 菏泽市| 怀宁县| 民县| 明星| 阿拉善左旗| 台东市| 屏东市| 梁平县| 成都市| 武汉市| 庆云县| 康保县| 平凉市| 安西县| 青州市| 樟树市| 江津市| 丹江口市| 大竹县| 衡阳市| 新乐市| 常熟市| 延安市| 庆阳市| 太仆寺旗|