From 8ca64a19b74ff8f964546b5120a4e5fb2e7dc9a5 Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Thu, 21 Aug 2025 18:36:31 +0200 Subject: [PATCH] survivors: adding health enemies dropping health packs --- absurd-survivors/src/Enemies.ts | 47 ++++++++++++++- absurd-survivors/src/Player.ts | 5 ++ absurd-survivors/src/drop.ts | 91 +++++++++++++++++++++--------- absurd-survivors/src/main.ts | 11 +++- absurd-survivors/src/projectile.ts | 2 + 5 files changed, 123 insertions(+), 33 deletions(-) diff --git a/absurd-survivors/src/Enemies.ts b/absurd-survivors/src/Enemies.ts index 421f135..b77cd76 100644 --- a/absurd-survivors/src/Enemies.ts +++ b/absurd-survivors/src/Enemies.ts @@ -4,7 +4,7 @@ import {Vector} from "./base.ts"; import {World} from "./World.ts"; import type {Projectile} from "./projectile.ts"; import {HomingProjectile, ProjectileStats, StraightProjectile} from "./projectile.ts"; -import {MoneyDrop} from "./drop.ts"; +import {HealthPack, MoneyDrop} from "./drop.ts"; export abstract class Enemy implements Placeable, Drawable, Acting, Healthy { protected _position: Vector; @@ -131,7 +131,7 @@ export class ShootingEnemy extends BasicEnemy implements Shooting { static generateShootingEnemy(world: World, position?: Vector) { if(position === undefined) { - position = new Vector(250, 250) + position = world.randomPlace() } let basicEnemy = new ShootingEnemy(position); basicEnemy.size = 5; @@ -160,4 +160,47 @@ export class EnemyStatus { set health(value: number) { this._health = value; } +} + +export class HealthEnemy extends Enemy { + + constructor(position: Vector) { + super(position); + } + + protected size: number; + protected color: string; + + draw(ctx: CanvasRenderingContext2D) { + drawDot(this._position, this.size, this.color, ctx) + } + + + move() { + } + + act() { + super.act(); + } + + die() { + HealthPack.createHealthPack(this.world, this._position) + } + + static createHealthEnemy(world: World, position?: Vector) { + if(position === undefined) { + position = world.randomPlace() + } + let basicEnemy = new HealthEnemy(position); + basicEnemy.size = 5; + basicEnemy.world = world; + basicEnemy.speed = 0; + basicEnemy.color = 'purple' + return basicEnemy; + } + + + getSize() { + return this.size + } } \ No newline at end of file diff --git a/absurd-survivors/src/Player.ts b/absurd-survivors/src/Player.ts index ff9f431..6bea9f2 100644 --- a/absurd-survivors/src/Player.ts +++ b/absurd-survivors/src/Player.ts @@ -43,6 +43,11 @@ export class Player implements Drawable, Acting, Healthy { this._status.health -= damage; } + heal(amount: number) { + this._status.health += amount; + this._status.health = Math.min(this._status.health, this._stats.health) + } + get health(): number { return this._status.health; } diff --git a/absurd-survivors/src/drop.ts b/absurd-survivors/src/drop.ts index b27cca0..17ae403 100644 --- a/absurd-survivors/src/drop.ts +++ b/absurd-survivors/src/drop.ts @@ -3,27 +3,17 @@ import {World} from "./World.ts"; import {drawDot, moveInDirectionOf} from "./utils.ts"; import {Vector} from "./base.ts"; -export class MoneyDrop implements Drop { - private world: World; - private worth: number; - private _position: Vector; - private _color: string; - private _size: number; - +export abstract class BasicDrop implements Drop { + protected world: World; + protected _position: Vector; + protected _color: string; + protected _size: number; constructor(world: World, position: Vector) { this.world = world; this._position = position.clone(); } - draw(ctx: CanvasRenderingContext2D) { - drawDot(this._position, this.getSize(), this._color, ctx) - } - - pickup() { - this.world.player.status.wealth += this.worth - } - getPosition(): Vector { return this._position; } @@ -31,6 +21,41 @@ export class MoneyDrop implements Drop { move() { } + pickup() { + } + + act() { + let distanceToPlayer = this._position.distanceTo(this.world.player.position); + if(distanceToPlayer < (this.world.player.stats.size + this._size)) { + this.pickup() + this.world.removeDrop(this) + } else if(distanceToPlayer < this.world.player.stats.pullRange) { + let speedFactor = 125 / distanceToPlayer; + this._position = moveInDirectionOf(this._position, this.world.player.position, speedFactor) + } + } + + + getSize() { + return this._size + } + + abstract draw(ctx: CanvasRenderingContext2D); + +} + +export class MoneyDrop extends BasicDrop { + + private worth: number; + + draw(ctx: CanvasRenderingContext2D) { + drawDot(this._position, this.getSize(), this._color, ctx) + } + + pickup() { + this.world.player.status.wealth += this.worth + } + static createMoneyDrop(world: World, position?: Vector): MoneyDrop { if(!position) { position = world.randomPlace() @@ -43,19 +68,29 @@ export class MoneyDrop implements Drop { return drop; } - act() { - let distanceToPlayer = this._position.distanceTo(this.world.player.position); - if(distanceToPlayer < (this.world.player.stats.size + this._size)) { - this.pickup() - this.world.removeDrop(this) - } else if(distanceToPlayer < this.world.player.stats.pullRange) { - let speedFactor = 125 / distanceToPlayer; - this._position = moveInDirectionOf(this._position, this.world.player.position, speedFactor) + +} + +export class HealthPack extends BasicDrop { + private healAmount: number; + + draw(ctx: CanvasRenderingContext2D) { + drawDot(this._position, this.getSize(), this._color, ctx) + } + + pickup() { + this.world.player.heal(this.healAmount) + } + + static createHealthPack(world: World, position?: Vector): HealthPack { + if(!position) { + position = world.randomPlace() } + let drop = new HealthPack(world, position) + drop.healAmount = 5; + drop._size = 2; + drop._color = 'green'; + world.addDrop(drop) + return drop; } - - getSize() { - return this._size - } - } \ No newline at end of file diff --git a/absurd-survivors/src/main.ts b/absurd-survivors/src/main.ts index eafa02b..16d61a5 100644 --- a/absurd-survivors/src/main.ts +++ b/absurd-survivors/src/main.ts @@ -4,7 +4,7 @@ import {docReady} from "canvas-common"; import {World} from "./World.ts"; import {Player} from "./Player.ts"; import {Vector} from "./base.ts"; -import {BasicEnemy, Enemy, ShootingEnemy} from "./Enemies.ts"; +import {BasicEnemy, Enemy, HealthEnemy, ShootingEnemy} from "./Enemies.ts"; import {HUD} from "./ui.ts"; import {Pistol} from "./weapons.ts"; @@ -110,8 +110,13 @@ docReady(function () { world.addEnemy(BasicEnemy.generateBasicEnemy(world)) world.addEnemy(ShootingEnemy.generateShootingEnemy(world, new Vector(350, 350))) setInterval(() => { - world.addEnemy(ShootingEnemy.generateShootingEnemy(world, new Vector(Math.random() * world.size.x, Math.random() * world.size.y))) - }, 1000) + world.addEnemy(ShootingEnemy.generateShootingEnemy(world)) + }, 1_000) + + setInterval(() => { + world.addEnemy(HealthEnemy.createHealthEnemy(world)) + }, 15_000) + player.addWeapon(Pistol.spawnPistol(world)) let secondPistol = Pistol.spawnPistol(world, new Vector(-5, -5)); player.addWeapon(secondPistol) diff --git a/absurd-survivors/src/projectile.ts b/absurd-survivors/src/projectile.ts index d033cb5..4432a9f 100644 --- a/absurd-survivors/src/projectile.ts +++ b/absurd-survivors/src/projectile.ts @@ -43,6 +43,8 @@ export abstract class Projectile implements Acting, Placeable { this.world.removeProjectile(this) } this.status.decreasePiercings() + } else { + this.world.removeProjectile(this) } } }