您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

Threejs系列--18游戏开发--沙漠赛车游戏【loading资源加载进度条】

Threejs系列--18游戏开发--沙漠赛车游戏【loading资源加载进度条】

  • 序言
  • 目录结构
  • 代码一览
    • AreaFloorBorderBufferGeometry.js代码
    • AreaFloorBorder.js代码
    • Area.js代码
    • Areas.js代码
    • index.js代码
  • 代码解读
  • 运行结果

序言

本章将实现loading加载资源进度条。

目录结构

资源目录里面的结构不变,点击传送门快速查看。

|__src
	|__assets
	|__js
	|	|__base		基础类文件夹
	|		|__Camera.js 相机类	
	|		|__Resources.js 资源类 
	|	|__geometries	定制的物体类文件夹
	|		|__AreaFloorBorderBufferGeometry.js 进度条几何体  【新增】
	|	|__materials	材质类文件夹
	|		|__Floor.js 地面材质
	|		|__AreaFloorBorder.js 进度条着色器  【新增】
	|	|__passes	合成器通道文件夹
	|		|__Blur.js	  模糊着色器
	|		|__Glows.js		发光着色器
	|	|__utils	工具类文件夹
	|		|__Sizes.js  画布大小控制类
	|		|__EventEmitter.js 基础事件处理器
	|		|__Time.js  动画刷新
	|		|__Loader.js 加载器 
	|	|__world	精灵类文件夹
	|		|__Area.js	区域基础类  【新增--基础实现】
	|		|__Areas.js	区域管理类  【新增--管理各个区域】
	|		|__index.js	精灵类	【新增--进度条导入与切换】
	|		|__Floor.js 地面类
	|	|__Application.js	初始化游戏的文件 
	|__index.js		入口
	|__index.css  	小项目,样式一丢丢

代码一览

AreaFloorBorderBufferGeometry.js代码

import * as THREE from "three";

/**
* 自定义进度条几何体
*/
class AreaFloorBorderBufferGeometry {
  constructor(_width, _height, _thickness) {
    this.parameters = {
      width: _width,
      height: _height,
      thickness: _thickness,
    };

    this.type = "AreaFloorBufferGeometry";

    const length = 8;

    const vertices = new Float32Array(length * 3);
    const indices = new Uint32Array(length * 6);

    const outerWidth = _width;
    const outerHeight = _height;

    const innerWidth = outerWidth - _thickness;
    const innerHeight = outerHeight - _thickness;

    // Vertices
    vertices[0 * 3 + 0] = innerWidth * 0.5;
    vertices[0 * 3 + 1] = innerHeight * 0.5;
    vertices[0 * 3 + 2] = 0;

    vertices[1 * 3 + 0] = innerWidth * 0.5;
    vertices[1 * 3 + 1] = -innerHeight * 0.5;
    vertices[1 * 3 + 2] = 0;

    vertices[2 * 3 + 0] = -innerWidth * 0.5;
    vertices[2 * 3 + 1] = -innerHeight * 0.5;
    vertices[2 * 3 + 2] = 0;

    vertices[3 * 3 + 0] = -innerWidth * 0.5;
    vertices[3 * 3 + 1] = innerHeight * 0.5;
    vertices[3 * 3 + 2] = 0;

    vertices[4 * 3 + 0] = outerWidth * 0.5;
    vertices[4 * 3 + 1] = outerHeight * 0.5;
    vertices[4 * 3 + 2] = 0;

    vertices[5 * 3 + 0] = outerWidth * 0.5;
    vertices[5 * 3 + 1] = -outerHeight * 0.5;
    vertices[5 * 3 + 2] = 0;

    vertices[6 * 3 + 0] = -outerWidth * 0.5;
    vertices[6 * 3 + 1] = -outerHeight * 0.5;
    vertices[6 * 3 + 2] = 0;

    vertices[7 * 3 + 0] = -outerWidth * 0.5;
    vertices[7 * 3 + 1] = outerHeight * 0.5;
    vertices[7 * 3 + 2] = 0;

    // Index
    indices[0 * 3 + 0] = 4;
    indices[0 * 3 + 1] = 0;
    indices[0 * 3 + 2] = 1;

    indices[1 * 3 + 0] = 1;
    indices[1 * 3 + 1] = 5;
    indices[1 * 3 + 2] = 4;

    indices[2 * 3 + 0] = 5;
    indices[2 * 3 + 1] = 1;
    indices[2 * 3 + 2] = 2;

    indices[3 * 3 + 0] = 2;
    indices[3 * 3 + 1] = 6;
    indices[3 * 3 + 2] = 5;

    indices[4 * 3 + 0] = 6;
    indices[4 * 3 + 1] = 2;
    indices[4 * 3 + 2] = 3;

    indices[5 * 3 + 0] = 3;
    indices[5 * 3 + 1] = 7;
    indices[5 * 3 + 2] = 6;

    indices[6 * 3 + 0] = 7;
    indices[6 * 3 + 1] = 3;
    indices[6 * 3 + 2] = 0;

    indices[7 * 3 + 0] = 0;
    indices[7 * 3 + 1] = 4;
    indices[7 * 3 + 2] = 7;

    const geometry = new THREE.BufferGeometry();

    geometry.setIndex(new THREE.BufferAttribute(indices, 1, false));

    geometry.setAttribute(
      "position",
      new THREE.Float32BufferAttribute(vertices, 3)
    );

    return geometry;
  }
}

