day 4
This commit is contained in:
@@ -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
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum BaseAnimation {
|
||||
Nan = -1,
|
||||
Idle = 0,
|
||||
Run = 1,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export enum MeshType {
|
||||
Character = "character",
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export enum ResourcesType {
|
||||
Mesh = "mesh",
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Vector3 } from "three";
|
||||
|
||||
export interface IMoveInput {
|
||||
get CurrentDirection(): Vector3;
|
||||
update(delta);
|
||||
}
|
||||
@@ -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<number>;
|
||||
private StartDelegate: Delegate<any>;
|
||||
private MoveDelegate: Delegate<any>;
|
||||
private StopDelegate: Delegate<any>;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<number>;
|
||||
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<number>(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<number[]>("global", "camera_position_p")
|
||||
: Template.getValue<number[]>("global", "camera_position_l");
|
||||
const offset = Helper.returnVectorCamera(values);
|
||||
return offset
|
||||
}
|
||||
}
|
||||
@@ -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<number>;
|
||||
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<number>(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);
|
||||
}
|
||||
}
|
||||
@@ -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<number>;
|
||||
private currentQ: Quaternion = new Quaternion();
|
||||
private targetQ: Quaternion = new Quaternion();
|
||||
|
||||
constructor(target: Object3D, Input: IMoveInput, speed: number = 5) {
|
||||
this.updateDelegate = new Delegate<number>(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);
|
||||
}
|
||||
}
|
||||
@@ -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<number>;
|
||||
|
||||
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<GLTF>(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<number>((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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
// this.createPrimitive();
|
||||
Map.Init();
|
||||
this.InitPlayer();
|
||||
|
||||
// example of using InputC events
|
||||
InputC.onTouchDown.addDelegate((event) => {
|
||||
console.log("onMouseDown", event);
|
||||
});
|
||||
// InputC.onTouchDown.addDelegate((event) => {
|
||||
// console.log("onMouseDown", event);
|
||||
// });
|
||||
|
||||
// Update loop to follow character with camera
|
||||
UpdateController.Instance.onUpdate.addDelegate(() => {
|
||||
this.updateCameraFollow();
|
||||
});
|
||||
// if you have update in your controller
|
||||
// UpdateController.Instance.onUpdate.addDelegate(() => {
|
||||
// this.update();
|
||||
// });
|
||||
}
|
||||
|
||||
private static loadMapModel() {
|
||||
const mapObject = ThreeC.getObject("map");
|
||||
if (!mapObject) {
|
||||
console.warn("Map model resource not found: map");
|
||||
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);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
mapObject.position.set(0, 0, 0);
|
||||
|
||||
ThreeC.setShadowsStateForChildren(mapObject, true, true);
|
||||
ThreeC.addToScene(mapObject);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private static loadCharacter() {
|
||||
const charObject = ThreeC.getObject("character");
|
||||
if (!charObject) {
|
||||
console.warn("Character model resource not found: character");
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,8 +24,10 @@ 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
|
||||
|
||||
|
||||
+4949
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user