diff --git a/src/configUIParams/globalSettings.ts b/src/configUIParams/globalSettings.ts index 74a1702..9feefba 100644 --- a/src/configUIParams/globalSettings.ts +++ b/src/configUIParams/globalSettings.ts @@ -3,7 +3,7 @@ import { ConfigUiParamsCategories } from "@24tools/ads_common"; export const globalSettings: ConfigUiParamsCategories[] = [ { id: "global", - name: "Scene settings", + name: "Global settings", params: [ { id: "light_intensity", @@ -30,7 +30,7 @@ export const globalSettings: ConfigUiParamsCategories[] = [ values: [ 30, 150, - 60 + 50 ] }, { @@ -43,17 +43,17 @@ export const globalSettings: ConfigUiParamsCategories[] = [ [ -10, 10, - 0 + 6 + ], + [ + 0, + 8, + 9 ], [ -10, 10, - 1 - ], - [ - -10, - 10, - 5 + 7 ] ] }, @@ -67,7 +67,7 @@ export const globalSettings: ConfigUiParamsCategories[] = [ [ -360, 360, - 0 + -5 ], [ -360, @@ -88,7 +88,7 @@ export const globalSettings: ConfigUiParamsCategories[] = [ values: [ 30, 150, - 60 + 55 ] }, { @@ -101,17 +101,17 @@ export const globalSettings: ConfigUiParamsCategories[] = [ [ -10, 10, - 0 + 2 ], [ - -10, - 10, - 1 - ], - [ - -10, - 10, + 0, + 8, 5 + ], + [ + -10, + 10, + 3 ] ] }, diff --git a/src/controllers/CameraC.ts b/src/controllers/CameraC.ts index 77644de..5bae09f 100644 --- a/src/controllers/CameraC.ts +++ b/src/controllers/CameraC.ts @@ -1,20 +1,16 @@ import { CameraC_internal, Helper, Template } from "@24tools/playable_template"; -import { PerspectiveCamera, Vector3 } from "three"; +import { PerspectiveCamera } from "three"; export class CameraC extends CameraC_internal { static setCamera(portraitOrientation: boolean) { const CATEGORY = Template.getCategory("global"); if (this.camera !== null) { - let position = portraitOrientation - ? Helper.returnVectorCamera(CATEGORY["camera_position_p"] as number[]) - : Helper.returnVectorCamera(CATEGORY["camera_position_l"] as number[]); const rotation = portraitOrientation ? Helper.returnEulerCamera(CATEGORY["camera_rotation_p"] as number[]) : Helper.returnEulerCamera(CATEGORY["camera_rotation_l"] as number[]); this.camera.rotation.x = rotation.x; this.camera.rotation.y = rotation.y; this.camera.rotation.z = rotation.z; - this.camera.position.copy(position.clone()); if (this.camera instanceof PerspectiveCamera) { this.camera.fov = portraitOrientation ? Number(CATEGORY["camera_fov_p"]) @@ -23,16 +19,4 @@ export class CameraC extends CameraC_internal { } } } - - static setTopDownCamera() { - if (this.camera !== null) { - this.camera.position.set(20, 10, -5); - this.camera.rotation.set(-5 * Math.PI / 12, 0, 0); - this.camera.lookAt(new Vector3(0, 0, 0)); - if (this.camera instanceof PerspectiveCamera) { - this.camera.fov = 55; - this.camera.updateProjectionMatrix(); - } - } - } } diff --git a/src/controllers/Map/Map.ts b/src/controllers/Map/Map.ts new file mode 100644 index 0000000..3f1726d --- /dev/null +++ b/src/controllers/Map/Map.ts @@ -0,0 +1,32 @@ +import { Object3D } from "three"; +import { ThreeC } from "../ThreeC"; +import { PhysicsBody, PhysicsLayer } from "../PhysicsC"; + +export class Map { + static Init() { + const mapObject = ThreeC.getObject("map"); + if (!mapObject) { + console.warn("Map model resource not found: map"); + return; + } + + mapObject.position.set(0, 0, 0); + ThreeC.setShadowsStateForChildren(mapObject, true, true); + ThreeC.addToScene(mapObject); + + const colliders = mapObject.getObjectByName("Colliders"); + if (colliders) { + colliders.visible = false; + this.buildColliders(colliders); + } + } + + private static buildColliders(collidersRoot: Object3D) { + collidersRoot.traverse((child) => { + if (child === collidersRoot) return; + if ((child as any).isMesh) { + new PhysicsBody(child, false, 0, PhysicsLayer.Wall, PhysicsLayer.Player); + } + }); + } +} diff --git a/src/controllers/Presets/Character/Character.ts b/src/controllers/Presets/Character/Character.ts new file mode 100644 index 0000000..4f2b343 --- /dev/null +++ b/src/controllers/Presets/Character/Character.ts @@ -0,0 +1,77 @@ +import { EasyEvent } from "@24tools/playable_template"; +import { AnimationAction, AnimationClip, AnimationMixer, Color, LoopOnce, LoopRepeat, Mesh, MeshBasicMaterial, Object3D, Vector3 } from "three"; +import { clone } from "three/examples/jsm/utils/SkeletonUtils"; +import { ThreeC } from "../../ThreeC"; +import { GLTF } from "three/examples/jsm/loaders/GLTFLoader"; + +export class Character { + tObj: Object3D; + animMixer: AnimationMixer; + animationList: AnimationClip[] = []; + + // isWalking: boolean = false; + curClipAction: null | AnimationAction = null; + animStopTimeout: null | NodeJS.Timeout = null + + onAnimLoop: EasyEvent<{}> = new EasyEvent<{}>(); + onAnimFinish: EasyEvent<{}> = new EasyEvent<{}>(); + + constructor(prefab: GLTF, start_position = new Vector3()) { + let tObj = clone(prefab.scene); + + tObj.castShadow = true; + let animMixer = new AnimationMixer(tObj); + + animMixer.addEventListener('loop', () => { + this.onAnimLoop.Invoke({}); + }); + animMixer.addEventListener('finished', () => { + this.onAnimFinish.Invoke({}); + }); + + if (start_position) tObj.position.copy(start_position); + + this.tObj = tObj; + this.animMixer = animMixer; + this.animationList = prefab.animations; + + ThreeC.addToScene(tObj); + ThreeC.addAnimMixer(animMixer); + + return this; + } + + set AnimationSpeed(timeScale: number) { + if (this.curClipAction) + this.curClipAction.timeScale = timeScale; + } + + set AnimationWeight(weight: number) { + if (this.curClipAction) + this.curClipAction.weight = weight; + } + + playAnimation(anim_id: number, one_time: boolean = false, fade = 0.25, randomStart = false) { + let oldClipAction: null | AnimationAction = this.curClipAction; + var clipAction = this.animMixer.clipAction(this.animationList[anim_id]); + + if (one_time) { + clipAction.clampWhenFinished = true; + clipAction.setLoop(LoopOnce, 1); + } + else { + clipAction.clampWhenFinished = false; + clipAction.setLoop(LoopRepeat, Infinity); + } + clipAction.timeScale = 1; + clipAction.weight = 1; + + clipAction.reset(); + if (randomStart) + clipAction.time = Math.random() * this.animationList[anim_id].duration; + clipAction.play(); + if (oldClipAction && oldClipAction != clipAction) + oldClipAction.crossFadeTo(clipAction, fade, true); + this.curClipAction = clipAction; + } +} \ No newline at end of file diff --git a/src/controllers/Presets/Enums/BaseAnimation.ts b/src/controllers/Presets/Enums/BaseAnimation.ts new file mode 100644 index 0000000..c4a7f90 --- /dev/null +++ b/src/controllers/Presets/Enums/BaseAnimation.ts @@ -0,0 +1,5 @@ +export enum BaseAnimation { + Nan = -1, + Idle = 0, + Run = 1, +} \ No newline at end of file diff --git a/src/controllers/Presets/Enums/MeshType.ts b/src/controllers/Presets/Enums/MeshType.ts new file mode 100644 index 0000000..bdeae7f --- /dev/null +++ b/src/controllers/Presets/Enums/MeshType.ts @@ -0,0 +1,3 @@ +export enum MeshType { + Character = "character", +} \ No newline at end of file diff --git a/src/controllers/Presets/Enums/ResourcesType.ts b/src/controllers/Presets/Enums/ResourcesType.ts new file mode 100644 index 0000000..16791d8 --- /dev/null +++ b/src/controllers/Presets/Enums/ResourcesType.ts @@ -0,0 +1,3 @@ +export enum ResourcesType { + Mesh = "mesh", +} \ No newline at end of file diff --git a/src/controllers/Presets/Helper.ts b/src/controllers/Presets/Helper.ts new file mode 100644 index 0000000..5f410f5 --- /dev/null +++ b/src/controllers/Presets/Helper.ts @@ -0,0 +1,16 @@ +import { Vec3 } from "cannon-es"; +import { Vector3 } from "three"; + +/** + * Vec3(cannon) To Vector3(three) + */ +export function Vector3CToT(value: Vec3) { + return new Vector3(value.x, value.y, value.z); +} + +/** + * Vector3(three) To Vec3(cannon) + */ +export function Vector3TToC(value: Vector3) { + return new Vec3(value.x, value.y, value.z); +} \ No newline at end of file diff --git a/src/controllers/Presets/Input/MoveInput.ts b/src/controllers/Presets/Input/MoveInput.ts new file mode 100644 index 0000000..0e2cdc8 --- /dev/null +++ b/src/controllers/Presets/Input/MoveInput.ts @@ -0,0 +1,6 @@ +import { Vector3 } from "three"; + +export interface IMoveInput { + get CurrentDirection(): Vector3; + update(delta); +} \ No newline at end of file diff --git a/src/controllers/Presets/Input/PlayerInput.ts b/src/controllers/Presets/Input/PlayerInput.ts new file mode 100644 index 0000000..9b5b690 --- /dev/null +++ b/src/controllers/Presets/Input/PlayerInput.ts @@ -0,0 +1,108 @@ +import { Delegate, JoystickC, UpdateController } from "@24tools/playable_template"; +import { Vector3 } from "three"; +import { IMoveInput } from "./MoveInput"; +import { FollowCameraC } from "../Movment/CameraMovment/FollowCamera"; + +// type JoystickVectorData = { +// vector?: { +// x: number; +// y: number; +// }; +// }; + +// type JoystickPayload = { +// event?: Event; +// data?: JoystickVectorData; +// }; + +export class PlayerInput implements IMoveInput { + + + public static InitJoystick() { + const screenSize = window.screenSize; + const minSize = Math.min(screenSize.width, screenSize.height); + const joystickSizeAspect = 0.2; + const fadeTime = 200; + const options = { + zone: document.getElementById("joystick_zone") as HTMLElement, + size: minSize * joystickSizeAspect, + restJoystick: true, + dynamicPage: true, + catchDistance: minSize * joystickSizeAspect / 2, + fadeTime: fadeTime, + }; + JoystickC.init(options); + + // JoystickC.onJoysticMove.addDelegate(({ event, data }) => { + // console.log('onJoysticMove', event, data); + // }) + } + + protected currentDirection: Vector3 = new Vector3(); + private updateDelegate: Delegate; + private StartDelegate: Delegate; + private MoveDelegate: Delegate; + private StopDelegate: Delegate; + private static threshold = 0.25; + + get CurrentDirection() { return this.currentDirection.clone(); }; + + inputaActive: boolean = false; + + + constructor() { + this.updateDelegate = UpdateController.Instance.onUpdate.addDelegate(this.update.bind(this)); + + this.MoveDelegate = JoystickC.onJoysticMove.addDelegate(this.onTouchMove.bind(this)); + // "down" also carries joystick data in this SDK, useful for first non-zero direction. + JoystickC.onJoysticDown.addListener(this.MoveDelegate); + + this.StopDelegate = JoystickC.onJoysticEnd.addDelegate(this.onTouchUp.bind(this)); + + + this.StartDelegate = JoystickC.onJoysticStart.addDelegate(this.onTouchDown.bind(this)); + } + + update(delta: number) { + + } + + onTouchMove(payload: any) { + this.currentDirection = this.GetDiraction(payload); + if (this.currentDirection.length() <= PlayerInput.threshold) + this.currentDirection.multiplyScalar(0); + } + + onTouchDown(_event: any) { + // console.log(event); + + if (this.inputaActive) return; + this.inputaActive = true; + } + + onTouchUp() { + if (!this.inputaActive) return; + this.inputaActive = false; + this.currentDirection.multiplyScalar(0); + } + + GetDiraction(payload: any) { + // Compatible with old/new nipplejs payloads wrapped by JoystickC: + // - { event, data } where data.vector exists + // - { event, data: undefined } where event.data.vector exists + const normalizedData = + payload?.data ?? + payload?.event?.data ?? + payload?.event; + const vector = normalizedData?.vector; + if (!vector) return new Vector3(); + + const x = vector.x; + const y = vector.y; + const dir = new Vector3(-x, 0, y); + dir.applyEuler(FollowCameraC.RotationCorection); + + return dir; + } + +} \ No newline at end of file diff --git a/src/controllers/Presets/Movment/CameraMovment/FollowCamera.ts b/src/controllers/Presets/Movment/CameraMovment/FollowCamera.ts new file mode 100644 index 0000000..1e789f5 --- /dev/null +++ b/src/controllers/Presets/Movment/CameraMovment/FollowCamera.ts @@ -0,0 +1,93 @@ +import { Delegate, Helper, Template, UpdateController } from "@24tools/playable_template"; +import { Object3D, Vector3 } from "three"; +import { ThreeC } from "../../../ThreeC"; +import { CameraC } from "../../../CameraC"; + +export class FollowCameraC { + private static updateDelegate: Delegate; + static target: Object3D; + static offset: Vector3; + + static mainContainer: Object3D = new Object3D(); + static cameraContainer: Object3D = new Object3D(); + static cameraRotation: Object3D = new Object3D(); + + /** Normalized movement direction set each frame by the player */ + static inputDirection: Vector3 = new Vector3(); + /** How far (world units) the camera shifts ahead of the player */ + static lookAheadAmount: number = 2; + /** Lerp speed for the look-ahead offset (lower = smoother/slower) */ + static lookAheadLerpSpeed: number = 0.7; + + private static lookAheadCurrent: Vector3 = new Vector3(); + + static Init(target: Object3D) { + this.target = target; + this.offset = this.Offset; + + console.log(target); + + + this.updateDelegate = new Delegate(this.Update.bind(this)); + UpdateController.Instance.onUpdate.addListener(this.updateDelegate); + + ThreeC.addToScene(this.mainContainer); + this.mainContainer.add(this.cameraContainer); + this.cameraContainer.add(this.cameraRotation); + this.cameraRotation.add(CameraC.cameraContainer); + + this.cameraRotation.rotateY(Math.PI); + + this.mainContainer.position.copy(target.position); + this.mainContainer.position.x += this.Offset.x; + this.mainContainer.position.z += this.Offset.z; + + this.cameraContainer.position.y += this.Offset.y; + } + + private static Update(delta: number) { + if (!this.target.position) return; + + // Lerp look-ahead toward current movement direction (stays at last direction when stopped) + const lookAheadTarget = this.inputDirection.clone().multiplyScalar(this.lookAheadAmount); + this.lookAheadCurrent.lerp(lookAheadTarget, delta * this.lookAheadLerpSpeed); + + const offset = this.Offset; + + // Base position without look-ahead + const basePos = this.target.position.clone(); + basePos.x += offset.x; + basePos.z += offset.z; + + // Final target = base + look-ahead shift + const targetPos = basePos.clone(); + targetPos.x += this.lookAheadCurrent.x; + targetPos.z += this.lookAheadCurrent.z; + + // Capture actual previous position BEFORE any mutation + const oldPos = this.mainContainer.position.clone(); + + // Compute rotation using base position to avoid tilt from look-ahead offset + this.mainContainer.position.copy(basePos); + this.mainContainer.lookAt(this.target.position); + this.cameraContainer.lookAt(this.target.position); + + // Smooth follow lerp from real previous position toward target with look-ahead + const lerpSpeed = 10; + this.mainContainer.position.lerpVectors(oldPos, targetPos, delta * lerpSpeed); + } + + static get RotationCorection() { + const rotation = this.mainContainer.rotation.clone(); + return rotation; + } + + static get Offset() { + const portrait = window.screenSize.portrait + const values = portrait + ? Template.getValue("global", "camera_position_p") + : Template.getValue("global", "camera_position_l"); + const offset = Helper.returnVectorCamera(values); + return offset + } +} \ No newline at end of file diff --git a/src/controllers/Presets/Movment/MoveC.ts b/src/controllers/Presets/Movment/MoveC.ts new file mode 100644 index 0000000..c8c5379 --- /dev/null +++ b/src/controllers/Presets/Movment/MoveC.ts @@ -0,0 +1,25 @@ +import { Delegate, UpdateController } from "@24tools/playable_template"; +import { IMoveInput } from "../Input/MoveInput"; +import { Vector3 } from "three"; + +export class MoveC { + private input: IMoveInput; + private speed: number = 5; + private updateDelegate: Delegate; + private moveDiraction: Vector3 = new Vector3(); + get Diraction() { return this.moveDiraction }; + get Weight() { return this.moveDiraction.length() / this.speed }; + + constructor(Input: IMoveInput, speed: number = 5) { + this.updateDelegate = new Delegate(this.update.bind(this)); + UpdateController.Instance.onUpdate.addListener(this.updateDelegate); + this.input = Input; + this.speed = speed; + } + + private update(delta: number) { + // delta *= TimeC.TimeScale; + const moveStep = this.input.CurrentDirection.multiplyScalar(this.speed); + this.moveDiraction.copy(moveStep); + } +} \ No newline at end of file diff --git a/src/controllers/Presets/Movment/RotationC.ts b/src/controllers/Presets/Movment/RotationC.ts new file mode 100644 index 0000000..f778f33 --- /dev/null +++ b/src/controllers/Presets/Movment/RotationC.ts @@ -0,0 +1,35 @@ +import { Delegate, UpdateController } from "@24tools/playable_template"; +import { IMoveInput } from "../Input/MoveInput"; +import { Object3D, Quaternion, Vector3 } from "three"; + +export class RotationC { + private target: Object3D; + private input: IMoveInput; + private speed: number = 5; + private updateDelegate: Delegate; + private currentQ: Quaternion = new Quaternion(); + private targetQ: Quaternion = new Quaternion(); + + constructor(target: Object3D, Input: IMoveInput, speed: number = 5) { + this.updateDelegate = new Delegate(this.update.bind(this)); + UpdateController.Instance.onUpdate.addListener(this.updateDelegate); + this.input = Input; + this.speed = speed; + this.target = target; + this.currentQ.copy(this.target.quaternion); + this.targetQ.copy(this.target.quaternion); + } + + private update(delta: number) { + const loockAtStep = this.input.CurrentDirection; + if (loockAtStep.length() != 0) { + const loockAtPoint = this.target.position.clone().add(loockAtStep); + this.target.lookAt(loockAtPoint); + this.targetQ.copy(this.target.quaternion); + this.target.quaternion.copy(this.currentQ); + } + + this.target.quaternion.slerp(this.targetQ, delta * this.speed); + this.currentQ.copy(this.target.quaternion); + } +} \ No newline at end of file diff --git a/src/controllers/Presets/Player.ts b/src/controllers/Presets/Player.ts new file mode 100644 index 0000000..26164da --- /dev/null +++ b/src/controllers/Presets/Player.ts @@ -0,0 +1,117 @@ +import { Delegate, ResourcesC, UpdateController } from "@24tools/playable_template"; +import { Character } from "./Character/Character"; +import { ResourcesType } from "./Enums/ResourcesType"; +import { MeshType } from "./Enums/MeshType"; +import { GLTF } from "three/examples/jsm/loaders/GLTFLoader"; +import { BaseAnimation } from "./Enums/BaseAnimation"; +import { PhysicsBody, PhysicsLayer } from "../PhysicsC"; +import { Object3D } from "three"; +import { ThreeC } from "../ThreeC"; +import { PlayerInput } from "./Input/PlayerInput"; +import { MoveC } from "./Movment/MoveC"; +import { Vec3 } from "cannon-es"; +import { contain } from "three/src/extras/TextureUtils"; +import { Vector3CToT, Vector3TToC } from "./Helper"; +import { RotationC } from "./Movment/RotationC"; +import { FollowCameraC } from "./Movment/CameraMovment/FollowCamera"; +import { Vector3 } from "three"; + +export class Player { + private static inited: boolean = false; + private static isRunning: boolean = false; + + private static updateDelegate: Delegate; + + private static container: Object3D = new Object3D; + private static input: PlayerInput; + private static movement: MoveC; + private static rotation: RotationC; + private static spawnPosition: Vector3 = new Vector3(0, 0, 0); + + static character: Character; + static physics: PhysicsBody; + + static SetSpawnPosition(position: Vector3) { + this.spawnPosition.copy(position); + } + + static Init() { + if (this.inited) return; + this.inited = true + const asset = ResourcesC.getResource(ResourcesType.Mesh, MeshType.Character) + this.character = new Character(asset); + + this.container.position.copy(this.spawnPosition); + this.character.playAnimation(BaseAnimation.Idle) + this.container.add(this.character.tObj); + ThreeC.addToScene(this.container); + + this.InitPhisic(); + const input = new PlayerInput(); + const moveSpeed = 3; + const rotationSpeed = 8; + this.movement = new MoveC(input, moveSpeed); + this.rotation = new RotationC(this.container, input, rotationSpeed); + + this.updateDelegate = new Delegate((delta) => this.Update(delta)); + UpdateController.Instance.onUpdate.addListener(this.updateDelegate); + + FollowCameraC.Init(this.container); + } + + private static InitPhisic() { + this.physics = new PhysicsBody( + this.container, + false, + 1, + PhysicsLayer.Player, + PhysicsLayer.Wall, + ); + } + + private static StartRunning() { + if (this.isRunning) return; + this.character.playAnimation(BaseAnimation.Run); + this.isRunning = true; + } + private static StopRunning() { + if (!this.isRunning) return; + this.character.playAnimation(BaseAnimation.Idle); + this.AnimationValue = 1; + this.isRunning = false; + } + + private static set AnimationValue(value: number) { + this.character.AnimationSpeed = value; + this.character.AnimationWeight = value * 12.5 + 87.5; + } + + private static Update(delta: number) { + const diraction = this.movement.Diraction; + const weight = this.movement.Weight; + + if (diraction.length() > 0) { + this.StartRunning(); + this.AnimationValue = weight; + FollowCameraC.inputDirection.copy(diraction).normalize(); + } else { + this.StopRunning(); + } + + + + const cPos = Vector3TToC(diraction); + + this.physics.getPhysicsBody().velocity.copy(cPos); + this.MoveVisual(delta); + } + + private static MoveVisual(delta: number) { + const lerpSpeed = 10; + const targetPos = (Vector3CToT(this.physics.getPhysicsBody().position)); + + this.container.position.lerp(targetPos, delta * lerpSpeed) + } + + +} \ No newline at end of file diff --git a/src/controllers/TestSceneC.ts b/src/controllers/TestSceneC.ts index 62bfbc5..8501e71 100644 --- a/src/controllers/TestSceneC.ts +++ b/src/controllers/TestSceneC.ts @@ -1,72 +1,52 @@ -import { DirectionalLight, Object3D, Vector3, Mesh, Material } from "three"; +import { BoxGeometry, Mesh, MeshStandardMaterial, Vector3 } from "three"; import { ThreeC } from "./ThreeC"; -import { CameraC } from "./CameraC"; -import { InputC, UpdateController } from "@24tools/playable_template"; +import { InputC, JoystickC } from "@24tools/playable_template"; +import { Player } from "./Presets/Player"; +import { PhysicsBody, PhysicsLayer } from "./PhysicsC"; +import { Map } from "./Map/Map"; export class TestSceneC { - private static character: Object3D | null = null; - static init() { - this.loadMapModel(); - this.loadCharacter(); - - // example of using InputC events - InputC.onTouchDown.addDelegate((event) => { - console.log("onMouseDown", event); - }); - - // Update loop to follow character with camera - UpdateController.Instance.onUpdate.addDelegate(() => { - this.updateCameraFollow(); - }); - } - - private static loadMapModel() { - const mapObject = ThreeC.getObject("map"); - if (!mapObject) { - console.warn("Map model resource not found: map"); - return; - } - - mapObject.position.set(0, 0, 0); + // this.createPrimitive(); + Map.Init(); + this.InitPlayer(); - ThreeC.setShadowsStateForChildren(mapObject, true, true); - ThreeC.addToScene(mapObject); - } - + // example of using InputC events + // InputC.onTouchDown.addDelegate((event) => { + // console.log("onMouseDown", event); + // }); - private static updateCameraFollow() { - if (!this.character || !CameraC.camera) return; - - // Position camera at 75 degree angle from horizontal, slightly to the side - const charPos = this.character.position; - const angle = 70 * (Math.PI / 180); // 75 degrees - const distance = 10; - const sideOffset = 5; // offset to the left side - - // Calculate vertical and horizontal distances based on 75 degree angle - const verticalDistance = distance * Math.sin(angle); - const horizontalDistance = distance * Math.cos(angle); - - CameraC.camera.position.set( - charPos.x + sideOffset, - charPos.y + verticalDistance, - charPos.z + horizontalDistance - ); - CameraC.camera.lookAt(charPos.x, charPos.y + 1, charPos.z); + // if you have update in your controller + // UpdateController.Instance.onUpdate.addDelegate(() => { + // this.update(); + // }); } - private static loadCharacter() { - const charObject = ThreeC.getObject("character"); - if (!charObject) { - console.warn("Character model resource not found: character"); - return; - } + // private static createPrimitive() { + // const planeSize = new Vector3(10, 0.1, 10); + // const geometryPlane = new BoxGeometry(planeSize.x, planeSize.y, planeSize.z); + // const materialPlane = new MeshStandardMaterial({ color: 0xaaaaaa }); + // const plane = new Mesh(geometryPlane, materialPlane); - // Place character near the map center; adjust Y for ground offset - charObject.position.copy(new Vector3(0, 0, 32)); - this.character = charObject; - ThreeC.setShadowsStateForChildren(charObject, true, true); - ThreeC.addToScene(charObject); + // ThreeC.setShadowsStateForChildren(plane, false, true); + + // plane.position.y = -planeSize.y / 2; + + // new PhysicsBody( + // plane, + // false, + // 0, + // PhysicsLayer.Wall, + // PhysicsLayer.Player, + // ); + + // ThreeC.addToScene(plane); + // } + + private static InitPlayer() { + const playerSpawnPoint = new Vector3(4, 0, 27); + Player.SetSpawnPosition(playerSpawnPoint); + Player.Init(); } + } diff --git a/src/index.ts b/src/index.ts index 4eb2600..3b658bb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,7 +16,7 @@ window.setupConfig = async function (config) { redirectOptions: {}, ticker: Template3d.ticker, debug: { - physics: false, + physics: true, // set true if you want to enable physics debugger logger: false // set true if you want to enable logger } diff --git a/src/templateConfig/beforeResourcesLoadedCb.ts b/src/templateConfig/beforeResourcesLoadedCb.ts index 5507c3d..8953deb 100644 --- a/src/templateConfig/beforeResourcesLoadedCb.ts +++ b/src/templateConfig/beforeResourcesLoadedCb.ts @@ -1,7 +1,7 @@ import { CameraC_internal, CameraType, - // JoystickC, + JoystickC, Physics_internal, Template, Template3d, @@ -11,6 +11,7 @@ import { } from "@24tools/playable_template"; import { CameraC } from "../controllers/CameraC"; import { ThreeC } from "../controllers/ThreeC"; +import { PlayerInput } from "../controllers/Presets/Input/PlayerInput"; import { Color } from "three"; import { Vec3 } from "cannon-es"; export const beforeResourcesLoadedCb = () => { @@ -23,20 +24,22 @@ export const beforeResourcesLoadedCb = () => { ThreeC_internal.init(); ThreeC.createBaseLights(); ThreeC.setupDirectionalLight(); + PlayerInput.InitJoystick(); - let physicsWorld = Physics_internal.init(new Vec3(0, -9.81, 0)); + + let physicsWorld = Physics_internal.init(new Vec3(0, 0, 0)); // example of using joystick. Uncomment if you need joystick - // JoystickC.init({ - // zone: document.getElementById("joystick_zone") as HTMLDivElement, - // fadeTime: 0, - // mode: "dynamic", - // restJoystick: true, - // catchDistance: 1, - // restOpacity: 0, - // follow: false, - // }); + // JoystickC.init({ + // zone: document.getElementById("joystick_zone") as HTMLDivElement, + // fadeTime: 0, + // mode: "dynamic", + // restJoystick: true, + // catchDistance: 1, + // restOpacity: 0, + // follow: false, + // }); // JoystickC.onJoysticMove.addDelegate(({event, data}) => { // console.log('onJoysticMove', event, data); diff --git a/stats.html b/stats.html new file mode 100644 index 0000000..e03defd --- /dev/null +++ b/stats.html @@ -0,0 +1,4949 @@ + + + + + + + + Rollup Visualizer + + + +
+ + + + +