水排序中的这个效果怎么实现?
白玉无冰
共 6167字,需浏览 13分钟
· 2021-06-08
Water Sort Puzzle!
效果
这次咱们来实现杯子倾斜中的水面效果。
效果预览:
视频预览:
实现
首先,简化模型,杯子当作长方形处理,仅考虑杯子旋转范围-90 ~ 90
度。
水面渲染可采用graphics
绘图组件处理(把原点移动至杯子左下角作为原点),再添加一层mask
图片遮罩,裁剪出杯子效果。
确认已知条件:
杯子的宽高。 杯子旋转角度。 水面初始高度(杯子未旋转时)。
需求出:
水面与水杯的交点位置。
先考虑杯子节点顺时针旋转(angle
为正)。
水面会出现两种情况,我们只需把握一个原则,水的体积(面积)不变。
梯形形状计算过程如下图所示:
三角形形状计算过程如下图所示:
计算一个临界角度,通过这个角度判断水的形状是属于哪一种。
对于杯子节点逆时针旋转(angle
为负),推算过程类似,参考以下计算过程。
private drawOneWater(height: number, color: Color) {
const radiansA = this.bottleAngle / 180 * Math.PI;
//计算临界角度
const radiansM = Math.atan(2 * height / this.bottleWidth);
const tempWTan = this.bottleWidth * Math.tan(radiansA);
this.drawGraphics.fillColor = color;
if (radiansA <= radiansM) {
if (radiansA < -radiansM) {
// 三角形 逆时针
let hL = Math.sqrt(2 * height * -tempWTan);
// 超出高度处理
hL = hL > this.bottleHeight ? this.bottleHeight : hL;
const bW = hL / Math.tan(-radiansA);
this.drawGraphics.moveTo(this.bottleWidth, 0);
this.drawGraphics.lineTo(this.bottleWidth, hL);
this.drawGraphics.lineTo(this.bottleWidth - bW, 0);
this.drawGraphics.lineTo(this.bottleWidth, 0);
} else {
// 梯形,包含顺逆时针
this.drawGraphics.moveTo(0, 0);
let hL = height + tempWTan / 2;
// 超出高度处理
let cutOffset = 0;
if (hL > this.bottleHeight) {
cutOffset += hL - this.bottleHeight
}
let hR = height - tempWTan / 2;
if (hR > this.bottleHeight) {
cutOffset += hR - this.bottleHeight
}
this.drawGraphics.lineTo(this.bottleWidth, 0);
this.drawGraphics.lineTo(this.bottleWidth, hR - cutOffset);
this.drawGraphics.lineTo(0, hL - cutOffset);
this.drawGraphics.lineTo(0, 0);
}
} else {
// 三角形 顺时针
let hL = Math.sqrt(2 * height * tempWTan);
// 超出高度处理
hL = hL > this.bottleHeight ? this.bottleHeight : hL;
const bW = hL / Math.tan(radiansA);
this.drawGraphics.moveTo(0, 0);
this.drawGraphics.lineTo(bW, 0);
this.drawGraphics.lineTo(0, hL);
this.drawGraphics.lineTo(0, 0);
}
this.drawGraphics.fill();
}
对于多层水,按照从高到低的顺序画图,低处的水覆盖高层。如下图所示,按照0,1,2
的顺序画对应的水层。
private drawWater() {
if (!this.drawGraphics) return
this.drawGraphics.clear();
// 水的高度从高到低画
for (let index = 0; index < this.waterHeights.length; index++) {
const height = this.waterHeights[index];
this.drawOneWater(height, this.waterClolors[index] || Color.WHITE);
}
}
对于每一层什么时候倒完,正好是水的下一层到达瓶口时,大家可以算出对应的角度,这里就留给大家继续实现这个功能吧!
小结
抓住不变量,临界值实现对应效果!
以上为白玉无冰使用 Cocos Creator 3.1.0
实现 "水排序之水杯效果!"
的技术分享。
如果你也办法实现这个效果,一起留言讨论吧!
keep hungry! keep foolish!
更多
“点赞“ ”在看” 鼓励一下▼
评论
多人同时导出 Excel 干崩服务器!新来的阿里大佬给出的解决方案太优雅了!
点击关注公众号,Java 干货及时推送↓推荐阅读:面试辅导,我们出大成果了!来源:juejin.cn/post/7259249904777838629前言 业务诉求:考虑到数据库数据日渐增多,导出会有全量数据的导出,多人同时导出可以会对服务性能造成影响,导出涉及到mysql查询的io操作,
Java技术栈
1
Go 1.22 的新增功能系列之二:reflect.TypeFor
Go 1.22 的第一个候选版本已经发布,这意味着最终版本即将发布,现在是我在博客中介绍我在这个周期中所做工作的时候了。像往常一样,我的贡献很小,但它们是我的,所以我将从幕后的角度来谈谈它们。首先是reflect.TypeFor。这是整个函数:// TypeFor returns the [Type
GoCN
0
有意思!一个关于 Spring 历史的在线小游戏
发现 Spring One 的官网上有个好玩的彩蛋,分享给大家!进到Spring One的官网,可以看到右下角有个类似马里奥游戏中的金币图标。点击该金币之后,会打开一个新的页面,进入下面这样一个名为:The History Of Spring 的在线小游戏你可以使用上下左右的方向键来控制Spring
公众号程序猿DD
1
了解加密货币到加密货币的互换
1、什么是加密货币互换?加密货币到加密货币的互换是指以现行市场汇率将一种加密货币直接兑换为另一种加密货币。与需要法定货币存款和较长流程的传统交易所不同,加密货币到加密货币的互换可以无缝地促进交换。掉期在提高加密货币的流动性和效率方面发挥着重要作用。该功能使用户能够将他们的加密货币与钱包中的其他代币进
区块链头条
0
李彦宏:开源大模型不如闭源,后者会持续领先;周鸿祎:“开源不如闭源” 的言论是胡说八道
架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。
公众号该公众号已被封禁0、李彦宏:开源大模型不如闭源,后者会持续领先当今
源码共读
0
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
Go早期是如何在Google内部发展起来的
2007年Go诞生于Google,2009年Google正式对外宣布了Go语言的开源!时至今日,距离Go开源已经过去了近15个年头了[1]!Go在Google公司内部究竟是怎样的一个状态呢?前Google员工Yves Junqueira近期撰文从其个人所见所闻谈了Go在Google的历程[2]!这里
GoCN
0
【第129期】程序员的新宠:三款终端工具,让你告别Xshell!
概述 WindTerm:跨平台的SSH利器 首先介绍的是WindTerm,这是一款使用C语言开发的跨平台SSH客户端。它不仅完全免费,而且没有商业使用的限制。WindTerm支持SSH v2、Telnet、Raw Tcp等协议,而且性能出色,甚至超过了FinalShell和Electerm。功能
前端微服务
0