Circular Dependencies with RxJS. 对孢子进行建模



我尝试用RxJS对一些游戏进行建模。 但我发现了循环依赖的一些麻烦。因此,我将游戏简化为一个简单的模拟(我只留下了"移动"动作)。你可以在下面找到代码(我省略了一些部分,你可以在这里找到存储库)

const rx = require('rx')
const math = require('mathjs')
const _ = require('underscore')
const FIELD_SIZE = 10
const ctx = require('axel');
let getInitialState = () => {
  return {
    size: FIELD_SIZE,
    people: [
      { x: 0, y: 0 },
      { x: 9, y: 9 },
      { x: 5, y: 5 }
    ]
  }
}
var drawWorld = ({size, people}) => {
  // draw world logic
}

let getMove = (index)=> {
  let [xOffset, yOffset] = [[0,1], [1,0]][math.pickRandom([0, 1])]
  let direction = math.pickRandom([-1, 1])
  return (state) => {
    let {people} = state
    let p = people[index]
    people[index] = {
      x: math.max(
          0,
          math.min(p.x + xOffset * direction, FIELD_SIZE-1)),
      y: math.max(
          0,
          math.min(p.y + yOffset * direction, FIELD_SIZE-1))
    }
    return _.extend({}, state, {people})
  }
}
var POOL = []
var produceActions = (state) => {
  _.range(state.people.length).forEach((i) => {
    POOL.push(getMove(i))
  })
}
var stateObservable = rx.Observable
  .interval(100)
  .timeInterval()
  .map(()=> {
    var x = POOL.slice()
    POOL.splice(0, POOL.length)
    return x
  })
  .scan(
      (state, ops) => ops.reduce(
        (st, o) => o(st),
        state
      ),
      getInitialState()
  )
stateObservable.subscribe(drawWorld)
stateObservable.tap(produceActions).subscribe()

有没有办法重写这个依赖于全局变量的丑陋的"生产操作"部分?就像@user3743222答案中提出的那样

这是一个在这里已经讨论过多次的问题。

我可以提到的三种方式(可能是其他人):

  • 使用主题
    • 如何处理 RxJS 中的循环依赖可观察量?
  • 使用expand
    • RX 中没有主题的反馈循环
    • RxJs:如何根据可观察对象的状态进行循环?
    • RxJS,如何使用动态时间戳轮询 API 以持续检查更新的记录
  • 使用周期.js(如果你熟悉 RxJS,学习曲线很小,如果你做了很多游戏,可能值得付出努力)

在您更新的问题和示例请求之后,这是未经测试的,但这是我的尝试,基于主题技术提供的链接。检查它是否有效,如果有效,我会发布一些解释。另外,请检查语法,我对ES6了解不多。

使用代理主体进行POOL

var POOL_proxyS = new Rx.BehaviorSubject([]); // instead of var POOL = []
var stateObservable = rx.Observable
  .interval(100)
  .timeInterval()
  .combineLatest(POOL_proxyS, (_, POOL) => POOL.slice() )
  .scan(
      (state, ops) => ops.reduce(
        (st, o) => o(st),
        state
      ),
      getInitialState()
  );
var produceActions = (state) => _.range(state.people.length).map((i) => getMove(i));
stateObservable
  .do(drawWorld)
  .map(produceActions)
  .subscribe(POOL_proxyS);

最新更新