猫史档案馆


《怪物巡逻、吐蛋》

用户:残梦殇残梦殇查看:0 回复:3 评论:0 创建时间:2024-01-30T10:33:05


console.clear()

// 根据内鬼绿的需求, 这次教大家 lucifer 吐蛋的代码
// 可以看到lucifer的模型我已经提前放进来了
// 今天完成来个功能一直个lucifer 周围没有人的时候, 他就巡逻, 如果有人就吐蛋
// 封装一个类来 实现lucifer的功能


class Lucifer{
constructor(entity){
/**
* @type GameEntity
*/
this.entity = entity

//需要有一个自旋来驱动lucifer , 这个上节课讲过的
// 初始化 tick
// 60毫秒一帧 来驱动lucifer 运动
this.tick = 0
this.range = 20 // 距离初始化为20
this.rot = 0 // 初始化旋转的角度
this.rotSpeed = 0.2 // 初始化一个角度的增加量
this.walkSpeed = 0.3
// 素材是反正的,这里需要调一下
this.seftQuat = new GameQuaternion(0, 0, 0, 1).rotateY(Math.PI)

this.walk_motion = this.entity.motion.loadByName('walk')
this.is_walk = false
this.walk_motion.onFinish(()=>{
this.is_walk = false
})

this.egg_attack_motion = this.entity.motion.loadByName('skill_3')
this.is_attack = false
this.egg_attack_motion.onFinish(()=>{
this.is_attack = false
})

setInterval(()=>{
this.tick ++
this.onTick()
}, 60)

}

/**
* @param {GameVector3} pos
*/
async spitEgg(pos){
// 先让lucider停止运动
this.entity.velocity = new GameVector3(0, 0, 0)
// 然后让它转向玩家
// pos就是玩家的位置
const vel = pos.sub(this.entity.position)
// 要让lucider 朝向这个向量
this.entity.meshOrientation = this.seftQuat.rotateY(Math.atan2(vel.z, vel.x))
// 试试效果 ok
// 播放lucifer 模型上吐蛋的动作了 skill_3 就是它
// 还是刚才的问题, 要控制重复播放
// 需要一个状态控制
if(!this.is_attack){
this.is_attack = true
this.egg_attack_motion.play()
// 然后要吐蛋了
// 我们要create一个蛋出来
const egg = world.createEntity({
id:'egg',
mesh:'mesh/路西法特效1.vb',
position: this.entity.position.add(new GameVector3(0, 5,0)),
meshScale: new GameVector3(1/16, 1/16, 1/16) // 填这个就和你拖进来的大小是一样的, 为啥别问
})
// 需要给蛋一个速度, 要不然就成下蛋了
egg.velocity = vel.normalize().scale(2) // normalize是归一化。 就是让这个相关成为0~1的值
// 蛋飞的低了,
//和动作就对上了
// 接下来就是蛋落地, 过一段时间仆从就从蛋里孵化出来
// 首先让蛋仔落地后停下来
egg.onVoxelContact(()=>{
egg.velocity = new GameVector3(0,0,0)
})
// 等待6秒 然后变仆从
// await 只能在 async 的方法里用
await sleep(6000)
// 变仆从就是把蛋的实体移除,放上来一个仆从的实体
// 先在蛋的位置创建一个仆从
const entity = world.createEntity({
id:'footman',
mesh:'mesh/路西法男爵仆从.vb',
position: egg.position,
meshScale: new GameVector3(1/16, 1/16, 1/16)
})
egg.destroy()
new Footman(entity)
// 吉吉帮助完成测试
// 接着要完成 仆从的逻辑了哦
}
// 试试 大意了

}

onTick(){
// lucifer 要找周围有没有人, 上节课也讲过哦, 我们直接写
const players = this.queryNearByPlayer(this.range)
if(players.length > 0){
// 如果周围有人就要朝他吐蛋
// 然后就要朝你吐蛋了
this.spitEgg(players[0].position)
// ok
}else{
// 如果没有人, 就要巡逻, 这个上节课讲过, 先过一下
this.walkNoAim()
// 试试效果
// 转的有点快了a
// 因为lucider 是有动画的, 我们需要给它加一个行走的动画
// 新知识了哦
if(!this.is_walk){
this.walk_motion.play()
this.is_walk = true
// 要让动画一直循环播放
}
// ok lucider的巡逻就完成了哦
// 动画被重复调用了, 需要一个控制动画的状态

}
}

walkNoAim(){
// 首先定一个旋转的角度, 不断的增加
this.rot += this.rotSpeed
// 求出这个角度在x和z轴上的向量
const xv = Math.cos(this.rot)
const zv = Math.sin(this.rot)
// 要定义lucifer 巡逻的速度
this.entity.velocity.x = xv * this.walkSpeed
this.entity.velocity.z = zv * this.walkSpeed
// lucifer 要一直面上走路的方向
this.entity.meshOrientation = this.seftQuat.rotateY(this.rot)
}

queryNearByPlayer(range){
const players = world.querySelectorAll('player')
return players.filter((e)=>{
return e.position.distance(this.entity.position) < range
})
}
}

