系列文章目录
前言
前段时间接手了一个项目,里面有一个很有意思的物理交互效果,当时就感觉挺好奇,于是就去网上搜罗了一下有关“JS版物理引擎”的相关资料,主要有以下发现
1.pharse
活跃度不高,但资料相对丰富,主打游戏引擎,感兴趣的可以去"pharse小站"看看。
2.matter.js
网上的资料不多,但入门很轻松,用来实现简单的2D物理交互很适合,听说是基于pharse
3.pixi.js
不是用来做游戏但很适合做游戏的一款图形渲染“引擎”😂
不过以上都是2D的,后来发现以后有可能要涉及3D模型的展示与交互,于是乎,爱好变成了工作😭,一番查找下,找到了这样一款市场占有率似乎还阔以的“three.js”。
一、概念
和大多数的物理引擎一样,three.js 的主要元素主要有摄像机、场景、光源、物体元素以及物体材质,可能是之前接触过3Dmax,这一步走的还算轻松。
二、使用步骤
1.搭建开发环境
首先,使用webpack作为代码编译工具,建立开发环境,由于考虑到原生开发,所以要自己写配置,接受老项目的痛 (╥﹏╥)
代码如下(示例):
yarn init // 初始化项目,根据提示进行配置
yarn add webpack -D //安装webapck
yarn add webpack-cli -D //安装webapck命令行工具
yarn add three // 安装three.js
yarn add path -D // 安装path模块
yarn add fs -D // 安装fs模块
yarn add html-webpack-plugin -D // 安装HtmlWebpackPlugin插件,用来打包html文件
执行完以上命令后,再对webpack进行配置(真的好麻烦,用vue不知道会不会好点)
1. 在项目目录下,创建webpack.config.js 文件,之后写入如下代码
// 引入要用的模块
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 获取页面JS文件
function getSrcJs(path){
let backObject = {}
// 遍历指定路径上的所有文件及子文件夹
fs.readdirSync(path).forEach((file)=>{
const nowPath = path+'/'+file
// fs.statSync 模块用来获取文件的状态,这里用来判断所遍历到的文件是否为子文件夹
if(fs.statSync(nowPath).isDirectory()){
// 如果是则回调本函数遍历该子文件夹,并将获取的结果合并进 backObject 中
Object.assign(backObject,getSrcJs(nowPath))
}else {
// 如果不是则判断是否为JS文件,如果是则添加进 backObject 中
if(/\.js$/.test(file)){
backObject[nowPath.replace(/.js$/,"")] = nowPath
}
}
})
// 返回遍历后的结果
return backObject
}
// 同上,但这里获取的是html文件,通过HtmlWebpackPlugin插件进行打包
function getPage(path){
let backArray = []
fs.readdirSync(path).forEach((file)=>{
const nowPath = path+'/'+file
if(fs.statSync(nowPath).isDirectory()){
backArray.push(...getPage(nowPath))
}else {
if(/\.html$/.test(file)){
backArray.push(new HtmlWebpackPlugin({
template:nowPath, // 类似 output 的 filename
filename:nowPath, // 类似 output 的 path
chunks:[] //设置改html自动引入的js文件,默认引入所有js文件
}))
}
}
})
return backArray
}
module.exports = {
// 开发模式 development 为开发环境 production 为生产环境
mode: "development",
// 打包的入口,及要打包的文件格式为{ 打包后的文件路径及名称 : 打包前的文件路径及名称 }
entry: getSrcJs('./src'),
output: {
// 打包后的文件路径及名称,通过 entry 的配置获取
filename: '[name].js',
// 设置打包后的根目录
path: path.resolve(__dirname,'dist'),
// 清除上一次的打包结果
clean: true
},
plugins: [
// 首页要单独处理,放在根目录下
new HtmlWebpackPlugin({
template: "index.html",
filename:"index.html",
chunks:[]
}),
...getPage('./page') // 打包 html 文件
]
}
完成以上步骤之后,基本的打包配置就完成了,接下来还需要在项目的根目录下创建src和page目录,其中 page 目录中用来存放 html 文件,src 目录用来存放 html 中链接的js文件,其余的工具方法什么的,可以在根目录上创建任意文件夹来完成。这里分别在根目录和js中创建 index.html 和index.js 文件 ,下面贴上一张当前目录的结构图
2.完成配置之后,现在来测试一下 在该项目的命令行中执行 npx webpack 之后就能看到在项目根目录生成的 dist 文件夹, 为了方便快捷,可以在 package.json 中做出如下改动
"scripts": {
"build": "webpack"
}
现在,在命令行中 执行 yarn build 就可以完成打包了(好麻烦,真的好麻烦(╯°□°)╯ ┻━┻)。不过,到这里我们只是实现了基本的打包配置功能,但在实际开发中,我们还需要配置热更新( 真的,╰(*°▽°*)╯超级好用 )。方法很简单,对 package.json 文件做出如下改动。
"dev": "webpack serve"
这样,只需优雅的在命令行中输入 yarn dev 就能愉快(社畜)的敲代码了。
2.配置webpack
虽然在上一步中,成功实现了 webpack 对多页面的打包方案,但是此时的webpack环境只能够实现对js和html文件的解析并打包,如果是实际的应用的话,还需要对webpack进行更多的配置。
1. 首先,先来配置对css文件的打包,先执行如下指令
yarn add style-loader -D
yarn add css-loader -D
在webpack中,仅支持j对js文件打包,如果想要对其它文件打包,只能选择安装相应的加载器。并且,进行在 webpack.config.js 文件中进行配置。如下。
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader',"css-loader"]
}
]
}
其中,test 通常是一个正则,用来匹配文件,use 中则是相应的加载器,webpack 按照倒序进行编译,值得一提的是,在 webpack 的官方文档有提到过对于css文件的加载器,有与其相对应的加载位置的标准,也就是上述的那样。(注:这里的配置,是将css文件打包到代码里,而非打包成独立的文件)
2.依照上述方式,执行如下指令。
yarn add file-loader -D
yarn add babel-loader -D
yarn add @babel/core -D
同样 webpack.config.js 中添加配置
{
test: /\.js$/i,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
use: {
loader: "file-loader",
options: {
name:'[name].[ext]',
outputPath:'asset'
}
}
},
{
test:/\.(glb|gltf|bin)$/i,
use:{
loader: "file-loader",
options: {
name:'[name].[ext]',
outputPath:'models'
}
}
}
这里的 loader 实际上和上一步的 use:[]的方式效果是一样的,之所以按照这样的方式来写,是因 为,这里打包的是 资源文件 需要对其进行特殊配置,使其打包成一个独立的文件,也就是上面里 option 的相关配置,其中 name 表示打包后的文件名称,如果不设置的话,webpack会自动进行命名,outputPath 是打包后的在出口文件夹中的位置。
需要注意的是 由于 node_modules 的特殊性,这里需要使用babel-loader来进行加载,exclude的意思是排除,也就是避免原本的打包机制对其的操作。
注:glb,gltf 是three.js 推荐的导入模型的格式,其中gltf需要与bin文件一同导入才能正常使用。另外 @babel/core 配合babel-loader 使用,不装会报错!
总结
本章节,主要用于实现,多页面格式的 webpack + three.js 的开发环境,东西虽然不多,但啃webpack的配置,真的超麻烦(╯°□°)︵ ┻━┻。