Threejs系列--20游戏开发--沙漠赛车游戏【点击开始之场景切换】
序言
本章将实现鼠标点击切换场景。
目录结构
资源目录里面的结构不变,点击传送门快速查看。
|__src
|__assets
|__js
| |__base 基础类文件夹
| |__Camera.js 相机类
| |__Resources.js 资源类
| |__geometries 定制的物体类文件夹
| |__AreaFenceBufferGeometry.js 栏栅模型
| |__AreaFloorBorderBufferGeometry.js 进度条几何体
| |__materials 材质类文件夹
| |__Floor.js 地面材质
| |__AreaFence.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 小项目,样式一丢丢
代码一览
Area.js 代码
...
export default class Area extends EventEmitter{
constructor(_options){
super();
...
// 用于判断是否loading加载完毕 执行鼠标移入动画
this.active = _options.active;
// 用于判断是否鼠标移入
this.isIn = false;
...
}
out(){
this.isIn = false;
gsap.killTweensOf(this.fence.mesh.position);
gsap.to(this.fence.mesh.position, { duration: 0.35, ease: "back.out(4)", z: -this.fence.offset });
}
in(){
this.isIn = true;
if (!this.active) return;
gsap.killTweensOf(this.fence.mesh.position);
gsap.to(this.fence.mesh.position, { duration: 0.35, ease: "back.out(3)", z: this.fence.offset });
}
activate(){
this.active = true;
this.isIn && this.in();
}
deactivate(){
this.active = false;
this.isIn && this.out();
}
interact(){
if(!this.active) return;
//点击时取消正在执行的动画 重新执行
gsap.killTweensOf(this.fence.mesh.position);
gsap.killTweensOf(this.floorBorder.material.uniforms.uAlpha);
gsap.killTweensOf(this.fence.material.uniforms.uBorderAlpha);
gsap.to(this.fence.mesh.position, {
duration: 0.05,
z: 0,
onComplete: () => {
gsap.to(this.fence.mesh.position, {duration: 0.25, ease: "back.out(2)", z: 0.5});
gsap.fromTo(this.floorBorder.material.uniforms.uAlpha, {value: 1}, {value: 0.5, duration: 1.5});
gsap.fromTo(this.fence.material.uniforms.uBorderAlpha, {value: 1}, {value: 0.5, duration: 1.5});
}
});
//交互开始
this.trigger('interact');
}
...
}
Areas.js代码
...
export default class Areas {
...
add(_options) {
const area = new Area({
time: this.time,
resources: this.resources,
active: true, //创建的模型默认鼠标移入载入动画
..._options,
});
this.container.add(area.container);
this.items.push(area);
return area;
}
}
index.js代码
setStartingScreen() {
this.startingScreen = {};
this.startingScreen.area = this.areas.add({
position: new THREE.Vector2(0, 0),
halfExtents: new THREE.Vector2(2.35, 1.5),
active: false, //loading加载中 不执行鼠标移入动画
});
...
this.resources.on('ready', () => {
window.requestAnimationFrame(() => {
//此方法控制在loading加载过程中是否可点击 切换页面
this.startingScreen.area.activate();
gsap.to(this.startingScreen.area.floorBorder.material.uniforms.uAlpha, {duration: 0.3, value: 0.3 });
gsap.to(this.startingScreen.loadingLabel.material, {duration: 0.3, opacity: 0});
gsap.to(this.startingScreen.startLabel.material, {duration: 0.3, opacity: 1, delay:0.3});
})
})
// 交互事件 让开始按钮消失
this.startingScreen.area.on('interact', () => {
this.startingScreen.area.deactivate();
gsap.to(this.startingScreen.area.floorBorder.material.uniforms.uProgress, { duration: 0.3, delay: 0.4, value: 0});
gsap.to(this.startingScreen.startLabel.material, {duration: 0.3, delay: 0.4, opacity: 0});
})
}
代码解读
代码不多。实现了鼠标移入开始按钮后,点击按钮,让当前场景消失。
index.js 的setStartingScreen()方法中,在加载完laoding与开始,监听加载结果后,新增了监听交互事件。
Area.js 的interact()方法中,判断可点击后,开始执行需要展示的动画,点击后start的边框白色不透明,栏栅的边框一样,并且触发index中监听的交互事件。