You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OOP游戏开发中Mediator模式的实现困惑求助

用Mediator模式实现捕食者-猎物交互逻辑

先修正现有代码的小问题:Human类继承了Organism的isStomachFull和stomachCapacity,无需重复定义,直接移除这两个属性即可。

接下来通过Mediator模式让游戏区域(GameArea)作为中介,统一处理Alien和Human的交互,具体实现步骤如下:

1. 完善基础生物类

给Organism添加位置属性用于距离检测,同时补充饱腹值相关逻辑:

export abstract class Organism {
  abstract maxHP: number;
  abstract currentHP: number;
  abstract canHit: boolean;

  // 新增位置属性,用于距离计算
  x: number = 0;
  y: number = 0;

  isStomachFull = false;
  stomachCapacity = 100;
  currentStomach = 0; // 当前饱腹值,判断是否能继续进食

  reduceHp() {
    if (this.currentHP > 0) {
      this.currentHP -= 1;
    }
  }

  recoverHp() {
    // 修正回血逻辑:当前血量小于最大血量时才回血
    if (this.currentHP < this.maxHP) {
      this.currentHP += 1;
    }
  }

  // 新增进食方法,Alien通过这个方法增加饱腹值
  eat(foodValue: number) {
    if (!this.isStomachFull) {
      this.currentStomach += foodValue;
      if (this.currentStomach >= this.stomachCapacity) {
        this.currentStomach = this.stomachCapacity;
        this.isStomachFull = true;
      }
    }
  }
}

2. 定义中介者接口与实现

创建IGameMediator接口规范中介者行为,再实现GameArea作为具体中介者,负责管理所有生物并处理交互:

中介者接口

import { Organism } from './Organism';

export interface IGameMediator {
  registerOrganism(organism: Organism): void;
  update(): void; // 每帧更新,处理生物间交互
}

游戏区域(中介者实现)

import { IGameMediator } from './IGameMediator';
import { Organism } from './Organism';
import { Alien } from './Alien';
import { Human } from './Human';

export class GameArea implements IGameMediator {
  private organisms: Organism[] = [];
  private readonly eatRange = 5; // Alien的有效进食范围

  registerOrganism(organism: Organism): void {
    this.organisms.push(organism);
  }

  update(): void {
    // 筛选出所有Alien和可食用的Human
    const aliens = this.organisms.filter(o => o instanceof Alien) as Alien[];
    const eatableHumans = this.organisms.filter(
      o => o instanceof Human && (o as Human).isEatable && o.currentHP > 0
    ) as Human[];

    aliens.forEach(alien => {
      if (alien.isStomachFull) return; // 饱腹状态下不进食

      eatableHumans.forEach(human => {
        // 计算两者之间的欧氏距离
        const distance = Math.sqrt(
          Math.pow(alien.x - human.x, 2) + Math.pow(alien.y - human.y, 2)
        );

        // 距离在进食范围内时触发交互
        if (distance <= this.eatRange) {
          human.reduceHp();
          alien.eat(10); // 每次进食增加10点饱腹值
          console.log(`Alien进食!人类剩余血量:${human.currentHP},Alien饱腹值:${alien.currentStomach}`);
        }
      });
    });
  }
}

3. 修正Alien与Human类

移除Human中重复定义的继承属性,保持代码简洁:

// Alien类无需修改,保持原有结构即可
import { Organism } from '../abstract/Organism';

export class Alien extends Organism {
  maxHP: number;
  currentHP: number;
  canHit: boolean;

  constructor(hp: number, canHit: boolean) {
    super();
    this.maxHP = hp;
    this.canHit = canHit;
    this.currentHP = this.maxHP;
  }
}
// 修正后的Human类
import { Organism } from '../abstract/Organism';
import { IEatable } from '../interface/IEatable';

export class Human extends Organism implements IEatable {
  maxHP: number;
  currentHP: number;
  canHit: boolean;
  isEatable: boolean;

  constructor(hp: number, canHit: boolean, isEatable: boolean) {
    super();
    this.maxHP = hp;
    this.canHit = canHit;
    this.currentHP = this.maxHP;
    this.isEatable = isEatable;
  }
}

4. 模拟游戏运行示例

import { GameArea } from './GameArea';
import { Alien } from './Alien';
import { Human } from './Human';

// 创建游戏中介者
const gameArea = new GameArea();

// 创建捕食者和猎物
const alien = new Alien(100, true);
alien.x = 0;
alien.y = 0;

const human1 = new Human(20, false, true);
human1.x = 3; // 距离Alien 3单位,在进食范围内
human1.y = 0;

const human2 = new Human(20, false, true);
human2.x = 10; // 距离Alien 10单位,超出进食范围
human2.y = 0;

// 将生物注册到游戏区域
gameArea.registerOrganism(alien);
gameArea.registerOrganism(human1);
gameArea.registerOrganism(human2);

// 模拟游戏循环,每秒更新一次
const gameLoop = setInterval(() => {
  gameArea.update();
  if (human1.currentHP <= 0) {
    console.log('人类已死亡,停止模拟');
    clearInterval(gameLoop);
  }
}, 1000);

核心逻辑说明

  • 中介者解耦:Alien和Human无需直接引用彼此,所有交互由GameArea统一处理,降低了类之间的耦合度。
  • 扩展性强:后续新增其他生物类型(如新型捕食者/猎物),只需修改GameArea的update逻辑,无需改动现有生物类。
  • 集中管理:所有交互逻辑集中在中介者中,便于维护和调试。

内容的提问来源于stack exchange,提问作者thewebjackal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:12:37