Threejs系列--7游戲開發加載glb模型之牛刀小試
- 終極效果展示
- 開發環境搭建
- 目錄結構
- 重要依賴
- 代碼
- html模板內容
- main.ts游戲主場景
- role.ts角色構建
- helper.ts輔助線
- events.ts事件
- 代碼運行
- 作者的話
終極效果展示
目標如下,先來熟悉下threejs吧~~

開發環境搭建
- emmmmmm ~~~ 一臺非常攢勁的電腦
- 編輯器vscode
- js運行環境nodejs
- 瀏覽器chrome
目錄結構
|-- src 源代碼
|-- assets 資源目錄
|-- model
|-- 630cfe7e8388bff5bfda6692ce4ca40b.glb 一看就是網上隨便巴拉的檔案^^
|-- js 核心目錄
|-- events.ts 事件
|-- helper.ts 輔助工具
|-- role.ts 角色
|-- main.ts 游戲主場景
|-- index.ts 入口檔案
|-- index.html 模板檔案
|-- webpack.config.js webpack配置
重要依賴
//通過npm直接下載
"dependencies": {
"three": "^0.134.0"
},
"devDependencies": {
"@types/three": "^0.133.1",
"copy-webpack-plugin": "^9.0.1",
"html-webpack-plugin": "^5.5.0",
"ts-loader": "^9.2.6",
"typescript": "^4.4.4",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0"
}
代碼
html模板內容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {margin: 0; padding: 0;}
html,body,#webgl {height: 100%;}
body {overflow: hidden;}
</style>
</head>
<body>
<canvas id="webgl"></canvas>
</body>
</html>
main.ts游戲主場景
import * as THREE from 'three';
import LightHelper from './helper';
export default class Main {
public mesh: THREE.Mesh;
public scene: THREE.Scene;
public camera: THREE.PerspectiveCamera;
public renderer: THREE.WebGLRenderer;
private geometry: THREE.PlaneGeometry;
private material: THREE.Material;
public width: number = window.innerWidth;
public height: number = window.innerHeight;
constructor() {
this.initScent();
this.createGeometry();
this.setCamera();
this.setLight();
this.setRenderer();
}
createGeometry() {
this.geometry = new THREE.PlaneGeometry(600, 600);
this.material = new THREE.MeshLambertMaterial({
color: 0xeaeaea,
side: THREE.DoubleSide
});
//網格模型
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.rotation.x = -Math.PI / 2;
this.mesh.position.x = Math.PI/2
this.mesh.receiveShadow = true;
this.scene.add(this.mesh);
}
initScent() {
//創建場景
this.scene = new THREE.Scene();
}
setCamera() {
const k: number = this.width / this.height;
const s: number = 75;
//創建相機物件
this.camera = new THREE.PerspectiveCamera(s, this.width / this.height, 0.1, 10000);
this.camera.position.set(0, 300, 400);
this.camera.lookAt(this.scene.position);
}
setLight() {
const offset = 160
const Helper:LightHelper = new LightHelper(this.scene);
//頭頂四方四盞燈 增加無盡神秘感
Array(4).fill(0).forEach((item: any, index: number) => {
//燈光與位置
let spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.x = index>1 ? (index%2?offset:~offset) : 0;
spotLight.position.z = index<2 ? (index%2?offset:~offset) : 0;
spotLight.position.y = 400
//陰影與大小
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1200;
spotLight.shadow.mapSize.height = 1200;
//載入場景
this.scene.add( spotLight );
Helper.spointLightHelper(spotLight);
})
}
setRenderer() {
//渲染器
this.renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('webgl'),
antialias: true,
alpha: true
});
this.renderer.setSize(this.width, this.height);//設定渲染區域尺寸
this.renderer.setClearColor(0xb9d3ff, 1); //設定背景顏色
this.renderer.shadowMap.enabled = true;
}
render() {
this.renderer.render(this.scene,this.camera);//執行渲染操作
}
}
role.ts角色構建
import * as THREE from 'three';
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader';
import Main from './main'
export default class Role {
main: Main;
mixer: THREE.AnimationMixer = null;
constructor(main: Main) {
this.main = main;
this.loader();
}
loader() {
// const loader = new FBXLoader();//創建一個FBX加載器
const loader = new GLTFLoader();//創建一個GLTF加載器
var dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'draco/' );
loader.setDRACOLoader( dracoLoader );
loader.load('model/630cfe7e8388bff5bfda6692ce4ca40b.glb', (obj) => {
obj.scene.traverse( child => {
if (child.type == 'Mesh') {
child.castShadow = true
child.receiveShadow = true
}
})
obj.scene.receiveShadow = true
obj.scene.rotation.x = - Math.PI / 2
this.main.scene.add(obj.scene)
//this.mixer = new THREE.AnimationMixer(obj);
//AnimationAction.play();//播放影片
})
}
}
helper.ts輔助線
import * as THREE from 'three';
export default class LightHelper {
private scene: THREE.Scene;
constructor(scene: THREE.Scene) {
this.scene = scene;
}
/**
* 聚光燈輔助線
*/
spointLightHelper(spotLight: THREE.SpotLight) {
var sphereSize = 1;
var spointLightHelper = new THREE.PointLightHelper( spotLight, sphereSize );
this.scene.add( spointLightHelper );
}
}
events.ts事件
import Main from './main'
export default class Events {
main: Main;
constructor(main: Main) {
this.main = main;
window.addEventListener('resize', this.resize.bind(this));
window.addEventListener('dblclick', this.fullScreen.bind(this));
}
resize() {
this.main.camera.aspect = window.innerWidth / window.innerHeight;
this.main.camera.updateProjectionMatrix();
this.main.renderer.setSize(window.innerWidth, window.innerHeight);
}
fullScreen() {
if(document.fullscreen) {
document.exitFullscreen();
}else{
document.documentElement.requestFullscreen();
}
}
}
代碼運行
專案根目錄下執行 webpack
作者的話
emmm~~ 準備作業已經完成,順便熟悉了程式,下節將開始正式的游戲開發,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/355348.html
標籤:其他
