three-player-controller 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -5,6 +5,17 @@ import { RoundedBoxGeometry } from "three/examples/jsm/geometries/RoundedBoxGeom
5
5
  import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
6
6
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
7
7
  import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
8
+
9
+ // assets/imgs/fly.png
10
+ var fly_default = "data:image/png;base64,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";
11
+
12
+ // assets/imgs/jump.png
13
+ var jump_default = "data:image/png;base64,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";
14
+
15
+ // assets/imgs/view.png
16
+ var view_default = "data:image/png;base64,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";
17
+
18
+ // src/playerController.ts
8
19
  THREE.Mesh.prototype.raycast = acceleratedRaycast;
9
20
  var controllerInstance = null;
10
21
  var clock = new THREE.Clock();
@@ -20,15 +31,15 @@ var PlayerController = class {
20
31
  this.displayPlayer = false;
21
32
  this.displayCollider = false;
22
33
  this.displayVisualizer = false;
23
- // 场景对象
34
+ // 场景对象
24
35
  this.collider = null;
25
36
  this.visualizer = null;
26
37
  this.person = null;
27
- // 状态开关
38
+ // 状态开关
28
39
  this.playerIsOnGround = false;
29
40
  this.isupdate = true;
30
41
  this.isFlying = false;
31
- // 输入状态
42
+ // 输入状态
32
43
  this.fwdPressed = false;
33
44
  this.bkdPressed = false;
34
45
  this.lftPressed = false;
@@ -36,6 +47,19 @@ var PlayerController = class {
36
47
  this.spacePressed = false;
37
48
  this.ctPressed = false;
38
49
  this.shiftPressed = false;
50
+ // 移动端输入
51
+ this.prevJoyState = { dirX: 0, dirY: 0, shift: false };
52
+ // 移动控制相关
53
+ this.joystickManager = null;
54
+ this.joystickZoneEl = null;
55
+ this.lookAreaEl = null;
56
+ this.jumpBtnEl = null;
57
+ this.flyBtnEl = null;
58
+ this.viewBtnEl = null;
59
+ this.lookPointerId = null;
60
+ this.isLookDown = false;
61
+ this.lastTouchX = 0;
62
+ this.lastTouchY = 0;
39
63
  // 第三人称
40
64
  this._camCollisionLerp = 0.18;
41
65
  // 平滑系数
@@ -46,7 +70,7 @@ var PlayerController = class {
46
70
  this._maxCamDistance = 4.4;
47
71
  // 摄像机最大距离
48
72
  this.orginMaxCamDistance = 4.4;
49
- // 物理/运动
73
+ // 物理/运动
50
74
  this.playerVelocity = new THREE.Vector3();
51
75
  // 玩家速度向量
52
76
  this.upVector = new THREE.Vector3(0, 1, 0);
@@ -56,6 +80,8 @@ var PlayerController = class {
56
80
  this.tempBox = new THREE.Box3();
57
81
  this.tempMat = new THREE.Matrix4();
58
82
  this.tempSegment = new THREE.Line3();
83
+ // 检测动画定时
84
+ this.recheckAnimTimer = null;
59
85
  // 复用向量:用于相机朝向 / 移动
60
86
  this.camDir = new THREE.Vector3();
61
87
  this.moveDir = new THREE.Vector3();
@@ -106,6 +132,8 @@ var PlayerController = class {
106
132
  case "Space":
107
133
  this.spacePressed = true;
108
134
  if (!this.playerIsOnGround || this.isFlying) return;
135
+ const next = this.personActions?.get("jumping");
136
+ if (next && this.actionState === next) return;
109
137
  this.playPersonAnimationByName("jumping");
110
138
  this.playerVelocity.y = this.jumpHeight;
111
139
  this.playerIsOnGround = false;
@@ -119,6 +147,8 @@ var PlayerController = class {
119
147
  case "KeyF":
120
148
  this.isFlying = !this.isFlying;
121
149
  this.setAnimationByPressed();
150
+ if (!this.isFlying && !this.playerIsOnGround)
151
+ this.playPersonAnimationByName("jumping");
122
152
  break;
123
153
  }
124
154
  };
@@ -198,49 +228,51 @@ var PlayerController = class {
198
228
  this.playPersonAnimationByName("walking_backward");
199
229
  return;
200
230
  }
201
- } else {
202
- this.playPersonAnimationByName("jumping");
203
231
  }
232
+ if (this.recheckAnimTimer !== null) {
233
+ clearTimeout(this.recheckAnimTimer);
234
+ }
235
+ this.recheckAnimTimer = setTimeout(() => {
236
+ this.setAnimationByPressed();
237
+ this.recheckAnimTimer = null;
238
+ }, 200);
204
239
  };
205
240
  // 鼠标移动事件
206
241
  this._mouseMove = (e) => {
207
242
  if (document.pointerLockElement !== document.body) return;
208
- if (this.isFirstPerson) {
209
- const yaw = -e.movementX * 1e-4 * this.mouseSensity;
210
- const pitch = -e.movementY * 1e-4 * this.mouseSensity;
211
- this.player.rotateY(yaw);
212
- this.camera.rotation.x = THREE.MathUtils.clamp(
213
- this.camera.rotation.x + pitch,
214
- -1.3,
215
- 1.4
216
- );
217
- } else {
218
- const sensitivity = 1e-4 * this.mouseSensity;
219
- const deltaX = -e.movementX * sensitivity;
220
- const deltaY = -e.movementY * sensitivity;
221
- const target = this.player.position.clone();
222
- const distance = this.camera.position.distanceTo(target);
223
- const currentPosition = this.camera.position.clone().sub(target);
224
- let theta = Math.atan2(currentPosition.x, currentPosition.z);
225
- let phi = Math.acos(currentPosition.y / distance);
226
- theta += deltaX;
227
- phi += deltaY;
228
- phi = Math.max(0.1, Math.min(Math.PI - 0.1, phi));
229
- const newX = distance * Math.sin(phi) * Math.sin(theta);
230
- const newY = distance * Math.cos(phi);
231
- const newZ = distance * Math.sin(phi) * Math.cos(theta);
232
- this.camera.position.set(
233
- target.x + newX,
234
- target.y + newY,
235
- target.z + newZ
236
- );
237
- this.camera.lookAt(target);
238
- }
243
+ this.setToward(e.movementX, e.movementY, 1e-4);
239
244
  };
240
245
  this._mouseClick = (e) => {
241
246
  if (document.pointerLockElement !== document.body)
242
247
  document.body.requestPointerLock();
243
248
  };
249
+ this.onPointerDown = (e) => {
250
+ if (e.pointerType !== "touch") return;
251
+ this.isLookDown = true;
252
+ this.lookPointerId = e.pointerId;
253
+ this.lastTouchX = e.clientX;
254
+ this.lastTouchY = e.clientY;
255
+ this.lookAreaEl?.setPointerCapture && this.lookAreaEl.setPointerCapture(e.pointerId);
256
+ e.preventDefault();
257
+ };
258
+ this.onPointerMove = (e) => {
259
+ if (!this.isLookDown || e.pointerId !== this.lookPointerId) return;
260
+ const dx = e.clientX - this.lastTouchX;
261
+ const dy = e.clientY - this.lastTouchY;
262
+ this.lastTouchX = e.clientX;
263
+ this.lastTouchY = e.clientY;
264
+ this.setInput({
265
+ lookDeltaX: dx,
266
+ lookDeltaY: dy
267
+ });
268
+ e.preventDefault();
269
+ };
270
+ this.onPointerUp = (e) => {
271
+ if (e.pointerId !== this.lookPointerId) return;
272
+ this.isLookDown = false;
273
+ this.lookPointerId = null;
274
+ this.lookAreaEl?.releasePointerCapture && this.lookAreaEl.releasePointerCapture(e.pointerId);
275
+ };
244
276
  this._raycaster.firstHitOnly = true;
245
277
  this._raycasterPersonToCam.firstHitOnly = true;
246
278
  }
@@ -264,11 +296,18 @@ var PlayerController = class {
264
296
  this._minCamDistance = opts.minCamDistance ? opts.minCamDistance * s : 100 * s;
265
297
  this._maxCamDistance = opts.maxCamDistance ? opts.maxCamDistance * s : 440 * s;
266
298
  this.orginMaxCamDistance = this._maxCamDistance;
299
+ this.isShowMobileControls = opts.isShowMobileControls ?? true;
300
+ function isMobileDevice() {
301
+ return navigator.maxTouchPoints && navigator.maxTouchPoints > 0 || "ontouchstart" in window || /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
302
+ }
303
+ if (isMobileDevice() && this.isShowMobileControls) {
304
+ this.initMobileControls();
305
+ }
267
306
  await this.createBVH(opts.colliderMeshUrl);
268
307
  this.createPlayer();
269
308
  await this.loadPersonGLB();
270
- if (this.isFirstPerson && this.player) {
271
- this.player.add(this.camera);
309
+ if (this.isFirstPerson && this.person) {
310
+ this.person.add(this.camera);
272
311
  }
273
312
  this.onAllEvent();
274
313
  this.setCameraPos();
@@ -367,11 +406,7 @@ var PlayerController = class {
367
406
  this.person.traverse((child) => {
368
407
  if (child.isMesh) {
369
408
  child.castShadow = true;
370
- const mat = child.material;
371
- if (!mat) return;
372
- const mats = Array.isArray(mat) ? mat : [mat];
373
- mats.forEach((m) => {
374
- });
409
+ child.receiveShadow = true;
375
410
  }
376
411
  });
377
412
  this.player.add(this.person);
@@ -754,6 +789,7 @@ var PlayerController = class {
754
789
  this.scene.remove(this.collider);
755
790
  this.collider = null;
756
791
  }
792
+ this.destroyMobileControls();
757
793
  controllerInstance = null;
758
794
  }
759
795
  // 事件绑定
@@ -891,6 +927,305 @@ var PlayerController = class {
891
927
  }
892
928
  this.boundingBoxMinY = this.collider.geometry.boundingBox.min.y;
893
929
  }
930
+ // 设置朝向
931
+ setToward(dx, dy, speed) {
932
+ if (this.isFirstPerson) {
933
+ const yaw = -dx * speed * this.mouseSensity;
934
+ const pitch = -dy * speed * this.mouseSensity;
935
+ this.player.rotateY(yaw);
936
+ this.camera.rotation.x = THREE.MathUtils.clamp(
937
+ this.camera.rotation.x + pitch,
938
+ -1.1,
939
+ 1.4
940
+ );
941
+ } else {
942
+ const sensitivity = this.mouseSensity;
943
+ const deltaX = -dx * speed * sensitivity;
944
+ const deltaY = -dy * speed * sensitivity;
945
+ const target = this.player.position.clone();
946
+ const distance = this.camera.position.distanceTo(target);
947
+ const currentPosition = this.camera.position.clone().sub(target);
948
+ let theta = Math.atan2(currentPosition.x, currentPosition.z);
949
+ let phi = Math.acos(currentPosition.y / distance);
950
+ theta += deltaX;
951
+ phi += deltaY;
952
+ phi = Math.max(0.1, Math.min(Math.PI - 0.1, phi));
953
+ const newX = distance * Math.sin(phi) * Math.sin(theta);
954
+ const newY = distance * Math.cos(phi);
955
+ const newZ = distance * Math.sin(phi) * Math.cos(theta);
956
+ this.camera.position.set(
957
+ target.x + newX,
958
+ target.y + newY,
959
+ target.z + newZ
960
+ );
961
+ this.camera.lookAt(target);
962
+ }
963
+ }
964
+ // 设置输入
965
+ setInput(input) {
966
+ if (typeof input.moveX === "number") {
967
+ this.lftPressed = input.moveX == -1;
968
+ this.rgtPressed = input.moveX == 1;
969
+ this.setAnimationByPressed();
970
+ }
971
+ if (typeof input.moveY === "number") {
972
+ this.fwdPressed = input.moveY == 1;
973
+ this.bkdPressed = input.moveY == -1;
974
+ this.setAnimationByPressed();
975
+ }
976
+ if (typeof input.lookDeltaX === "number" && typeof input.lookDeltaY === "number") {
977
+ this.setToward(input.lookDeltaX, input.lookDeltaY, 2e-3);
978
+ }
979
+ if (typeof input.jump === "boolean") {
980
+ if (input.jump) {
981
+ this.spacePressed = true;
982
+ if (!this.playerIsOnGround || this.isFlying) return;
983
+ this.playPersonAnimationByName("jumping");
984
+ this.playerVelocity.y = this.jumpHeight;
985
+ this.playerIsOnGround = false;
986
+ } else {
987
+ this.spacePressed = false;
988
+ }
989
+ }
990
+ if (typeof input.shift === "boolean") {
991
+ this.shiftPressed = input.shift;
992
+ }
993
+ if (input.toggleView) {
994
+ this.changeView();
995
+ }
996
+ if (input.toggleFly) {
997
+ this.isFlying = !this.isFlying;
998
+ this.setAnimationByPressed();
999
+ if (!this.isFlying && !this.playerIsOnGround)
1000
+ this.playPersonAnimationByName("jumping");
1001
+ }
1002
+ }
1003
+ // 初始化移动端摇杆控制
1004
+ async initMobileControls() {
1005
+ this.controls.maxPolarAngle = Math.PI * (300 / 360);
1006
+ this.controls.touches = { ONE: null, TWO: null };
1007
+ const mod = (await import("nipplejs")).default;
1008
+ const nipple = mod;
1009
+ const JOY_SIZE = 120;
1010
+ const container = document.body;
1011
+ this.joystickZoneEl = document.createElement("div");
1012
+ this.joystickZoneEl.id = "joy-zone";
1013
+ Object.assign(this.joystickZoneEl.style, {
1014
+ position: "absolute",
1015
+ left: "16px",
1016
+ bottom: "16px",
1017
+ width: `${JOY_SIZE + 40}px`,
1018
+ height: `${JOY_SIZE + 40}px`,
1019
+ touchAction: "none",
1020
+ zIndex: "999",
1021
+ pointerEvents: "auto",
1022
+ WebkitUserSelect: "none",
1023
+ userSelect: "none"
1024
+ });
1025
+ container.appendChild(this.joystickZoneEl);
1026
+ ["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
1027
+ (evtName) => {
1028
+ this.joystickZoneEl?.addEventListener(
1029
+ evtName,
1030
+ (e) => {
1031
+ e.preventDefault();
1032
+ },
1033
+ { passive: false }
1034
+ );
1035
+ }
1036
+ );
1037
+ this.joystickManager = nipple.create({
1038
+ zone: this.joystickZoneEl,
1039
+ mode: "static",
1040
+ position: {
1041
+ left: `${(JOY_SIZE + 40) / 2}px`,
1042
+ bottom: `${(JOY_SIZE + 40) / 2}px`
1043
+ },
1044
+ color: "#ffffff",
1045
+ size: JOY_SIZE,
1046
+ multitouch: true,
1047
+ maxNumberOfNipples: 1
1048
+ });
1049
+ this.joystickManager.on("move", (_evt, data) => {
1050
+ if (!data) return;
1051
+ const rawX = data.vector?.x ?? 0;
1052
+ const rawY = data.vector?.y ?? 0;
1053
+ const distance = data.distance ?? 0;
1054
+ const deadzone = 0.5;
1055
+ const dirX = rawX > deadzone ? 1 : rawX < -deadzone ? -1 : 0;
1056
+ const dirY = rawY > deadzone ? 1 : rawY < -deadzone ? -1 : 0;
1057
+ const sprintThreshold = JOY_SIZE / 2;
1058
+ const isSprinting = distance >= sprintThreshold;
1059
+ const prev = this.prevJoyState || { dirX: 0, dirY: 0, shift: false };
1060
+ if (dirX === prev.dirX && dirY === prev.dirY && isSprinting === prev.shift) {
1061
+ return;
1062
+ }
1063
+ this.prevJoyState = { dirX, dirY, shift: isSprinting };
1064
+ this.setInput({ moveX: dirX, moveY: dirY, shift: isSprinting });
1065
+ });
1066
+ this.joystickManager.on("end", () => {
1067
+ const prev = this.prevJoyState || { dirX: 0, dirY: 0, shift: false };
1068
+ if (prev.dirX !== 0 || prev.dirY !== 0 || prev.shift !== false) {
1069
+ this.prevJoyState = { dirX: 0, dirY: 0, shift: false };
1070
+ this.setInput({ moveX: 0, moveY: 0, shift: false });
1071
+ }
1072
+ });
1073
+ this.lookAreaEl = document.createElement("div");
1074
+ Object.assign(this.lookAreaEl.style, {
1075
+ position: "absolute",
1076
+ right: "0",
1077
+ bottom: "0",
1078
+ width: "50%",
1079
+ height: "100%",
1080
+ zIndex: "998",
1081
+ touchAction: "none",
1082
+ WebkitUserSelect: "none",
1083
+ userSelect: "none"
1084
+ });
1085
+ container.appendChild(this.lookAreaEl);
1086
+ ["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
1087
+ (evtName) => {
1088
+ this.lookAreaEl?.addEventListener(
1089
+ evtName,
1090
+ (e) => {
1091
+ e.preventDefault();
1092
+ },
1093
+ { passive: false }
1094
+ );
1095
+ }
1096
+ );
1097
+ this.lookAreaEl.addEventListener("pointerdown", this.onPointerDown, {
1098
+ passive: false
1099
+ });
1100
+ this.lookAreaEl.addEventListener("pointermove", this.onPointerMove, {
1101
+ passive: false
1102
+ });
1103
+ this.lookAreaEl.addEventListener("pointerup", this.onPointerUp, {
1104
+ passive: false
1105
+ });
1106
+ this.lookAreaEl.addEventListener("pointercancel", this.onPointerUp, {
1107
+ passive: false
1108
+ });
1109
+ const createBtn = (rightPx, bottomPx, bgUrl) => {
1110
+ const btn = document.createElement("button");
1111
+ const styles = {
1112
+ position: "absolute",
1113
+ right: `${rightPx}px`,
1114
+ bottom: `${bottomPx}px`,
1115
+ width: "56px",
1116
+ height: "56px",
1117
+ zIndex: "1000",
1118
+ borderRadius: "50%",
1119
+ border: "2px solid black",
1120
+ background: "rgba(0,0,0)",
1121
+ padding: "20px",
1122
+ opacity: "0.95",
1123
+ touchAction: "none",
1124
+ fontSize: "14px",
1125
+ userSelect: "none",
1126
+ overflow: "hidden",
1127
+ boxSizing: "border-box",
1128
+ backgroundColor: "transparent",
1129
+ backgroundRepeat: "no-repeat, no-repeat",
1130
+ backgroundPosition: "center center, center center",
1131
+ backgroundSize: "100% 100%, 80% 80%"
1132
+ };
1133
+ if (bgUrl) {
1134
+ const overlayColor = "rgba(0,0,0,0.5)";
1135
+ styles.backgroundImage = `linear-gradient(${overlayColor}, ${overlayColor}), url("${bgUrl}")`;
1136
+ }
1137
+ Object.assign(btn.style, styles);
1138
+ container.appendChild(btn);
1139
+ ["touchstart", "touchend", "touchcancel"].forEach((evtName) => {
1140
+ btn.addEventListener(
1141
+ evtName,
1142
+ (e) => {
1143
+ e.preventDefault();
1144
+ },
1145
+ { passive: false }
1146
+ );
1147
+ });
1148
+ return btn;
1149
+ };
1150
+ this.jumpBtnEl = createBtn(14, 14, jump_default);
1151
+ this.jumpBtnEl.addEventListener(
1152
+ "touchstart",
1153
+ (e) => {
1154
+ e.preventDefault();
1155
+ this.setInput({ jump: true });
1156
+ },
1157
+ { passive: false }
1158
+ );
1159
+ this.jumpBtnEl.addEventListener(
1160
+ "touchend",
1161
+ (e) => {
1162
+ e.preventDefault();
1163
+ this.setInput({ jump: false });
1164
+ },
1165
+ { passive: false }
1166
+ );
1167
+ this.jumpBtnEl.addEventListener(
1168
+ "touchcancel",
1169
+ (e) => {
1170
+ e.preventDefault();
1171
+ this.setInput({ jump: false });
1172
+ },
1173
+ { passive: false }
1174
+ );
1175
+ this.flyBtnEl = createBtn(14, 14 + 80, fly_default);
1176
+ this.flyBtnEl.addEventListener(
1177
+ "touchstart",
1178
+ (e) => {
1179
+ e.preventDefault();
1180
+ this.setInput({ toggleFly: true });
1181
+ },
1182
+ { passive: false }
1183
+ );
1184
+ this.viewBtnEl = createBtn(14, 14 + 200, view_default);
1185
+ this.viewBtnEl.addEventListener(
1186
+ "touchstart",
1187
+ (e) => {
1188
+ e.preventDefault();
1189
+ this.setInput({ toggleView: true });
1190
+ },
1191
+ { passive: false }
1192
+ );
1193
+ }
1194
+ // 销毁移动端摇杆控制
1195
+ destroyMobileControls() {
1196
+ try {
1197
+ if (this.joystickManager && this.joystickManager.destroy) {
1198
+ this.joystickManager.destroy();
1199
+ this.joystickManager = null;
1200
+ }
1201
+ if (this.joystickZoneEl?.parentElement) {
1202
+ this.joystickZoneEl.parentElement.removeChild(this.joystickZoneEl);
1203
+ this.joystickZoneEl = null;
1204
+ }
1205
+ if (this.lookAreaEl?.parentElement) {
1206
+ this.lookAreaEl.parentElement.removeChild(this.lookAreaEl);
1207
+ this.lookAreaEl = null;
1208
+ }
1209
+ if (this.jumpBtnEl?.parentElement) {
1210
+ this.jumpBtnEl.parentElement.removeChild(this.jumpBtnEl);
1211
+ this.jumpBtnEl = null;
1212
+ }
1213
+ if (this.flyBtnEl?.parentElement) {
1214
+ this.flyBtnEl.parentElement.removeChild(this.flyBtnEl);
1215
+ this.flyBtnEl = null;
1216
+ }
1217
+ if (this.viewBtnEl?.parentElement) {
1218
+ this.viewBtnEl.parentElement.removeChild(this.viewBtnEl);
1219
+ this.viewBtnEl = null;
1220
+ }
1221
+ this.lookAreaEl?.removeEventListener("pointerdown", this.onPointerDown);
1222
+ this.lookAreaEl?.removeEventListener("pointermove", this.onPointerMove);
1223
+ this.lookAreaEl?.removeEventListener("pointerup", this.onPointerUp);
1224
+ this.lookAreaEl?.removeEventListener("pointercancel", this.onPointerUp);
1225
+ } catch (e) {
1226
+ console.warn("\u9500\u6BC1\u79FB\u52A8\u7AEF\u6447\u6746\u63A7\u5236\u65F6\u51FA\u9519\uFF1A", e);
1227
+ }
1228
+ }
894
1229
  };
895
1230
  function playerController() {
896
1231
  if (!controllerInstance) controllerInstance = new PlayerController();
@@ -900,7 +1235,8 @@ function playerController() {
900
1235
  changeView: () => c.changeView(),
901
1236
  reset: (pos) => c.reset(pos),
902
1237
  update: (dt) => c.update(dt),
903
- destroy: () => c.destroy()
1238
+ destroy: () => c.destroy(),
1239
+ setInput: (i) => c.setInput(i)
904
1240
  };
905
1241
  }
906
1242
  function onAllEvent() {