feat(All):Initial
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @author ErSan
|
||||
* @email mlt131220@163.com
|
||||
* @date 2024/8/29 22:10
|
||||
* @description 漫游的人物动画状态机
|
||||
*/
|
||||
import * as THREE from "three";
|
||||
|
||||
export class RoamingStatus{
|
||||
// 键盘按下状态
|
||||
keyDownStatus = {
|
||||
w:false,
|
||||
s:false,
|
||||
a:false,
|
||||
d:false,
|
||||
shift:false,
|
||||
space:false
|
||||
}
|
||||
|
||||
fadeTime = 0.2;
|
||||
|
||||
person: THREE.Group; // 人物
|
||||
mixer: THREE.AnimationMixer; // 动画混合器
|
||||
private clipAction: { [s: string]: THREE.AnimationAction } = {}; // 动画 action
|
||||
|
||||
constructor(person:THREE.Group,clips:THREE.AnimationClip[]) {
|
||||
this.person = person;
|
||||
this.mixer = new THREE.AnimationMixer(this.person);
|
||||
clips.forEach(clip => {
|
||||
this.clipAction[clip.name] = (this.mixer as THREE.AnimationMixer).clipAction(clip);
|
||||
})
|
||||
|
||||
this.mixer.addEventListener('loop', (e) => {
|
||||
switch (e.action.getClip().name){
|
||||
case "Enter":
|
||||
this.fadeIn("Idle");
|
||||
setTimeout(() => {
|
||||
this.clipAction.Enter.stop();
|
||||
},200)
|
||||
break;
|
||||
case "Jumping":
|
||||
this.setStatus("space",false);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
init(){
|
||||
this.clipAction.Idle.play();
|
||||
}
|
||||
|
||||
// 是否正在向前走
|
||||
get isWalkingForward(){
|
||||
return this.keyDownStatus.w || this.keyDownStatus.a || this.keyDownStatus.d;
|
||||
}
|
||||
|
||||
setStatus(key:string,value: boolean){
|
||||
this.keyDownStatus[key] = value;
|
||||
|
||||
switch (key){
|
||||
case "w":
|
||||
case "a":
|
||||
case "d":
|
||||
// 前进动画处理
|
||||
if(!this.keyDownStatus.w && !this.keyDownStatus.a && !this.keyDownStatus.d){
|
||||
this.fadeOut("Walking");
|
||||
|
||||
if(this.clipAction.Running.isRunning()){
|
||||
this.keyDownStatus.shift = false;
|
||||
this.fadeOut("Running")
|
||||
}
|
||||
}else{
|
||||
if(!this.clipAction.Walking.isRunning()){
|
||||
this.fadeIn("Walking");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "s":
|
||||
// 后退处理
|
||||
if(value){
|
||||
this.fadeIn("WalkingBackward");
|
||||
}else{
|
||||
this.fadeOut("WalkingBackward")
|
||||
}
|
||||
break;
|
||||
case "space":
|
||||
// 跳跃处理
|
||||
if(value){
|
||||
this.fadeIn("Jumping");
|
||||
|
||||
if(this.clipAction.Walking.isRunning()){
|
||||
this.fadeOut("Walking")
|
||||
}
|
||||
if(this.clipAction.Running.isRunning()){
|
||||
this.fadeOut("Running")
|
||||
}
|
||||
}else{
|
||||
if(this.keyDownStatus.shift){
|
||||
if(!this.clipAction.Running.isRunning()){
|
||||
this.fadeIn("Running")
|
||||
}
|
||||
}else if(this.isWalkingForward){
|
||||
if(!this.clipAction.Walking.isRunning()){
|
||||
this.fadeIn("Walking")
|
||||
}
|
||||
}
|
||||
|
||||
this.fadeOut("Jumping")
|
||||
}
|
||||
break;
|
||||
case "shift":
|
||||
if(value){
|
||||
this.fadeIn("Running");
|
||||
|
||||
this.fadeOut("Walking")
|
||||
}else{
|
||||
if(this.isWalkingForward){
|
||||
if(!this.clipAction.Walking.isRunning()){
|
||||
this.fadeIn("Walking");
|
||||
this.fadeOut("Running");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(!Object.values(this.keyDownStatus).includes(true)){
|
||||
if(!this.clipAction.Idle.isRunning()){
|
||||
this.fadeIn("Idle");
|
||||
}
|
||||
}else{
|
||||
if(this.clipAction.Idle.isRunning()){
|
||||
this.fadeOut("Idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fadeIn(name: string) {
|
||||
// if(!this.clipAction[name].isScheduled()){
|
||||
// this.clipAction[name].reset();
|
||||
// this.clipAction[name].play();
|
||||
// }
|
||||
//
|
||||
// this.clipAction[name].fadeIn(this.fadeTime);
|
||||
|
||||
this.clipAction[name].play();
|
||||
}
|
||||
|
||||
fadeOut(name:string){
|
||||
// this.clipAction[name].fadeOut(this.fadeTime)
|
||||
// setTimeout(() => {
|
||||
// this.clipAction[name].stop();
|
||||
// },this.fadeTime * 100)
|
||||
|
||||
this.clipAction[name].stop();
|
||||
}
|
||||
|
||||
stopAllAction(){
|
||||
// 停用混合器上所有预定的动作
|
||||
this.mixer.stopAllAction();
|
||||
}
|
||||
|
||||
|
||||
update(delta:number){
|
||||
this.mixer.update(delta);
|
||||
|
||||
// THREE.AnimationMixer loop事件不一定有用,此处添加一个检测
|
||||
if(!this.clipAction.Jumping.isRunning() && this.keyDownStatus.space){
|
||||
//console.log("THREE.AnimationMixer loop事件未生效,手动设置")
|
||||
this.keyDownStatus.space = false;
|
||||
}
|
||||
}
|
||||
|
||||
dispose(){
|
||||
this.stopAllAction();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user