State/StateManager/StateManager.js

  1. /**
  2. * Менеджер состояний игры.
  3. * Позволяет переключаться между состояниями игры без ожидания следующего игрового кадра (синхронные состояния).
  4. * При использовании синхронных состояний, движок остается в последнем асинхронном состоянии, но все вызовы
  5. * перенаправляются на новое синхронное состояние.
  6. * @param {Phaser.Game} game игра
  7. * @class
  8. * @extends {Phaser.StateManager}
  9. * @see {@link http://phaser.io/docs/2.6.2/Phaser.StateManager.html}
  10. */
  11. var StateManager = function(game){
  12. Phaser.StateManager.call(this, game);
  13. /**
  14. * Синхронные состояния (в дополнение к `states`)
  15. * @type {Object}
  16. */
  17. this.statesSync = {};
  18. /**
  19. * Текущее синхронное состояние игры.
  20. * Считается реальным состоянием игры (выполнятся методы этого состояния).
  21. * Чтобы узнать асинхронное состояние используется `current`.
  22. * @type {string}
  23. */
  24. this.currentSync = null;
  25. };
  26. extend(StateManager, Phaser.StateManager);
  27. /**
  28. * Текущее состояние (синхронное или асинхронное).
  29. * @return {State} Текущее состояние.
  30. */
  31. StateManager.prototype.getCurrent = function(){
  32. if(this.currentSync == this.current){
  33. return this.states[this.current];
  34. }
  35. else{
  36. return this.statesSync[this.currentSync];
  37. }
  38. };
  39. StateManager.prototype.getCurrentState = StateManager.prototype.getCurrent;
  40. /**
  41. * Добавляет асинхронное состояние в игру.
  42. * @type {function}
  43. */
  44. StateManager.prototype._addAsync = Phaser.StateManager.prototype.add;
  45. /**
  46. * Добавляет новое состояние в игру.
  47. * @param {State} state Состояние.
  48. * @param {boolean} isAsync Является ли состояние асинхронным.
  49. * @param {boolean} start Нужно ли переходить к этому состоянию сразу.
  50. */
  51. StateManager.prototype.add = function(state, isAsync, start){
  52. if(start){
  53. this.currentSync = state.key;
  54. }
  55. if(isAsync){
  56. this._addAsync(state.key, state, start);
  57. }
  58. else{
  59. this.statesSync[state.key] = state;
  60. if(start){
  61. this.change(state.key);
  62. }
  63. }
  64. };
  65. /**
  66. * Меняет состояние игры.
  67. * Переходы к асинхронным состояниям плохо работают с ответами серверу и анимациями,
  68. * поэтому такие переходы не рекомендуются и кидают предупреждение в консоль.
  69. * @param {string} key название состояния
  70. */
  71. StateManager.prototype.change = function(key, finishSequence){
  72. if(finishSequence === undefined){
  73. finishSequence = true;
  74. }
  75. var oldState, state;
  76. if(this.states[key]){
  77. console.warn('StateManager: changing to async state', key);
  78. if(this.current != this.currentSync){
  79. state = this.statesSync[this.currentSync];
  80. state.shutdown();
  81. this.currentSync = key;
  82. }
  83. this.start(key, false, false);
  84. }
  85. else if(this.statesSync[key]){
  86. if(finishSequence){
  87. actionHandler.sequencer.finish(true);
  88. }
  89. oldState = this.getCurrent();
  90. state = this.statesSync[key];
  91. oldState.shutdown(key);
  92. this.currentSync = key;
  93. state.preload(oldState.key);
  94. state.init(oldState.key);
  95. state.create(oldState.key);
  96. if(this.game.inDebugMode){
  97. console.log('StateManager: state changed to', key);
  98. }
  99. }
  100. else{
  101. console.error('StateManager: state not found', key);
  102. }
  103. };