mirror of
https://github.com/Sheldan/canvas.git
synced 2026-01-06 08:20:50 +00:00
survivors: split between base stats, temp stats and effective stats for players
changed the way how stats are increased/decreased
This commit is contained in:
@@ -4,7 +4,9 @@ import {fillDot, getCoordinatesSplit} from "./utils.ts";
|
||||
|
||||
export class Player implements Drawable, Acting, Healthy {
|
||||
private _position: Vector;
|
||||
private _stats: PlayerStats;
|
||||
private _baseStats: PlayerStats;
|
||||
private _effectiveStats: PlayerStats;
|
||||
private _tempStats: PlayerStats;
|
||||
private _color: string;
|
||||
|
||||
private _status: PlayerStatus;
|
||||
@@ -20,7 +22,7 @@ export class Player implements Drawable, Acting, Healthy {
|
||||
}
|
||||
|
||||
draw(ctx: CanvasRenderingContext2D) {
|
||||
fillDot(this.position, this._stats.size, this._color, ctx)
|
||||
fillDot(this.position, this._effectiveStats.size, this._color, ctx)
|
||||
this._weapons.forEach(weapon => weapon.draw(ctx))
|
||||
}
|
||||
|
||||
@@ -30,7 +32,10 @@ export class Player implements Drawable, Acting, Healthy {
|
||||
}
|
||||
let player = new Player(position);
|
||||
player._color = 'blue';
|
||||
player._stats = PlayerStats.defaultPlayerStats();
|
||||
player._baseStats = PlayerStats.defaultPlayerStats();
|
||||
let tempStats = new PlayerStats();
|
||||
tempStats.resetToBasic()
|
||||
player._tempStats = tempStats;
|
||||
player._speed = new Vector(0, 0)
|
||||
player._status = new PlayerStatus(10, 0, 0);
|
||||
return player;
|
||||
@@ -60,9 +65,15 @@ export class Player implements Drawable, Acting, Healthy {
|
||||
this._status.health -= damage;
|
||||
}
|
||||
|
||||
statsChanged() {
|
||||
this._effectiveStats.resetToBasic()
|
||||
this._effectiveStats.mergeStats(this._baseStats)
|
||||
this._effectiveStats.mergeStats(this._tempStats)
|
||||
}
|
||||
|
||||
heal(amount: number) {
|
||||
this._status.health += amount;
|
||||
this._status.health = Math.min(this._status.health, this._stats.health)
|
||||
this._status.health = Math.min(this._status.health, this._effectiveStats.health)
|
||||
}
|
||||
|
||||
get health(): number {
|
||||
@@ -77,8 +88,8 @@ export class Player implements Drawable, Acting, Healthy {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
get stats(): PlayerStats {
|
||||
return this._stats;
|
||||
get effectiveStats(): PlayerStats {
|
||||
return this._effectiveStats;
|
||||
}
|
||||
|
||||
get status(): PlayerStatus {
|
||||
@@ -101,19 +112,30 @@ export class Player implements Drawable, Acting, Healthy {
|
||||
}
|
||||
|
||||
getSize() {
|
||||
return this.stats.size
|
||||
return this._effectiveStats.size
|
||||
}
|
||||
|
||||
dead() {
|
||||
return this.status.dead
|
||||
}
|
||||
|
||||
changeBaseStat(value: number, statFun: (stats: PlayerStats, value: number) => void) {
|
||||
this._baseStats.changeStat(value, statFun)
|
||||
this.statsChanged()
|
||||
}
|
||||
|
||||
changeTempStat(value: number, statFun: (stats: PlayerStats, value: number) => void) {
|
||||
this._tempStats.changeStat(value, statFun)
|
||||
this.statsChanged()
|
||||
}
|
||||
|
||||
increaseLevel() {
|
||||
this.status.increaseLevel()
|
||||
this.stats.increaseLevel()
|
||||
this._baseStats.increaseLevel()
|
||||
this._weapons.forEach(weapon => {
|
||||
weapon.increaseLevel()
|
||||
})
|
||||
this.statsChanged()
|
||||
}
|
||||
|
||||
level() {
|
||||
@@ -179,6 +201,14 @@ export class PlayerStats {
|
||||
this._weaponRangeFactor = 1;
|
||||
}
|
||||
|
||||
resetToBasic() {
|
||||
this._speed = 0;
|
||||
this._health = 0;
|
||||
this._pullRange = 0;
|
||||
this._weaponRange = 0;
|
||||
this._weaponRangeFactor = 1
|
||||
}
|
||||
|
||||
increaseLevel() {
|
||||
this._speed *= 1.1;
|
||||
this._health += 1
|
||||
@@ -187,29 +217,42 @@ export class PlayerStats {
|
||||
this._weaponRangeFactor += 0.1
|
||||
}
|
||||
|
||||
|
||||
set speed(value: number) {
|
||||
this._speed = value;
|
||||
mergeStats(otherStats: PlayerStats) {
|
||||
this._speed += otherStats._speed;
|
||||
this._health += otherStats._health;
|
||||
this._pullRange += otherStats._pullRange;
|
||||
this._weaponRange += otherStats._weaponRange
|
||||
this._weaponRangeFactor += otherStats._weaponRangeFactor;
|
||||
}
|
||||
|
||||
set size(value: number) {
|
||||
this._size = value;
|
||||
clone() {
|
||||
let newStats = new PlayerStats();
|
||||
newStats.mergeStats(this)
|
||||
return newStats;
|
||||
}
|
||||
|
||||
set health(value: number) {
|
||||
this._health = value;
|
||||
changeStat(value: number, statFun: (stats: PlayerStats, value: number) => void) {
|
||||
statFun(this, value)
|
||||
}
|
||||
|
||||
set pullRange(value: number) {
|
||||
this._pullRange = value;
|
||||
static increaseSpeed(stats: PlayerStats, value: number) {
|
||||
stats._speed += value
|
||||
}
|
||||
|
||||
set weaponRange(value: number) {
|
||||
this._weaponRange = value;
|
||||
static factorSpeed(stats: PlayerStats, value: number) {
|
||||
stats._speed *= value
|
||||
}
|
||||
|
||||
set weaponRangeFactor(value: number) {
|
||||
this._weaponRangeFactor = value;
|
||||
static increasePullRange(stats: PlayerStats, value: number) {
|
||||
stats._pullRange += value
|
||||
}
|
||||
|
||||
static factorPullRange(stats: PlayerStats, value: number) {
|
||||
stats._pullRange += value
|
||||
}
|
||||
|
||||
static increaseHealth(stats: PlayerStats, value: number) {
|
||||
stats._health += value
|
||||
}
|
||||
|
||||
get speed(): number {
|
||||
|
||||
@@ -27,10 +27,10 @@ export abstract class BasicDrop implements Drop {
|
||||
|
||||
act() {
|
||||
let distanceToPlayer = this._position.distanceTo(this.world.player.position);
|
||||
if(distanceToPlayer < (this.world.player.stats.size + this.size)) {
|
||||
if(distanceToPlayer < (this.world.player.effectiveStats.size + this.size)) {
|
||||
this.pickup()
|
||||
this.world.removeDrop(this)
|
||||
} else if(distanceToPlayer < this.world.player.stats.pullRange) {
|
||||
} else if(distanceToPlayer < this.world.player.effectiveStats.pullRange) {
|
||||
let speedFactor = 125 / distanceToPlayer;
|
||||
this._position = moveInDirectionOf(this._position, this.world.player.position, speedFactor)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {ChanceEntry, Item} from "./interfaces.ts";
|
||||
import {Player} from "./Player.ts";
|
||||
import {Player, PlayerStats} from "./Player.ts";
|
||||
import {randomItem} from "./utils.ts";
|
||||
import {ChainBall, HomingPistol, Pistol, Spear, SpreadWeapon} from "./weapons.ts";
|
||||
import type {World} from "./World.ts";
|
||||
@@ -85,7 +85,7 @@ export abstract class BaseItem implements Item {
|
||||
|
||||
export class SpeedUp extends BaseItem {
|
||||
pickup(player: Player, world: World) {
|
||||
player.stats.speed += 1
|
||||
player.changeBaseStat(1, PlayerStats.increaseSpeed)
|
||||
super.pickup(player, world)
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export class SpeedUp extends BaseItem {
|
||||
|
||||
export class PullRangeUp extends BaseItem {
|
||||
pickup(player: Player, world: World) {
|
||||
player.stats.pullRange *= 1.1
|
||||
player.changeBaseStat(1.1, PlayerStats.factorPullRange)
|
||||
super.pickup(player, world)
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ export class PullRangeUp extends BaseItem {
|
||||
|
||||
export class HealthUp extends BaseItem {
|
||||
pickup(player: Player, world: World) {
|
||||
player.stats.health += 1
|
||||
player.changeBaseStat(1, PlayerStats.increaseHealth)
|
||||
super.pickup(player, world)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,16 +66,16 @@ function makeKey(char, fun) {
|
||||
|
||||
let keys = {};
|
||||
makeKey('w', function (intensity: number) {
|
||||
world.movePlayer(new Vector(0, -world.player.stats.speed * intensity))
|
||||
world.movePlayer(new Vector(0, -world.player.effectiveStats.speed * intensity))
|
||||
})
|
||||
makeKey('s', function (intensity: number) {
|
||||
world.movePlayer(new Vector(0, world.player.stats.speed * intensity))
|
||||
world.movePlayer(new Vector(0, world.player.effectiveStats.speed * intensity))
|
||||
})
|
||||
makeKey('a', function (intensity: number) {
|
||||
world.movePlayer(new Vector(-world.player.stats.speed * intensity, 0))
|
||||
world.movePlayer(new Vector(-world.player.effectiveStats.speed * intensity, 0))
|
||||
})
|
||||
makeKey('d', function (intensity: number) {
|
||||
world.movePlayer(new Vector(world.player.stats.speed * intensity, 0))
|
||||
world.movePlayer(new Vector(world.player.effectiveStats.speed * intensity, 0))
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export abstract class Projectile implements Acting, Placeable {
|
||||
act() {
|
||||
this.move()
|
||||
if(this.parent !== this.world.player) {
|
||||
if(this.position.distanceTo(this.world.player.position) < (this.stats.size + this.world.player.stats.size) && this.status.collisionCooldown.cooledDown()) {
|
||||
if(this.position.distanceTo(this.world.player.position) < (this.stats.size + this.world.player.effectiveStats.size) && this.status.collisionCooldown.cooledDown()) {
|
||||
this.impactPlayer()
|
||||
this.status.collisionCooldown.resetCooldown()
|
||||
}
|
||||
@@ -171,7 +171,7 @@ export class ChainBallProjectile extends Projectile {
|
||||
} else {
|
||||
this.position = moveInDirectionOf(this.position, this.world.player.position, this.speedVec.vecLength())
|
||||
}
|
||||
if(this.movingBack && this.position.distanceTo(this.world.player.position) < (this.stats.size + this.world.player.stats.size)) {
|
||||
if(this.movingBack && this.position.distanceTo(this.world.player.position) < (this.stats.size + this.world.player.effectiveStats.size)) {
|
||||
this.weapon.reset();
|
||||
this.die()
|
||||
}
|
||||
@@ -233,7 +233,7 @@ export class StraightMeleeWeaponProjectile extends Projectile {
|
||||
} else {
|
||||
this.position = moveInDirectionOf(this.position, new Vector(0, 0), this.speedVec.vecLength())
|
||||
}
|
||||
if(this.movingBack && this.position.distanceTo(new Vector(0, 0)) < (this.stats.size + this.world.player.stats.size)) {
|
||||
if(this.movingBack && this.position.distanceTo(new Vector(0, 0)) < (this.stats.size + this.world.player.effectiveStats.size)) {
|
||||
this.weapon.reset();
|
||||
this.die()
|
||||
}
|
||||
|
||||
@@ -120,14 +120,14 @@ export class PlayerInfo implements DrawContainer {
|
||||
|
||||
constructor(world: World) {
|
||||
this.world = world;
|
||||
this.bar = new InfoBar(new Vector(0, 50), 50, 150, () => 'Health', () => this.world.player.status.health, () => this.world.player.stats.health)
|
||||
this.bar = new InfoBar(new Vector(0, 50), 50, 150, () => 'Health', () => this.world.player.status.health, () => this.world.player.effectiveStats.health)
|
||||
this.statLabelBase = new Vector(0, 150)
|
||||
this.statLabels = [
|
||||
new StatLabel(() => 'Money', () => this.world.player.status.wealth),
|
||||
new StatLabel(() => 'Level', () => this.world.player.status.level),
|
||||
new StatLabel(() => 'Speed', () => Math.floor(this.world.player.stats.speed)),
|
||||
new StatLabel(() => 'Pull range', () => Math.floor(this.world.player.stats.pullRange)),
|
||||
new StatLabel(() => 'Weapon range', () => Math.floor(this.world.player.stats.effectiveWeaponRange))
|
||||
new StatLabel(() => 'Speed', () => Math.floor(this.world.player.effectiveStats.speed)),
|
||||
new StatLabel(() => 'Pull range', () => Math.floor(this.world.player.effectiveStats.pullRange)),
|
||||
new StatLabel(() => 'Weapon range', () => Math.floor(this.world.player.effectiveStats.effectiveWeaponRange))
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ export abstract class RangeWeapon extends BasicWeapon {
|
||||
}
|
||||
|
||||
calculateRange(): number {
|
||||
return this.world.player.stats.effectiveWeaponRange + this.stats.effectiveWeaponRange;
|
||||
return this.world.player.effectiveStats.effectiveWeaponRange + this.stats.effectiveWeaponRange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user