用户:
AK亨利佐加DanJamesThomas查看:6 回复:10 评论:6 创建时间:2022-11-13T20:05:28
对于临时切换模型,大家应该都熟悉吧?
看看100问的一个回答:
MOYO:地上用两个走路的模型切换模拟走路,上天的时候,换成一个贴在天花板的倒立蜘蛛模型而已。
鸡:对对对,就是他们说的这样的
呵呵,这是怎么实现的呢?
先一步一步地讲解:
首先,得先知道class,类的知识,
类(英语:class)在 面向对象编程中是一种 面向对象 计算机编程语言的构造,是创建 对象的蓝图,描述了所创建的对象共同的 属性和 方法。 类的更严格的定义是由某种特定的 元数据所组成的 内聚的包。它描述了一些对象的行为规则,而这些对象就被称为该类的 实例。类有 接口和结构。接口描述了如何通过方法与类及其实例互操作,而结构描述了一个实例中数据如何划分为多个属性。类是与某个层[注 1]的对象的最具体的类型。类还可以有运行时表示形式( 元对象),它为操作与类相关的元数据提供了运行时支持。 支持类的编程语言在支持与类相关的各种特性方面都多多少少有一些微妙的差异。大多数都支持不同形式的类继承。许多语言还支持提供封装性的特性,比如访问修饰符。类的出现,为 面向对象编程的三个最重要的特性(封装性、 继承性、 多态性),提供了实现的手段。 所以,我们可以用class封装一种东西:class something extends Box3Entity{}
而这里的class运用了它的继承性,具体表明方式是
class 子类 extends 父类 {}
子类继承了父类,理解了吗?一个模型继承了另一个模型!
当然,class也有init()在init()里干代码:
class something extends Box3Entity {
async init() {
while (true) {
await sleep(200)
this.mesh = world.querySelector('#something_action-1').mesh
await sleep(200)
this.mesh = world.querySelector('#something_action-2').mesh
}
}
}
注意看上面的this
他表明了继承的对象(something_actiong),在某个运行的途中改变模型(让一个模型替代这个模型)就可以实现模型动作改变的现象了。
举个栗子,3D超级马里奥的食人花在冒出来之后会有个“咬”的动作,代码(可能)如下
class CannibalPlant extends Box3Entity {
async init() {
let startPos = this.position.clone()
let endPos = startPos.add(new Box3Vector3(0, -5, 0))
const ani = this.animate([
{ position: startPos, duration: 1 + 1 * Math.random() },
{ position: startPos, duration: 0.5 + 0.5 * Math.random() },
{ position: endPos, duration: 3 + 3 * Math.random() },
{ position: endPos, duration: 0.5 + 0.5 * Math.random() },
])
ani.play({
duration: 16 * 5,
iterations: Infinity,//动画无限次循环播放
direction: Box3AnimationDirection.WRAP,//让动画实体从终点回到起点
})
this.onEntityContact(({ entity, other }) => {
if (other.isPlayer) {
other.beAttacked()
}
})
while (true) {
await sleep(200)
this.mesh = world.querySelector('#食人花').mesh
await sleep(200)
this.mesh = world.querySelector('#食人花2').mesh
}
}
}
当然,光光写出继承代码,得让他实现啊!
得给实体绑定脚本!
for (const e of world.querySelectorAll('*')) {
if (e.id.startsWith('食人花')) {
patch(e, CannibalPlant)
e.init()
}
}
注意,patch
的意思是给一个模型绑定一个脚本(我们的继承性class)。
好啦,总结一下代码:
首先,定义class,让一个模型(食人花)去在运行时或某个代码结束时,让另一个模型(食人花-2)去替换他,以实现动作交替进行的实现。
/** 食人花 */
class CannibalPlant extends Box3Entity {
async init() {
let startPos = this.position.clone()
let endPos = startPos.add(new Box3Vector3(0, -5, 0))
const ani = this.animate([
{ position: startPos, duration: 1 + 1 * Math.random() },
{ position: startPos, duration: 0.5 + 0.5 * Math.random() },
{ position: endPos, duration: 3 + 3 * Math.random() },
{ position: endPos, duration: 0.5 + 0.5 * Math.random() },
])
ani.play({
duration: 16 * 5,
iterations: Infinity,//动画无限次循环播放
direction: Box3AnimationDirection.WRAP,//让动画实体从终点回到起点
})
this.onEntityContact(({ entity, other }) => {
if (other.isPlayer) {
other.beAttacked()
}
})
while (true) {
await sleep(200)
this.mesh = world.querySelector('#copy-食人花').mesh
await sleep(200)
this.mesh = world.querySelector('#copy-食人花2').mesh
}
}
}
/** 给实体绑定脚本 */
for (const e of world.querySelectorAll('*')) {
if (e.id.startsWith('食人花')) {
patch(e, CannibalPlant)
e.init()
}
}
AK亨利佐加DanJamesThomaspatch的函数需要自己定义:
function patch(dstObj, srcClass) {
const srcProto = srcClass.prototype
for (const meth of Reflect.ownKeys(srcProto).slice(1)) {
dstObj[meth] = srcProto[meth]
}
}
global.patch = patch;
点赞0
评论