Add skill system, level-ups, and new enemy types

This commit is contained in:
2026-08-17 16:38:58 +02:00
parent 4751d428a7
commit 6f207ba1a0
23 changed files with 2192 additions and 83 deletions
+85 -18
View File
@@ -1,19 +1,46 @@
import * as THREE from 'three';
import { Sword } from './Sword';
import { Staff } from './Staff';
import { ChainLightning } from './ChainLightning';
import { loadGLB } from './MeshLoader';
import type { Game } from './Game';
import type { SkillSystem } from './Skills';
export interface PlayerStats {
maxHealth: number;
regen: number;
lifesteal: number;
shield: number;
shieldRechargeDelay: number;
moveSpeed: number;
swordDamage: number;
swordRange: number;
thornDamage: number;
}
export class Player {
body: THREE.Group;
leftHandWeapon: Staff;
rightHandWeapon: Sword;
skillLightning: ChainLightning;
velocity = new THREE.Vector3();
health = 100;
MAX_HEALTH = 100;
game!: Game;
jumpVelocity = 0;
onGround = true;
shieldHp = 0;
shieldTimer = 0;
stats: PlayerStats = {
maxHealth: 100,
regen: 0,
lifesteal: 0,
shield: 0,
shieldRechargeDelay: 8,
moveSpeed: 7.5,
swordDamage: 50,
swordRange: 2.2,
thornDamage: 0,
};
mixer!: THREE.AnimationMixer;
private clips: Map<string, THREE.AnimationAction> = new Map();
private currentAnim = '';
@@ -64,6 +91,8 @@ export class Player {
// Weapons
this.leftHandWeapon = new Staff();
this.rightHandWeapon = new Sword();
this.skillLightning = new ChainLightning();
this.leftHandWeapon.mesh.visible = false;
this.body.add(this.leftHandWeapon.mesh);
this.body.add(this.rightHandWeapon.mesh);
}
@@ -149,24 +178,60 @@ export class Player {
}
}
switchHands() {
const temp = this.leftHandWeapon;
this.leftHandWeapon = this.rightHandWeapon as unknown as Staff;
this.rightHandWeapon = temp as unknown as Sword;
const leftPos = this.leftHandWeapon.mesh.position.clone();
const rightPos = this.rightHandWeapon.mesh.position.clone();
this.leftHandWeapon.mesh.position.copy(rightPos);
this.rightHandWeapon.mesh.position.copy(leftPos);
const leftRot = this.leftHandWeapon.mesh.rotation.clone();
const rightRot = this.rightHandWeapon.mesh.rotation.clone();
this.leftHandWeapon.mesh.rotation.copy(rightRot);
this.rightHandWeapon.mesh.rotation.copy(leftRot);
heal(amount: number) {
this.health = Math.min(this.health + amount, this.stats.maxHealth);
}
heal(amount: number) {
this.health = Math.min(this.health + amount, this.MAX_HEALTH);
damage(amount: number) {
if (this.shieldHp > 0) {
const absorbed = Math.min(this.shieldHp, amount);
this.shieldHp -= absorbed;
amount -= absorbed;
this.shieldTimer = this.stats.shieldRechargeDelay;
}
this.health -= amount;
}
updatePassives(dt: number) {
if (this.stats.regen > 0) {
this.heal(this.stats.regen * dt);
}
if (this.stats.shield > 0) {
if (this.shieldHp < this.stats.shield) {
this.shieldTimer -= dt;
if (this.shieldTimer <= 0) {
this.shieldHp = this.stats.shield;
}
} else {
this.shieldTimer = 0;
}
}
}
applySkillSystem(skills: SkillSystem) {
const oldMax = this.stats.maxHealth;
const l = (id: string) => skills.getLevel(id);
this.stats = {
maxHealth: 100 + 25 * l('maxHp'),
regen: 1.5 * l('regen'),
lifesteal: 0.05 * l('lifesteal'),
shield: 25 * l('shield'),
shieldRechargeDelay: 8,
moveSpeed: 7.5 + l('speed'),
swordDamage: 50 + 25 * l('swordDamage'),
swordRange: 2.2 + 0.6 * l('swordRange'),
thornDamage: 15 * l('thorns'),
};
if (this.stats.maxHealth > oldMax) {
this.health = this.stats.maxHealth;
} else {
this.health = Math.min(this.health, this.stats.maxHealth);
}
if (this.stats.shield > 0 && this.shieldHp <= 0) {
this.shieldHp = this.stats.shield;
}
}
die() {
@@ -174,7 +239,9 @@ export class Player {
}
reset() {
this.health = this.MAX_HEALTH;
this.health = 100;
this.shieldHp = 0;
this.shieldTimer = 0;
this.body.position.set(0, 0.5, 0);
this.velocity.set(0, 0, 0);
this.jumpVelocity = 0;