survivors: reducing jumpiness of homing projectiles re-directing by limiting it to a certain angle

adding rad degree conversion utils checking world border for projectiles
This commit is contained in:
Sheldan
2025-08-21 17:48:16 +02:00
parent c8767f1119
commit 71f48404c9
4 changed files with 61 additions and 4 deletions

View File

@@ -62,6 +62,10 @@ export class World {
return this._size;
}
outside(position: Vector): boolean {
return position.x > this.size.x || position.y > this.size.y || position.x < 0 || position.y < 0
}
addEnemy(enemy: Enemy) {
this._enemies.push(enemy)
}

View File

@@ -1,3 +1,5 @@
import type {Placeable} from "./interfaces.ts";
export class Vector {
constructor(private _x: number, private _y: number) {
@@ -44,6 +46,13 @@ export class Vector {
return this.multiply(-1)
}
dotProduct(vector: Vector): number {
return this._x * vector._x + this._y * vector._y;
}
angleTo(vector: Vector): number {
return Math.acos(this.dotProduct(vector))
}
get x(): number {
return this._x;
@@ -87,4 +96,25 @@ export class Cooldown {
resetCooldown() {
this._currentValue = this._totalValue;
}
}
export class Point implements Placeable {
private position: Vector;
constructor(position: Vector) {
this.position = position;
}
getPosition(): Vector {
return this.position;
}
getSize() {
}
move(any?: any) {
}
}

View File

@@ -1,8 +1,8 @@
import type {Acting, Placeable, Healthy} from "./interfaces.ts";
import type {Vector} from "./base.ts";
import {World} from "./World.ts";
import {Cooldown, Vector} from "./base.ts";
import {drawDot, moveInDirectionOf, straightMove} from "./utils.ts";
import {Cooldown, Point, Vector} from "./base.ts";
import {drawDot, moveInDirectionOf, straightMove, toRad} from "./utils.ts";
import {InstanceOfUtils} from "./instance.ts";
export abstract class Projectile implements Acting, Placeable {
@@ -48,7 +48,13 @@ export abstract class Projectile implements Acting, Placeable {
}
}
this.status.collisionCooldown.decreaseCooldown();
this.checkWorldBorder()
}
checkWorldBorder() {
if(this.world.outside(this.position)) {
this.world.removeProjectile(this)
}
}
impactPlayer() {
@@ -97,7 +103,6 @@ export class HomingProjectile extends Projectile {
private target: Placeable;
constructor(position: Vector, speedVec: Vector, stats: ProjectileStats, world: World, parent: any, target: Placeable) {
super(position, speedVec, stats, world, parent);
this.target = target;
@@ -112,12 +117,22 @@ export class HomingProjectile extends Projectile {
return;
}
let closestTargetTo = this.world.getClosestTargetTo(this.world.player.position)
if (closestTargetTo !== undefined && closestTargetTo[1] !== undefined) {
this.target = closestTargetTo[1]!;
let dir = Vector.createVector(this.target.getPosition(), this.position).normalize()
let newTargetPosition = closestTargetTo[1]!.getPosition();
let newDir = Vector.createVector(newTargetPosition, this.position).normalize()
let newDirAngle = newDir.angleTo(dir);
if(Math.abs(newDirAngle) < toRad(60)) {
this.target = closestTargetTo[1]!;
} else {
this.target = new Point(this.target.getPosition().add(dir.normalize().multiply(Math.max(this.world.size.x, this.world.size.y))))
}
}
}
}
this.position = moveInDirectionOf(this.position, this.target.getPosition(), this.speedVec.vecLength())
this.checkWorldBorder()
}
static createHomingProjectile(world: World, start: Vector, parent: any, target: Placeable, stats: ProjectileStats, color?: string) {

View File

@@ -15,4 +15,12 @@ export function moveInDirectionOf(position: Vector, target: Vector, speedFactor:
export function straightMove(position: Vector, speed: Vector): Vector {
return position.add(speed)
}
export function toRad(angle) {
return angle / 180 * Math.PI;
}
export function toDegrees(angle) {
return angle * 180 / Math.PI
}