Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/client/core/Game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ export class Game {
this.shotHandler,
this.renderer,
this.inputHandler,
this.collisionManager,
this.networking,
this.localPlayer,
);
this.chatOverlay.setNetworking(this.networking);
this.chatOverlay.setInputHandler(this.inputHandler);
this.mapLoader = new MapLoader(this.renderer);
this.healthIndicator = new HealthIndicator(this.renderer, this.localPlayer, this.networking);
this.remoteItemRenderer = new RemoteItemRenderer(this.networking, this.renderer, this.shotHandler);
this.remoteItemRenderer = new RemoteItemRenderer(
this.networking,
this.renderer,
this.shotHandler,
this.collisionManager,
);
}

init() {
Expand Down
6 changes: 5 additions & 1 deletion src/client/core/Inventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import { Pipe } from '../items/Pipe.ts';
import { FlagItem } from '../items/FlagItem.ts';
import { ShotHandler } from './ShotHandler.ts';
import { Sniper } from '../items/Sniper.ts';
import { CollisionManager } from '../input/CollisionManager.ts';
export class Inventory {
private inventoryItems: ItemBase[] = [];
private renderer: Renderer;
private inputHandler: InputHandler;
private readonly collisionManager: CollisionManager;
private networking: Networking;
private shotHandler: ShotHandler;
private inventoryScene: THREE.Scene;
Expand All @@ -38,12 +40,14 @@ export class Inventory {
shotHandler: ShotHandler,
renderer: Renderer,
inputHandler: InputHandler,
collisionManager: CollisionManager,
networking: Networking,
localPlayer: Player,
) {
this.shotHandler = shotHandler;
this.renderer = renderer;
this.inputHandler = inputHandler;
this.collisionManager = collisionManager;
this.networking = networking;
this.inventoryScene = renderer.getInventoryMenuScene();
this.clock = new THREE.Clock();
Expand Down Expand Up @@ -85,7 +89,7 @@ export class Inventory {
break;
}
case 2: {
const fish = new FishGun(this.renderer, this.shotHandler, i, ItemType.InventoryItem);
const fish = new FishGun(this.renderer, this.shotHandler, this.collisionManager, i, ItemType.InventoryItem);
this.inventoryItems.push(fish);
break;
}
Expand Down
12 changes: 10 additions & 2 deletions src/client/core/RemoteItemRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Pipe } from '../items/Pipe.ts';
import { FlagItem } from '../items/FlagItem.ts';
import { ShotHandler } from './ShotHandler.ts';
import { Sniper } from '../items/Sniper.ts';
import { CollisionManager } from '../input/CollisionManager.ts';

// Custom types
type Vector3Data = {
Expand All @@ -31,12 +32,19 @@ export class RemoteItemRenderer {
private shotHandler: ShotHandler;
private networking: Networking;
private renderer: Renderer;
private collisionManager: CollisionManager;
private itemsToRender: ItemsToRenderEntry[] = [];

constructor(networking: Networking, renderer: Renderer, shotHandler: ShotHandler) {
constructor(
networking: Networking,
renderer: Renderer,
shotHandler: ShotHandler,
collisionManager: CollisionManager,
) {
this.networking = networking;
this.renderer = renderer;
this.shotHandler = shotHandler;
this.collisionManager = collisionManager;
}

public update() {
Expand Down Expand Up @@ -93,7 +101,7 @@ export class RemoteItemRenderer {
case 1:
return new BananaGun(this.renderer, this.shotHandler, 0, ItemType.WorldItem);
case 2:
return new FishGun(this.renderer, this.shotHandler, 0, ItemType.WorldItem);
return new FishGun(this.renderer, this.shotHandler, this.collisionManager, 0, ItemType.WorldItem);
case 3:
return new Pipe(this.renderer, this.shotHandler, 0, ItemType.WorldItem);
case 4:
Expand Down
48 changes: 31 additions & 17 deletions src/client/input/CollisionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class CollisionManager {
private coyoteTime: number;
private jumped: boolean;
private collided: boolean;
private readonly velocity: THREE.Vector3;

// Temporary objects for prop collision calculations to avoid re-allocation
private readonly tempLocalSphere: THREE.Sphere;
Expand All @@ -48,6 +49,7 @@ export class CollisionManager {
this.coyoteTime = 0;
this.jumped = false;
this.collided = false;
this.velocity = new THREE.Vector3(0, 0, 0);

// Initialize temporary objects for prop collisions
this.tempLocalSphere = new THREE.Sphere(new THREE.Vector3(), this.colliderSphere.radius);
Expand Down Expand Up @@ -82,12 +84,12 @@ export class CollisionManager {
private physics(localPlayer: Player, deltaTime: number) {
this.prevPosition.copy(localPlayer.position);
const jump: boolean = this.inputHandler.jump;

if (localPlayer.doPhysics) localPlayer.gravity += deltaTime * -30;
localPlayer.inputVelocity.y += localPlayer.gravity;
// Note: This averaging of inputVelocity.y might be specific smoothing; kept as is.
localPlayer.inputVelocity.y = (localPlayer.inputVelocity.y + this.inputHandler.prevInputVelocity.y) * .25;
localPlayer.position.add(localPlayer.inputVelocity.clone().multiplyScalar(deltaTime));
if (this.coyoteTime > 0) this.velocity.add(localPlayer.inputVelocity.clone().multiplyScalar(deltaTime * 8));
else this.velocity.add(localPlayer.inputVelocity.clone().multiplyScalar(deltaTime * 11));
this.velocity.y += -20 * deltaTime;
if (Math.abs(this.velocity.x) < .0000001) this.velocity.x = 0;
if (Math.abs(this.velocity.z) < .0000001) this.velocity.z = 0;
localPlayer.position.add(this.velocity.clone().multiplyScalar(deltaTime));

this.collided = false; // Reset collided status for this physics step

Expand Down Expand Up @@ -116,11 +118,13 @@ export class CollisionManager {

if (angle >= CollisionManager.maxAngle) { // Ground collision
localPlayer.position.addScaledVector(this.deltaVec, depth);
localPlayer.inputVelocity.y = 0;
localPlayer.gravity = 0;
this.velocity.y = 0;
this.coyoteTime = 0;
this.collided = true;
} else { // Wall/ceiling collision
} else if (angle <= -.75) { // Ceiling
localPlayer.position.addScaledVector(this.deltaVec, depth);
this.velocity.y = 0;
} else { // Wall
localPlayer.position.addScaledVector(this.deltaVec, depth);
}
// Update colliderSphere center for subsequent checks within this shapecast
Expand Down Expand Up @@ -177,15 +181,17 @@ export class CollisionManager {

const angle = worldTriNormal.dot(this.upVector);

if (angle >= CollisionManager.maxAngle) { // Ground-like collision with prop
// Prop collisions
if (angle >= CollisionManager.maxAngle) { // Ground collision
localPlayer.position.addScaledVector(worldPenetrationVec, depth);
localPlayer.inputVelocity.y = 0;
localPlayer.gravity = 0;
this.velocity.y = 0;
this.coyoteTime = 0;
this.collided = true;
} else { // Wall/ceiling-like collision with prop
} else if (angle <= -.75) { // Ceiling
localPlayer.position.addScaledVector(worldPenetrationVec, depth);
this.velocity.y = 0;
} else { // Wall
localPlayer.position.addScaledVector(worldPenetrationVec, depth);
// Optionally, add sliding logic here for walls
}
// Update player's local position for next triangle check in this shapecast
this.tempLocalSphere.center.copy(localPlayer.position).applyMatrix4(this.worldToLocalMatrix);
Expand All @@ -203,14 +209,18 @@ export class CollisionManager {

// Coyote time, jump, and velocity calculation logic
if (!this.collided) { // If not collided with map OR any prop
this.velocity.x *= Math.pow(.95, deltaTime * 120);
this.velocity.z *= Math.pow(.95, deltaTime * 120);
this.coyoteTime += deltaTime;
if (jump && this.coyoteTime < 6 / 60 && !this.jumped) {
localPlayer.gravity = 8;
if (jump && this.coyoteTime < 12 / 120 && !this.jumped) {
this.velocity.y = 5;
this.jumped = true;
}
} else { // Collided with map OR a prop
this.velocity.x *= Math.pow(.90, deltaTime * 120);
this.velocity.z *= Math.pow(.90, deltaTime * 120);
if (jump) { // Allow jump if on ground (map or prop)
localPlayer.gravity = 8;
this.velocity.y = 5;
// this.jumped = true; // If you want to allow multiple jumps while holding space on ground
} else {
this.jumped = false;
Expand Down Expand Up @@ -246,4 +256,8 @@ export class CollisionManager {
public isPlayerInAir(): boolean {
return !this.collided; // Player is in air if no collision occurred in the last physics step
}

public applyVelocity(vector: THREE.Vector3): void {
this.velocity.add(vector);
}
}
25 changes: 11 additions & 14 deletions src/client/input/InputHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class InputHandler {

public handleInputs() {
const deltaTime: number = this.clock.getDelta();
const deltaTimeAcceleration = this.localPlayer.acceleration * deltaTime;
const acceleration = this.localPlayer.acceleration;

let dist = 1;
let speedMultiplier: number = 1;
Expand All @@ -124,10 +124,10 @@ export class InputHandler {
this.updateGamepadInputArray(this.gamepad);
this.gamepadEuler.setFromQuaternion(this.localPlayer.lookQuaternion);
if (Math.abs(this.gamepadInputs.leftJoyX) >= .1) {
this.inputX += deltaTimeAcceleration * this.gamepadInputs.leftJoyX;
this.inputX += acceleration * this.gamepadInputs.leftJoyX;
}
if (Math.abs(this.gamepadInputs.leftJoyY) >= .1) {
this.inputZ += deltaTimeAcceleration * this.gamepadInputs.leftJoyY;
this.inputZ += acceleration * this.gamepadInputs.leftJoyY;
}
const vectorLength = Math.sqrt(
(this.gamepadInputs.leftJoyX * this.gamepadInputs.leftJoyX) +
Expand All @@ -151,18 +151,18 @@ export class InputHandler {
if (Math.hypot(this.touchJoyY, this.touchJoyX) > 0.1) {
const touchVectorLength = Math.hypot(this.touchJoyX, this.touchJoyY);
speedMultiplier = Math.min(Math.max(touchVectorLength, 0), 1);
this.inputX += deltaTimeAcceleration * this.touchJoyX;
this.inputZ += deltaTimeAcceleration * this.touchJoyY;
this.inputX += acceleration * this.touchJoyX;
this.inputZ += acceleration * this.touchJoyY;
}

const touchSensitivity = 0.03; // Adjust sensitivity as needed
this.gamepadEuler.setFromQuaternion(this.localPlayer.lookQuaternion);

if (!this.localPlayer.chatActive && !this.nameSettingActive) {
if (this.getKey('w')) this.inputZ -= deltaTimeAcceleration;
if (this.getKey('s')) this.inputZ += deltaTimeAcceleration;
if (this.getKey('a')) this.inputX -= deltaTimeAcceleration;
if (this.getKey('d')) this.inputX += deltaTimeAcceleration;
if (this.getKey('w')) this.inputZ -= acceleration;
if (this.getKey('s')) this.inputZ += acceleration;
if (this.getKey('a')) this.inputX -= acceleration;
if (this.getKey('d')) this.inputX += acceleration;
const aimAdjust = this.calculateAimAssist();
if (this.getKey('arrowright')) {
this.gamepadEuler.y -= SettingsManager.settings.controllerSense * deltaTime * aimAdjust * 4 /
Expand Down Expand Up @@ -192,23 +192,20 @@ export class InputHandler {

switch (this.inputZ - oldInputZ) {
case 0:
this.inputZ = InputHandler.approachZero(this.inputZ, deltaTimeAcceleration);
this.inputZ = InputHandler.approachZero(this.inputZ, acceleration);
}

switch (this.inputX - oldInputX) {
case 0:
this.inputX = InputHandler.approachZero(this.inputX, deltaTimeAcceleration);
this.inputX = InputHandler.approachZero(this.inputX, acceleration);
}

if (this.localPlayer.health <= 0) dist = 0; //don't allow movement when health = 0

this.prevInputVelocity.copy(this.localPlayer.inputVelocity);

this.localPlayer.inputVelocity.z = dist * this.inputZ;
this.localPlayer.inputVelocity.x = dist * this.inputX;
this.localPlayer.inputVelocity.y = 0;
this.localPlayer.inputVelocity.clampLength(0, this.localPlayer.speed * speedMultiplier);
this.localPlayer.inputVelocity.y = this.prevInputVelocity.y;
this.inputZ = this.localPlayer.inputVelocity.z;
this.inputX = this.localPlayer.inputVelocity.x;

Expand Down
15 changes: 14 additions & 1 deletion src/client/items/FishGun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as THREE from 'three';
import { Renderer } from '../core/Renderer.ts';
import { AssetManager } from '../core/AssetManager.ts';
import { ShotHandler, ShotParticleType } from '../core/ShotHandler.ts';
import { CollisionManager } from '../input/CollisionManager.ts';

const firingDelay = 0.45;
const firingDelayHeld = 0.45; //longer firing delay when mouse is held down
Expand All @@ -18,19 +19,27 @@ const inventoryQuaternionBase = new THREE.Quaternion(0, 0, 0, 1);

export class FishGun extends ItemBase {
private shotHandler: ShotHandler;
private collisionManager: CollisionManager;
private lastInput: HeldItemInput;
private lastFired: number;
private addedToHandScene: boolean;
private renderer: Renderer;

// deno-lint-ignore constructor-super
constructor(renderer: Renderer, shotHandler: ShotHandler, index: number, itemType: ItemType) {
constructor(
renderer: Renderer,
shotHandler: ShotHandler,
collisionManager: CollisionManager,
index: number,
itemType: ItemType,
) {
if (itemType === ItemType.WorldItem) {
super(itemType, renderer.getEntityScene(), renderer.getInventoryMenuScene(), index);
} else {
super(itemType, renderer.getHeldItemScene(), renderer.getInventoryMenuScene(), index);
}
this.shotHandler = shotHandler;
this.collisionManager = collisionManager;
this.lastInput = new HeldItemInput();
this.addedToHandScene = false;
this.lastFired = 0;
Expand Down Expand Up @@ -184,6 +193,10 @@ export class FishGun extends ItemBase {
muzzleDir,
true,
);

const velocity = muzzleDir.clone().multiplyScalar(-10);
velocity.y *= .8;
this.collisionManager.applyVelocity(velocity);
}

// Method to set world position when used as WorldItem
Expand Down