Skip to content

Commit

Permalink
feat: add hit area & check hit
Browse files Browse the repository at this point in the history
  • Loading branch information
K9 committed Jul 31, 2024
1 parent 690cad3 commit 1ada5eb
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/Game/Game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class Game {
const affectZombies = this.quadTree.retrieve(detectCircle) as Zombie[];

for (let zombie of affectZombies) {
if (zombie.circleIntersect(detectCircle)) {
if (zombie.checkHited(detectCircle)) {
zombie.hitHealth(explodeBullet.getDamage());
if (zombie.isDead()) {
// 重置zombie
Expand All @@ -299,7 +299,7 @@ class Game {
const affectZombies = this.quadTree.retrieve(detectCircle) as Zombie[];

for (let zombie of affectZombies) {
if (zombie.circleIntersect(detectCircle)) {
if (zombie.checkHited(detectCircle)) {
zombie.hitHealth(bullet.getDamage());
if (zombie.isDead()) {
// 重置目标zombie
Expand Down Expand Up @@ -338,7 +338,7 @@ class Game {

for (let angle of angles) {
// const adjustedAngle = calculateAngle(player, target);
const adjustedAngle = calculateInterceptAngle(player, target, player.getSpeed(), target.getSpeed());
const adjustedAngle = calculateInterceptAngle(player, target, player.getSpeed(), target?.getSpeed());
const enhanced: BulletEnhancedInterface = {
...DEFAULT_BULLET_ENHANCE_OBJECT,
damage: player.damage,
Expand Down
15 changes: 11 additions & 4 deletions src/Game/GameObject/GameObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,18 @@ class GameObject extends Circle {

draw(ctx: CanvasRenderingContext2D) {}

circleIntersect(other: Circle) {
const dx = this.x - other.x;
const dy = this.y - other.y;
// circleIntersect(other: Circle) {
// const dx = this.x - other.x;
// const dy = this.y - other.y;
// const distance = Math.sqrt(dx * dx + dy * dy);
// return distance <= this.r + other.r;
// }

circleIntersect(source: Circle, target: Circle) {
const dx = source.x - target.x;
const dy = source.y - target.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return distance <= this.r + other.r;
return distance <= source.r + target.r;
}

isOffCanvas(bound: BoundInterface) {
Expand Down
2 changes: 1 addition & 1 deletion src/Game/GameObject/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class Player extends GameObject {
const angles = this._calculateRangeAngles();
for (let angle of angles) {
// const adjustedAngle1 = this._calculateAngle(target);
const adjustedAngle = calculateInterceptAngle(this, target, this.speed, target.getSpeed());
const adjustedAngle = calculateInterceptAngle(this, target, this.speed, target?.getSpeed());
const enhanced: BulletEnhancedInterface = {
...DEFAULT_BULLET_ENHANCE_OBJECT,
damage: this.damage,
Expand Down
19 changes: 18 additions & 1 deletion src/Game/GameObject/Zombie.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import GameObject from "./GameObject";
import { GameObjectEnum } from "../enum";
import { ZombieEnhanceInterface } from "../type";
import { CircleInterface, ZombieEnhanceInterface } from "../type";
import { Circle } from "@timohausmann/quadtree-ts";

class Zombie extends GameObject {
private speed: number;
private health: number;
private is_boss: boolean;
private hit_area: CircleInterface[];
constructor(x: number, y: number, enhanced: ZombieEnhanceInterface) {
super(x, y, enhanced.radius, GameObjectEnum.ZOMBIE);
this.speed = enhanced.speed;
this.health = enhanced.health;
this.is_boss = enhanced.isBoss;
this.hit_area = [{
x: 0,
y: 0,
r: enhanced.hitRadius
}];
}

getSpeed() {
Expand All @@ -29,6 +36,16 @@ class Zombie extends GameObject {
return this.is_boss;
}

checkHited(circle: Circle) {
for (let i = 0; i < this.hit_area.length; i++) {
const area = this.hit_area[i];
if (this.circleIntersect({ x: this.x + area.x, y: this.y + area.y, r: area.r } as Circle, circle)) {
return true;
}
}
return false;
}

isDead() {
return this.health <= 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Game/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ export const DEFAULT_ZOMBIE_ENHANCE_OBJECT: ZombieEnhanceInterface = {
speed: 0.2,
health: 50,
isBoss: false,
hitRadius: 10
};

export const DEFAULT_ZOMBIE_BOSS_ENHANCE_OBJECT: ZombieEnhanceInterface = {
radius: 20,
speed: 0.2,
health: 500,
isBoss: true,
hitRadius: 10
};

export const DEFAULT_BULLET_ENHANCE_OBJECT: BulletEnhancedInterface = {
Expand Down
7 changes: 7 additions & 0 deletions src/Game/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export interface ZombieEnhanceInterface {
speed: number;
health: number;
isBoss: boolean;
hitRadius: number;
}

export interface ExplosionEnhanceInterface {
Expand Down Expand Up @@ -49,6 +50,12 @@ export interface Position {
y: number;
}

export interface CircleInterface {
x: number;
y: number;
r: number;
}

export interface BulletConstructorProps {
x: number;
y: number;
Expand Down
8 changes: 4 additions & 4 deletions src/Game/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export const calculateInterceptAngle = (
source: Circle,
target: Circle | null,
sourceSpeed: number,
targetSpeed: number
targetSpeed: number = 0
): number => {
if (!target) return Math.PI / 2;
if (!target) return -Math.PI / 2;
const sourcePos = new Vector(source.x, source.y);
const targetPos = new Vector(target.x, target.y);
const targetVel = new Vector(0, targetSpeed);
Expand All @@ -61,15 +61,15 @@ export const calculateInterceptAngle = (
// 求解二次方程
const discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
return Math.PI / 2;
return -Math.PI / 2;
}

const t1 = (-b + Math.sqrt(discriminant)) / (2 * a);
const t2 = (-b - Math.sqrt(discriminant)) / (2 * a);
const t = Math.max(t1, t2);

if (t < 0) {
return Math.PI / 2;
return -Math.PI / 2;
}

const interceptPos = targetPos.add(targetVel.multiply(t));
Expand Down

0 comments on commit 1ada5eb

Please sign in to comment.