class Footman{
constructor(entity){
this.entity = entity
// 普通也要巡逻
// 和lucifer是一个样的
// 要在写一边么
// 还记得上节课我们将的继承么
this.tick = 0

this.range = 20 // 距离初始化为20
this.rot = 0 // 初始化旋转的角度
this.rotSpeed = 0.2 // 初始化一个角度的增加量
this.walkSpeed = 0.3
// 素材是反正的,这里需要调一下
this.seftQuat = new GameQuaternion(0, 0, 0, 1).rotateY(Math.PI)
this.traceSpeed = 0.8

setInterval(()=>{
this.tick ++
this.onTick()
},60)
}

onTick(){
// lucifer 要找周围有没有人, 上节课也讲过哦, 我们直接写
const players = this.queryNearByPlayer(this.range)
if(players.length > 0){
// 刚才搬砖的电脑卡丢了一些代码
// 仆从也开始动了
// 然后让仆从追着吉吉跑
// 代码就讲到这里了哦
// 给大家留个作业,是搬砖没有做的
// 就是把lucider和 footman 公共的代码抽象到父类里, 上节课有讲过的
this.moveToTarget(players[0].position)
}else{
this.walkNoAim()
}
}

moveToTarget(pos){
const vel = pos.sub(this.entity.position).normalize()
this.entity.velocity.x = vel.x * this.traceSpeed
this.entity.velocity.z = vel.z * this.traceSpeed
const ori = this.seftQuat.rotateY(Math.atan2(vel.z, vel.x))
this.entity.meshOrientation = this.entity.meshOrientation.slerp(ori, 0.2)
}

queryNearByPlayer(range){
const players = world.querySelectorAll('player')
return players.filter((e)=>{
return e.position.distance(this.entity.position) < range
})
}

walkNoAim(){
// 首先定一个旋转的角度, 不断的增加
this.rot += this.rotSpeed
// 求出这个角度在x和z轴上的向量
const xv = Math.cos(this.rot)
const zv = Math.sin(this.rot)
// 要定义lucifer 巡逻的速度
this.entity.velocity.x = xv * this.walkSpeed
this.entity.velocity.z = zv * this.walkSpeed
// lucifer 要一直面上走路的方向
this.entity.meshOrientation = this.seftQuat.rotateY(this.rot)
}

}


// 我们找到这个模型
const entity = world.querySelector('#路西法男爵-1')
const lucifer = new Lucifer(entity)


回复

上一页1 页 / 共 1下一页
残梦殇残梦殇

console.clear()

