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的更多相关文章

  1. 零基础从实践出发学java编程【总结篇】

    1.背景 很多人学习java的第一步就是系统的学习java基础语法,有的java基础语法还没学完就崩溃了,确实java基础语法太多太细,而且都是理论,学着让人很懵: 好不容易学完基础语法,又要学框架. ...

  2. 20145316《网络对抗》Exp9 Web安全基础实践学习总结

    20145316<网络对抗>Exp9 Web安全基础实践学习总结 基础问题回答 SQL注入攻击原理,如何防御 SQL注入,就是攻击者通过把SQL命令插入到Web表单递交或输入域名或页面请求 ...

  3. linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制)

    linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制) 发表于2012//07由feng linux 本身的ugo rwx的权限,对于精确的权限控制很是力不从心的,ac ...

  4. Web前端开发最佳实践(1):前端开发概述

    引言 我从07年开始进入博客园,从最开始阅读别人的文章到自己开始尝试表达一些自己对技术的看法.可以说,博客园是我参与技术讨论的一个主要的平台.在这其间,随着接触技术的广度和深度的增加,也写了一些得到了 ...

  5. Web开发初探之JavaScript 快速入门

    本文改编和学习自 A JavaScript Primer For Meteor 和 MDN Web教程 前文 Web开发初探 概述 本文以介绍 JavaScript 为主,初学者掌握本文的内容后,将能 ...

  6. C# Web应用调试开启外部访问

    在用C#开发Web应用时有个痛点,就是本机用VS开启Web应用调试时外部机器无法访问此Web应用.这里将会介绍如何通过设置允许局域网和外网机器访问本机的Web应用. 目录 1. 设置内网访问 2. 设 ...

  7. 网页提交中文到WEB容器的经历了些什么过程....

    先准备一个网页 <html><meta http-equiv="Content-Type" content="text/html; charset=gb ...

  8. 闲来无聊,研究一下Web服务器 的源程序

    web服务器是如何工作的 1989年的夏天,蒂姆.博纳斯-李开发了世界上第一个web服务器和web客户机.这个浏览器程序是一个简单的电话号码查询软件.最初的web服务器程序就是一个利用浏览器和web服 ...

  9. java: web应用中不经意的内存泄露

    前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...

  10. 对抗密码破解 —— Web 前端慢 Hash

    (更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...

随机推荐

  1. [深度学习] tf.keras入门1-基本函数介绍

    目录 构建一个简单的模型 序贯(Sequential)模型 网络层的构造 模型训练和参数评价 模型训练 模型的训练 tf.data的数据集 模型评估和预测 基本模型的建立 网络层模型 模型子类函数构建 ...

  2. Spark详解(06) - SparkSQL

    Spark详解(06) - SparkSQL Spark SQL概述 什么是Spark SQL Spark SQL是Spark用于结构化数据(Structured Data)处理的Spark模块. ( ...

  3. 一文读懂 Kubernetes 存储设计

    在 Docker 的设计中,容器内的文件是临时存放的,并且随着容器的删除,容器内部的数据也会一同被清空.不过,我们可以通过在 docker run 启动容器时,使用 --volume/-v 参数来指定 ...

  4. Maven项目中导入坐标依赖时报(Failure to transfer....)的错的问题

    Maven项目中导入坐标依赖时报(Failure to transfer....)的错的问题   今天在做Spring MVC的一个项目时导入坐标依赖的时候突然网断了一下(村里网络日常不稳定),然后就 ...

  5. 【大型软件开发】浅谈大型Qt软件开发(二)面向未来开发——来自未来的技术:COM组件。我如何做到让我们的教学模块像插件一样即插即用,以及为什么这么做。

    前言 最近我们项目部的核心产品正在进行重构,然后又是年底了,除了开发工作之外项目并不紧急,加上加班时间混不够了....所以就忙里偷闲把整个项目的开发思路聊一下,以供参考. 鉴于接下来的一年我要进行这个 ...

  6. 【译】15 个有用的 JavaScript 技巧

    原文地址:https://javascript.plainenglish.io/15-useful-javascript-tips-814eeba1f4fd 1)数字分隔符 为了提高数字的可读性,可以 ...

  7. pycham debug 专辑

    遇到大量代码的项目时怎么迅猛的调代码今天将交给大家几个方法 配置环境: 环境的统一是一切的基础,因为不同的版本不同步之间会造成很多各式各样的报错 然后选择现有环境进行配置 上面的路径进行默认环境变量的 ...

  8. 流程概述与顺序结构-选择结构_单if语句

    流程概述与顺序结构 概述 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说,程序的流程对运行结果 有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要 ...

  9. 行为型模式 - 访问者模式Visitor

    学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 行为型模式,我之所以把他放到第一个,是因为它号称是GoF中最难的一个. 模式的定义与特点 在访问者模式中(Visitor Pat ...

  10. Unity之GPS定位(高德解析)

    Unity之GPS定位 Unity之GPS定位(高德解析) 前言 开篇 Unity版本及使用插件 正题 创建场景 写脚本 把脚本挂载到场景中 打包发布场景 安装真机并且测试 代码中的==Key==怎么 ...