Add skill system, level-ups, and new enemy types
This commit is contained in:
+85
-18
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user