// 根据内鬼绿的需求, 这次教大家 lucifer 吐蛋的代码
// 可以看到lucifer的模型我已经提前放进来了
// 今天完成来个功能一直个lucifer 周围没有人的时候, 他就巡逻, 如果有人就吐蛋
// 封装一个类来 实现lucifer的功能


class Lucifer{
    constructor(entity){
        /**
         * @type GameEntity
         */
        this.entity = entity

        //需要有一个自旋来驱动lucifer , 这个上节课讲过的
        // 初始化 tick
        // 60毫秒一帧 来驱动lucifer 运动
        this.tick = 0
        this.range = 20 // 距离初始化为20
        this.rot = 0 // 初始化旋转的角度
        this.rotSpeed = 0.2 // 初始化一个角度的增加量
        this.walkSpeed = 0.3
        // 素材是反正的,这里需要调一下
        this.seftQuat = new GameQuaternion(0, 0, 0, 1).rotateY(Math.PI)

        this.walk_motion = this.entity.motion.loadByName('walk')
        this.is_walk = false
        this.walk_motion.onFinish(()=>{
            this.is_walk = false
        })

        this.egg_attack_motion = this.entity.motion.loadByName('skill_3')
        this.is_attack = false
        this.egg_attack_motion.onFinish(()=>{
            this.is_attack = false
        })

        setInterval(()=>{
            this.tick ++
            this.onTick()
        }, 60)

    }

    /**
     * @param {GameVector3} pos
     */
    async spitEgg(pos){
        // 先让lucider停止运动
        this.entity.velocity = new GameVector3(0, 0, 0)
        // 然后让它转向玩家
        // pos就是玩家的位置
        const vel = pos.sub(this.entity.position)
        // 要让lucider 朝向这个向量
        this.entity.meshOrientation = this.seftQuat.rotateY(Math.atan2(vel.z, vel.x))
        // 试试效果 ok 
        // 播放lucifer 模型上吐蛋的动作了 skill_3 就是它
        // 还是刚才的问题, 要控制重复播放
        // 需要一个状态控制
        if(!this.is_attack){
            this.is_attack = true
            this.egg_attack_motion.play()
            // 然后要吐蛋了
            // 我们要create一个蛋出来
            const egg = world.createEntity({
                id:'egg',
                mesh:'mesh/路西法特效1.vb',
                position: this.entity.position.add(new GameVector3(0, 5,0)),
                meshScale: new GameVector3(1/16, 1/16, 1/16) // 填这个就和你拖进来的大小是一样的, 为啥别问
            })
            // 需要给蛋一个速度, 要不然就成下蛋了
            egg.velocity = vel.normalize().scale(2) // normalize是归一化。 就是让这个相关成为0~1的值
            // 蛋飞的低了, 
            //和动作就对上了
            // 接下来就是蛋落地, 过一段时间仆从就从蛋里孵化出来
            // 首先让蛋仔落地后停下来
            egg.onVoxelContact(()=>{
                egg.velocity = new GameVector3(0,0,0)
            })
            // 等待6秒 然后变仆从
            // await 只能在 async 的方法里用
            await sleep(6000)
            // 变仆从就是把蛋的实体移除,放上来一个仆从的实体
            // 先在蛋的位置创建一个仆从
            const entity = world.createEntity({
                id:'footman',
                mesh:'mesh/路西法男爵仆从.vb',
                position: egg.position,
                meshScale: new GameVector3(1/16, 1/16, 1/16)
            })
            egg.destroy()
            new Footman(entity)
            // 吉吉帮助完成测试
            // 接着要完成 仆从的逻辑了哦
        }
        // 试试 大意了

    }

