Circular Dependencies with RxJS. Modeling spores

僤鯓⒐⒋嵵緔 提交于 2019-12-12 06:06:48

问题


I try to model some game with RxJS. but I found some troubles with circular dependencies. So, I simplified my game to a simple simulation(I left only 'move' action). You can find code below(I omitted some parts, you can find the repo here)

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()

Is there a way to rewrite this ugly `produceActions' part which relies on global variable? Like proposed in the @user3743222 answer


回答1:


Following your updated question and request for an example, this is untested but here is my try, based on the provided link on the subject technique. Check if it works, I'll post some explanations after that if it does. Also, please check the syntax, I don't know so much about ES6.

Using a proxy subject for 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);



回答2:


This is a question which has been dealt with a number of times here.

Three ways I can mention (might be others) :

  • use a subject
    • How to handle circularly dependent observables in RxJS?
  • use expand
    • Feedback loop without Subject in RX
    • RxJs: How to loop based on state of the observable?
    • RxJS, how to poll an API to continuously check for updated records using a dynamic timestamp
  • use cycle.js (if you are familiar with RxJS, the learning curve is small, and if you do a lot of games, it might be worth the effort)


来源:https://stackoverflow.com/questions/35037305/circular-dependencies-with-rxjs-modeling-spores

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!