export default AreaFloorBorderBufferGeometry;

AreaFloorBorder.js代码

import * as THREE from "three";

import shaderFragment from "../../assets/shaders/areaFloorBorder/fragment.glsl";
import shaderVertex from "../../assets/shaders/areaFloorBorder/vertex.glsl";

/**
* 进度条着色器
*/
export default function () {
  const uniforms = {
    uColor: { value: null },
    uAlpha: { value: null },
    uLoadProgress: { value: null },
    uProgress: { value: null },
  };

  const material = new THREE.ShaderMaterial({
    wireframe: false,
    transparent: true,
    depthTest: true,
    depthWrite: false,
    uniforms,
    vertexShader: shaderVertex,
    fragmentShader: shaderFragment,
  });

  return material;
}

Area.js代码

import * as THREE from 'three';
import EventEmitter from "../utils/EventEmitter";

import AreaFloorBorderBufferGeometry from '../geometries/AreaFloorBorderBufferGeometry';
import AreaFloorBorderMaterial from '../materials/AreaFloorBorder';

/**
* 区域类
*/
export default class Area extends EventEmitter{
    constructor(_options){
        super();

        this.position = _options.position;
        this.halfExtents = _options.halfExtents;

        this.container = new THREE.Object3D();
        this.container.position.x = this.position.x;
        this.container.position.y = this.position.y;
        this.container.matrixAutoUpdate = false;
        this.container.updateMatrix();

        this.setFloorBorder();
    }

    setFloorBorder(){
        this.floorBorder = {};
		//创建进度条
        this.floorBorder.geometry = new AreaFloorBorderBufferGeometry(
            this.halfExtents.x * 2,
            this.halfExtents.y * 2,
            0.25
        );
        this.floorBorder.material = new AreaFloorBorderMaterial();
        this.floorBorder.material.uniforms.uColor.value = new THREE.Color(0xffffff);
        this.floorBorder.material.uniforms.uAlpha.value = 1;
        this.floorBorder.material.uniforms.uLoadProgress.value = 1;
        this.floorBorder.material.uniforms.uProgress.value = 1;
        
        this.floorBorder.mesh = new THREE.Mesh(this.floorBorder.geometry, this.floorBorder.material);
        console.log(this.floorBorder.geometry)
        this.floorBorder.mesh.matrixAutoUpdate = false;
        this.container.add(this.floorBorder.mesh);
    }
}

Areas.js代码

import * as THREE from 'three';
import Area from "./Area";

/**
* 区域管理
*/
export default class Areas {
    constructor(_options) {
        this.resources = _options.resources;

        this.container = new THREE.Object3D();
        this.container.matrixAutoUpdate = false;
    }

    add(_options) {
        const area = new Area({
            resources: this.resources,
            ..._options,
        });

        this.container.add(area.container);

        return area;
    }
}

index.js代码

import * as THREE from "three";
import gsap from "gsap";
import Floor from "./Floor.js";
import Areas from "./Areas.js";

export default class {
    constructor(_options){
        ...

        //设置世界中的区域加载
        this.setAreas();

        //设置启动屏
        this.setStartingScreen();
    }

    setStartingScreen() {
        this.startingScreen = {};
        
        this.startingScreen.area = this.areas.add({
            position: new THREE.Vector2(0, 0),
            halfExtents: new THREE.Vector2(2.35, 1.5),
        });

        ...
        
        this.resources.on('progress', _progress => {
            this.startingScreen.area.floorBorder.material.uniforms.uAlpha.value = 1;
            this.startingScreen.area.floorBorder.material.uniforms.uLoadProgress.value = _progress;
        })
        
        this.resources.on('ready', () => {
            window.requestAnimationFrame(() => {
                gsap.to(this.startingScreen.area.floorBorder.material.uniforms.uAlpha, {duration: 0.3, value: 0.3 });
                ...
            })
        })
    }

   ...

    setAreas(){
        this.areas = new Areas({
            resources: this.resources
        })
        this.container.add(this.areas.container)
    }
}

代码解读

AreaFloorBorderBufferGeometry.js自定义了需要的进度条
AreaFloorBorder.js使用自定义的着色器渲染材质
Area.js合成自定义的进度条
Areas.js统一管理区块【进度条也是一个区块】
index.js导入Areas,使用进度条,根据资源加载进度,控制参数变化

运行结果

在这里插入图片描述


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进