    onTick(){
        // lucifer 要找周围有没有人, 上节课也讲过哦, 我们直接写 
        const players = this.queryNearByPlayer(this.range)
        if(players.length > 0){
            // 如果周围有人就要朝他吐蛋
            // 然后就要朝你吐蛋了
            this.spitEgg(players[0].position)
            // ok
        }else{
            // 如果没有人, 就要巡逻, 这个上节课讲过, 先过一下
            this.walkNoAim()
            // 试试效果
            // 转的有点快了a
            // 因为lucider 是有动画的, 我们需要给它加一个行走的动画
            // 新知识了哦
            if(!this.is_walk){
                this.walk_motion.play()
                this.is_walk = true
                // 要让动画一直循环播放
            }
            // ok lucider的巡逻就完成了哦
            // 动画被重复调用了, 需要一个控制动画的状态

        }
    }

    walkNoAim(){
        // 首先定一个旋转的角度, 不断的增喵出这个角度在x和z轴上的向量
        const xv = Math.cos(this.rot)
        const zv = Math.sin(this.rot)
        // 要定义lucifer 巡逻的速度
        this.entity.velocity.x = xv * this.walkSpeed
        this.entity.velocity.z = zv * this.walkSpeed
        // lucifer 要一直面上走路的方向
        this.entity.meshOrientation = this.seftQuat.rotateY(this.rot)
    }

    queryNearByPlayer(range){
        const players = world.querySelectorAll('player')
        return players.filter((e)=>{
            return e.position.distance(this.entity.position) < range
        })
    }
}

class Footman{
    constructor(entity){
        this.entity = entity
        // 普通也要巡逻
        // 和lucifer是一个样的
        // 要在写一边么
        // 还记得上节课我们将的继承么
        this.tick = 0

        this.range = 20 // 距离初始化为20
        this.rot = 0 // 初始化旋转的角度
        this.rotSpeed = 0.2 // 初始化一个角度的增加量
        this.walkSpeed = 0.3
        // 素材是反正的,这里需要调一下
        this.seftQuat = new GameQuaternion(0, 0, 0, 1).rotateY(Math.PI)
        this.traceSpeed = 0.8

        setInterval(()=>{
            this.tick ++
            this.onTick()
        },60)
    }

    onTick(){
        // lucifer 要找周围有没有人, 上节课也讲过哦, 我们直接写 
        const players = this.queryNearByPlayer(this.range)
        if(players.length > 0){
            // 刚才搬砖的电脑卡丢了一些代码
            // 仆从也开始动了
            // 然后让仆从追着吉吉跑
            // 代码就讲到这里了哦
            // 给大家留个作业,是搬砖没有做的
            // 就是把lucider和 footman 公共的代码抽象到父类里, 上节课有讲过的
            this.moveToTarget(players[0].position)
        }else{
            this.walkNoAim()
        }
    }

    moveToTarget(pos){
        const vel = pos.sub(this.entity.position).normalize()
        this.entity.velocity.x = vel.x * this.traceSpeed
        this.entity.velocity.z = vel.z * this.traceSpeed
        const ori = this.seftQuat.rotateY(Math.atan2(vel.z, vel.x))
        this.entity.meshOrientation = this.entity.meshOrientation.slerp(ori, 0.2) 
    }

    queryNearByPlayer(range){
        const players = world.querySelectorAll('player')
        return players.filter((e)=>{
            return e.position.distance(this.entity.position) < range
        })
    }

    walkNoAim(){
        // 首先定一个旋转的角度, 不断的增喵出这个角度在x和z轴上的向量
        const xv = Math.cos(this.rot)
        const zv = Math.sin(this.rot)
        // 要定义lucifer 巡逻的速度
        this.entity.velocity.x = xv * this.walkSpeed
        this.entity.velocity.z = zv * this.walkSpeed
        // lucifer 要一直面上走路的方向
        this.entity.meshOrientation = this.seftQuat.rotateY(this.rot)
    }

}


// 我们找到这个模型
const entity = world.querySelector('#路西法男爵-1')
const lucifer = new Lucifer(entity)

点赞0


评论


飞熊jsrt飞熊jsrt

嗨嗨嗨,板凳

点赞0


评论


飞熊jsrt飞熊jsrt

还是我,天花板

点赞0


评论