Phaser 3 循环依赖问题

3

如何解决Phaser 3中的循环依赖问题

背景

我正在使用Phaser 3、TypeScript和Parcel制作一个游戏。我添加了一些实现某些接口的类,但这些接口相互导入和使用。我开始使用airbnb规则集下的eslint,其中一个规则是import/no-cycle,但我感觉我的游戏需要它

示例代码

GameInterface.ts

import { Scene } from 'phaser';
import PlayerInterface from '../../entities/player/PlayerInterface'; // circular

interface GameInterface extends Scene {
  player: PlayerInterface;
}

export default GameInterface;

PlayerInterface.ts

import GameInterface from '../../scenes/game/GameInterface'; // circular

interface PlayerInterface extends Phaser.Physics.Arcade.Sprite {
  scene: GameInterface;
  speed: number;
}

export default PlayerInterface;

问题

一个“玩家”被添加到“游戏”中,而玩家类有一个场景。因此它们都需要在接口中。由于这只是一个类型文件,我可以忽略这个规则吗?还是有一个聪明的重组结构可以做到这一点?

编辑1

此外这里是完整仓库的链接。

编辑2

这是实现这些接口的两个类。

Game.ts

class Game extends Scene implements GameInterface {
  player: PlayerInterface;

  constructor() {
    super({
      key: 'Game',
    });
  }

  preload(): void {
    /* preload code */
  }

  create(): void {
   /* create code */ 
  }
}

Player.ts

class Player extends Phaser.Physics.Arcade.Sprite implements PlayerInterface {
  scene: GameInterface;

  constructor(scene: GameInterface) {
    super(scene, x, y, 'player');
    this.scene = scene;
    this.scene.add.existing(this);
    this.scene.physics.add.existing(this);
  }

  static preload(scene: GameInterface): void {
    /* preload */
  }
}

您可以看到游戏类创建了玩家,但是在创建时也传递了一个场景。


你能试着把两个接口放在同一个文件中吗? - mbkfa93
我不确定你的逻辑是否正确。在这里,您描述了一个无限递归的JavaScript对象,看起来像这样:player = { scene: { player: { scene: { player: ... } } } }。您真的操作这种类型的对象吗? - johannchopin
为什么不把接口放在一个文件里呢? - Eldar
你应该设计你的应用程序,使得其中一个接口不需要另一个接口。 - Ievgen
2个回答

1
首先,"循环依赖"是指当你有两个类A和B时:
  • 类A使用了类B,因此A依赖于B
  • 类B使用了类A,因此B也依赖于A
因此,在初始化这两个类时,会陷入无限循环,因为它想要创建基于B的A类,而类B又想要基于类A创建,从而形成了死循环。

enter image description here

所以只需切断不必要的依赖关系。

  1. Game类中,似乎您不需要使用PlayerInterface
  2. 而且您也不需要在接口中扩展ScenePhaser.Physics.Arcade.Sprite。因为您已经在具体类中扩展了它们。只需将它们删除即可。

1
循环依赖仅来自我的接口。我在每个类中都使用玩家和游戏,只是这里没有在代码中显示它们,因为这会使问题变得臃肿。不过,我将测试从接口中删除场景和精灵,但我觉得以前它给我带来了错误。 - Joe Lloyd
FYI,从扩展中删除场景/精灵是不好的。如果我删除它,接口就不能代表它本身。如果我从类中删除它,它将无法工作,因为接口实现不正确。 - Joe Lloyd

1
将两个接口放在同一个文件中。这将消除循环文件加载问题,这正是在此处使您犯错的原因。

这不是一个可扩展的解决方案。 - Joe Lloyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接