web实践学习3
web实践学习3
20201303张奕博 2023.1.26
创建树
从预览动图和页面可以看到,浮岛上共有两种树 ,绿色的高树和粉红色的矮树,树的实现也非常简单,是使用了两个 BoxBufferGeometry 拼接到一起。类 Tree 和 LeafTree 分别用于生成这两种树木,接收参数 (x, y, z) 分别表示树木在场景中的位置信息。我们可以在 Island 辅导上添加一些树木,构成浮岛上的一片小森林。
export default class Tree {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.treeMesh = new THREE.Group();
this.generate();
}
generate() {
// 树干
var trunkMat = new THREE.MeshLambertMaterial({
color: 0x543b14,
side: THREE.DoubleSide
});
var trunkGeom = new THREE.BoxBufferGeometry(20, 200, 20);
this.trunkMesh = new THREE.Mesh(trunkGeom, trunkMat);
// 树叶
var leavesMat = new THREE.MeshLambertMaterial({
color: 0x016316,
side: THREE.DoubleSide
});
var leavesGeom = new THREE.BoxBufferGeometry(80, 400, 80);
this.leavesMesh = new THREE.Mesh(leavesGeom, leavesMat);
this.treeMesh.add(this.trunkMesh);
this.treeMesh.add(this.leavesMesh);
this.treeMesh.position.set(this.x, this.y, this.z);
// ...
}
}
矮树
export default class LeafTree {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.treeMesh = new THREE.Group();
this.generate();
}
generate() {
// ...
}
}
创建胡萝卜
接着,在地面上添加一些胡萝卜 。胡萝卜身体部分是通过四棱柱 CylinderBufferGeometry 实现的,然后通过 BoxBufferGeometry 立方体来实现胡萝卜的两片叶子。场景中可以通过 Carrot 类来添加胡萝卜,本页面示例中是通过循环调用添加了 20 个随机位置的胡萝卜。
export default class Carrot {
constructor() {
this.carrotMesh = new THREE.Group();
this.generate();
}
generate() {
const carrotMat = new THREE.MeshLambertMaterial({
color: 0xd9721e
});
const leafMat = new THREE.MeshLambertMaterial({
color: 0x339e33
});
// 身体
const bodyGeom = new THREE.CylinderBufferGeometry(5, 3, 12, 4, 1);
this.body = new THREE.Mesh(bodyGeom, carrotMat);
// 叶子
const leafGeom = new THREE.BoxBufferGeometry(5, 10, 1, 1);
this.leaf1 = new THREE.Mesh(leafGeom, leafMat);
this.leaf2 = this.leaf1.clone();
// ...
this.carrotMesh.add(this.body);
this.carrotMesh.add(this.leaf1);
this.carrotMesh.add(this.leaf2);
}
};
for (let i = 0; i < 20; i++) {
carrot[i] = new Carrot();
scene.add(carrot[i].carrotMesh);
carrot[i].carrotMesh.position.set(-170 * Math.random() * 3 - 300, -12, 1400 * Math.random() * 1.2 - 900);
}
创建兔子
最后,来创建页面的主角兔子 。兔子全部都是由立方体 BoxBufferGeometry 搭建而成的,整体可以分解为头、眼睛、耳朵、鼻子、嘴、胡须、身体、尾巴、四肢等构成,构建兔子时的核心要素就是各个立方体位置和缩放比例的调整,需要具备一定的审美能力,当然本例中使用的兔子是在 Three.js 社区开源代码的基础上改造的 。
完成兔子的整体外形之后,我们通过 gsap 给兔子添加一些运动动画效果和方法以供外部调用,其中 blink() 方法用于眨眼、jump() 方法用于原地跳跃、nod() 方法用于点头、run() 方法用于奔跑、fall() 方法用于边界检测时检测到超出运动范围时使兔子坠落效果等。完成 Rabbit 类后,我们就可以在场景中初始化小兔子。
import { TweenMax, Power0, Power1, Power4, Elastic, Back } from 'gsap';
export default class Rabbit {
constructor() {
this.bodyInitPositions = [];
this.runningCycle = 0;
this.rabbitMesh = new THREE.Group();
this.bodyMesh = new THREE.Group();
this.headMesh = new THREE.Group();
this.generate();
}
generate() {
var bodyMat = new THREE.MeshLambertMaterial({
color: 0x5c6363
});
var tailMat = new THREE.MeshLambertMaterial({
color: 0xc2bebe
});
var nouseMat = new THREE.MeshLambertMaterial({
color: 0xed716d
});
// ...
var pawMat = new THREE.MeshLambertMaterial({
color: 0xbf6970
});
var bodyGeom = new THREE.BoxBufferGeometry(50, 50, 42, 1);
var headGeom = new THREE.BoxBufferGeometry(44, 44, 54, 1);
var earGeom = new THREE.BoxBufferGeometry(5, 60, 10, 1);
var eyeGeom = new THREE.BoxBufferGeometry(20, 20, 8, 1);
var irisGeom = new THREE.BoxBufferGeometry(8, 8, 8, 1);
var mouthGeom = new THREE.BoxBufferGeometry(8, 16, 4, 1);
var mustacheGeom = new THREE.BoxBufferGeometry(0.5, 1, 22, 1);
var spotGeom = new THREE.BoxBufferGeometry(1, 1, 1, 1);
var legGeom = new THREE.BoxBufferGeometry(33, 33, 10, 1);
var pawGeom = new THREE.BoxBufferGeometry(45, 10, 10, 1);
var pawFGeom = new THREE.BoxBufferGeometry(20, 20, 20, 1);
var tailGeom = new THREE.BoxBufferGeometry(20, 20, 20, 1);
var nouseGeom = new THREE.BoxBufferGeometry(20, 20, 15, 1);
var tailGeom = new THREE.BoxBufferGeometry(23, 23, 23, 1);
this.body = new THREE.Mesh(bodyGeom, bodyMat);
this.bodyMesh.add(this.body);
this.head = new THREE.Mesh(headGeom, bodyMat);
this.bodyMesh.add(this.legL);
this.headMesh.add(this.earR);
this.rabbitMesh.add(this.bodyMesh);
this.rabbitMesh.add(this.headMesh);
// ...
}
blink() {
var sp = 0.5 + Math.random();
if (Math.random() > 0.2)
TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp / 8, {
y: 0,
ease: Power1.easeInOut,
yoyo: true,
repeat: 3
});
}
// 跳跃
jump() {
var speed = 10;
var totalSpeed = 10 / speed;
var jumpHeight = 150;
TweenMax.to(this.earL.rotation, totalSpeed / 2, {
z: "+=.3",
ease: Back.easeOut,
yoyo: true,
repeat: 1
});
TweenMax.to(this.earR.rotation, totalSpeed / 2, {
z: "-=.3",
ease: Back.easeOut,
yoyo: true,
repeat: 1
});
// ...
}
// 点头
nod() {}
// 奔跑
run() {}
// 移动
move() {}
// 坠落
fall() {}
// 动作销毁
killNod() {}
killJump() {}
killMove() {}
}
web实践学习3的更多相关文章
- 零基础从实践出发学java编程【总结篇】
1.背景 很多人学习java的第一步就是系统的学习java基础语法,有的java基础语法还没学完就崩溃了,确实java基础语法太多太细,而且都是理论,学着让人很懵: 好不容易学完基础语法,又要学框架. ...
- 20145316《网络对抗》Exp9 Web安全基础实践学习总结
20145316<网络对抗>Exp9 Web安全基础实践学习总结 基础问题回答 SQL注入攻击原理,如何防御 SQL注入,就是攻击者通过把SQL命令插入到Web表单递交或输入域名或页面请求 ...
- linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制)
linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制) 发表于2012//07由feng linux 本身的ugo rwx的权限,对于精确的权限控制很是力不从心的,ac ...
- Web前端开发最佳实践(1):前端开发概述
引言 我从07年开始进入博客园,从最开始阅读别人的文章到自己开始尝试表达一些自己对技术的看法.可以说,博客园是我参与技术讨论的一个主要的平台.在这其间,随着接触技术的广度和深度的增加,也写了一些得到了 ...
- Web开发初探之JavaScript 快速入门
本文改编和学习自 A JavaScript Primer For Meteor 和 MDN Web教程 前文 Web开发初探 概述 本文以介绍 JavaScript 为主,初学者掌握本文的内容后,将能 ...
- C# Web应用调试开启外部访问
在用C#开发Web应用时有个痛点,就是本机用VS开启Web应用调试时外部机器无法访问此Web应用.这里将会介绍如何通过设置允许局域网和外网机器访问本机的Web应用. 目录 1. 设置内网访问 2. 设 ...
- 网页提交中文到WEB容器的经历了些什么过程....
先准备一个网页 <html><meta http-equiv="Content-Type" content="text/html; charset=gb ...
- 闲来无聊,研究一下Web服务器 的源程序
web服务器是如何工作的 1989年的夏天,蒂姆.博纳斯-李开发了世界上第一个web服务器和web客户机.这个浏览器程序是一个简单的电话号码查询软件.最初的web服务器程序就是一个利用浏览器和web服 ...
- java: web应用中不经意的内存泄露
前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...
- 对抗密码破解 —— Web 前端慢 Hash
(更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...
随机推荐
- Ubuntu:Docker启动与停止
安装完成Docker后,默认已经启动了docker服务,如需手动控制docker服务的启停,可执行如下命令 启动docker sudo service docker start 停止docker su ...
- java中String类型的相关知识的简单总结
java中String类型的相关知识总结 一.常用方法: 1.构造方法: byte数组 可指定offset和length 可指定charset char数组 可指定offset和count 字符序列 ...
- Excelize 2.7.0 发布, 2023 年首个更新
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Exc ...
- [C++]全面理解C++中的引用
一.引用的本质是什么 说到引用,一般C++的教材中都是这么定义的: 1,引用就是一个对象的别名. 2,引用不是值不占内存空间. 3,引用必须在定义时赋值,将变量与引用绑定. 那你有没有想过,上面的定义 ...
- 洛谷P8508 做不完的作业【题解】
事先声明 此题解为一篇洛谷题解的详细补充,这里(我才不告诉你我这道题想了好久) 题目大意 有 \(n\) 个任务,记作 \(t\) 数组,由于主人公很懒,所以他每天都要睡觉,每一天都有 \(x\) 小 ...
- Java遍历Map集合
Java遍历Map集合简单例子 import java.util.*; public class Main { public static void main(String[] args) { Has ...
- STM32 的学习方法
前言 学习知识要掌握有效的学习方法,学习技术也是一样,本篇分享关于我学习 STM32 后总结的学习方法. 推荐的学习方法 系统学习 在网上购买一款开发板,使用开发板+开发板配套视频教程+开发板配套源码 ...
- SOFAJRaft源码阅读-ShutdownHook如何优雅的停机
Java程序经常会遇到进程挂掉的情况,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码.JAVA中的ShutdownHook提供了比较好的方案.而在SOFAJRaft- ...
- angular建立服务打印日志创建全局变量方法有两种,手工创建,依赖注入
- 黏包现象、struct模块、并行与并发
1.黏包现象 1.黏包现象产生的背景: 1.1 服务端连续执行三次recv 1.2 客户端连续执行三次send 执行上述操作会发现服务端一次性接收到了客户端三条消息,而后面两次什么都没接收到,该现象称 ...