查看: 2809|回复: 3

[交流讨论] [无用研究]将显示对象与MV解耦

[复制链接]
梦石
0
星屑
1907
在线时间
1555 小时
注册时间
2013-4-13
回帖
783
发表于 2020-6-14 19:36:11 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
大家都知道能够显示在游戏画面的有Sprite和各种Window,
实际上这些类都是从PIXI.Container继承而来的,
当我们要自己设计一个可显示对象的时候, 其实可以从Container这个级别开始
虽然会失去很多预设功能, 不过这些都可以自己按需求加回去
另一个问题是几个平行的可显示对象互相交互也需要互相引用
这里通过引用一个订阅者, 解决了这个问题

下面是具体玩法:
[pre lang="javascript"]// 模拟异步行为的等待
const delay = (timeout) => {
  return new Promise((resolve) => {
    setTimeout(resolve, timeout);
  });
};

const buildTestObject = () => {
  // 实例一个建造者
  const builder = GameObject.builder();
  // 读取Bitmap
  const windowskin = ImageManager.loadSystem('Window');
  const face = ImageManager.loadFace('Actor1');
  // 随便弄俩精灵, 一个背景, 一个头像
  windowBackSprite = new Sprite();
  windowBackSprite.alpha = 192 / 255;
  windowContentsSprite = new Sprite();
  windowContentsSprite.bitmap = new Bitmap(500, 500);

  // 开始建造
  builder
    // 当一切加载完毕以后执行
    // 这里初始化了绑定的数据和窗口大小
    .setupHandler('start', (self) => {
      console.log('start');
      self.initData({ faceIndex: 0 });
      self.x = 50;
      self.y = 50;
      self.width = 200;
      self.height = 200;
    })
    // 每次更新的时候执行
    // 从data里获取faceIndex
    // 判断用户输入选择向左或者向右切换头像
    .setupHandler('update', (self) => {
      const { faceIndex } = self.getData();
      if (Input.isRepeated('left')) {
        self.setData({ faceIndex: (faceIndex + 7) % 8 });
      }
      if (Input.isRepeated('right')) {
        self.setData({ faceIndex: (faceIndex + 1) % 8 });
      }
    })
    // 初始化的时候触发, 会等待所有异步操作完毕
    .setupHandler('create', async (self) => {
      console.log('creating...');
      await Promise.all([
        new Promise((resolve) => {
          windowskin.addLoadListener(resolve);
        }),
        new Promise((resolve) => {
          face.addLoadListener(resolve);
        }),
      ]);
      console.log('loaded...');
      await delay(1000);
      console.log('done!');
    })
    // 当更新绑定数据时候, initData不会触发change事件
    // 判断faceIndex是否发生了改变
    // 可以根据特定的值发生了变化来执行对应的操作
    .setupHandler('change', (self, oldData) => {
      if (oldData.faceIndex !== self.getData().faceIndex)
        self.triggerEvent(self.getDrawHandler('face'));
    })
    // 添加一个精灵
    .addSprite('windowskin', windowBackSprite, (self) => {
      var w = self.width;
      var h = self.height;
      var bitmap = new Bitmap(w, h);
      windowBackSprite.bitmap = bitmap;
      windowBackSprite.setFrame(0, 0, w, h);
      if (w > 0 && h > 0 && windowskin) {
        var p = 96;
        bitmap.blt(windowskin, 0, 0, p, p, 0, 0, w, h);
      }
    })
    // 添加另一个精灵
    // 会从绑定数据中读取信息
    .addSprite('face', windowContentsSprite, (self) => {
      windowContentsSprite.bitmap.clear();
      var faceIndex = self.getData().faceIndex;
      var x = 0;
      var y = 0;
      var width = Window_Base._faceWidth;
      var height = Window_Base._faceHeight;
      var bitmap = ImageManager.loadFace('Actor1');
      var pw = Window_Base._faceWidth;
      var ph = Window_Base._faceHeight;
      var sw = Math.min(width, pw);
      var sh = Math.min(height, ph);
      var dx = Math.floor(x + Math.max(width - pw, 0) / 2);
      var dy = Math.floor(y + Math.max(height - ph, 0) / 2);
      var sx = (faceIndex % 4) * pw + (pw - sw) / 2;
      var sy = Math.floor(faceIndex / 4) * ph + (ph - sh) / 2;
      windowContentsSprite.bitmap.blt(
        bitmap,
        sx,
        sy,
        sw,
        sh,
        dx,
        dy,
        width,
        height
      );
    });
  // 完成建造
  return builder.build();
};
[/pre]

在控制台输入
const a = buildTestObject()
SceneManager._scene.addChild(a)
就可以看到效果了:

2.png

以下是当文档来看也是极好的Typescript版本
[pre lang="typescript"]declare type Maybe<T> = T | null;
/**
* 事件响应, 可以返回一个Promise
*/
type EventHandler = (self: GameObject, ...args: any[]) => void | Promise<any>;
/**
* 事件名
*/
type EventName =
  | 'create'
  | 'terminate'
  | 'start'
  | 'update'
  | 'change'
  | 'draw'
  | string;
/**
* 处理全局消息通信
*/
class GlobalEventManager {
  static listeners: Record<EventName, GameObject[]> = {};

  private static getListeners(eventName: EventName) {
    const listeners = this.listeners[eventName] || [];
    if (!listeners.length) this.listeners[eventName] = listeners;
    return listeners;
  }

  /**
   * 订阅事件
   */
  public static subscribe(item: GameObject, eventName: EventName) {
    const listeners = this.getListeners(eventName);
    if (listeners.find((listener) => listener === item)) return;
    listeners.push(item);
  }

  /**
   * 取消订阅
   */
  public static unsubscribe(item: GameObject, eventName: EventName) {
    const listeners = this.getListeners(eventName);
    const index = listeners.indexOf(item);
    if (index >= 0) listeners.splice(index, 1);
  }

  /**
   * 取消全部订阅
   */
  public static removeListener(item: GameObject) {
    Object.keys(this.listeners).forEach((eventName) => {
      this.unsubscribe(item, eventName);
    });
  }

  /**
   * 广播事件
   */
  public static dispatch(eventName: EventName, ...args: []) {
    const listeners = this.listeners[eventName] || [];
    listeners.forEach((item) => {
      item.triggerEvent(eventName, ...args);
    });
  }
}

class GameObjectBuilder<T = any> {
  gameObject: GameObject<T>;
  constructor() {
    this.gameObject = new GameObject();
  }

  setupHandler(eventName: EventName, eventHandler: EventHandler) {
    this.gameObject.setupHandler(eventName, eventHandler);
    return this;
  }

  initData(data: Maybe<T>) {
    this.gameObject.initData(data);
    return this;
  }

  addSprite(name: string, sprite: PIXI.Sprite, handler: EventHandler) {
    this.gameObject.addSprite(name, sprite, handler);
    return this;
  }

  build() {
    return this.gameObject;
  }
}

class GameObject<T = any> extends PIXI.Container {
  static builder() {
    return new GameObjectBuilder();
  }
  private _width: number;
  private _height: number;
  children: GameObject[] = [];
  willCreate: boolean = true;
  willTerminate: boolean = false;
  isCreated: boolean = false;
  isTerminated: boolean = false;
  isStarted: boolean = false;
  eventHandlers: Record<EventName, EventHandler> = {};
  data: Maybe<T> = null;
  sprites: Record<string, PIXI.Sprite> = {};

  /**
   * 覆写PIXI默认的宽高, 防止图像拉伸
   */
  constructor(width = 0, height = 0) {
    super();
    this._width = width;
    this._height = height;
    Object.defineProperties(this, {
      width: {
        get: () => this._width,
        set: (w) => {
          this._width = w;
          this.refresh();
        },
      },
      height: {
        get: () => this._height,
        set: (h) => {
          this._height = h;
          this.refresh();
        },
      },
    });
  }

  /**
   * 注册事件处理方法或异步方法
   */
  setupHandler(eventName: EventName, eventHandler: EventHandler) {
    this.eventHandlers[eventName] = eventHandler;
  }

  /**
   * 移除已注册的方法
   */
  removeHandler(eventName: EventName) {
    delete this.eventHandlers[eventName];
  }

  /**
   * 手动触发事件
   */
  triggerEvent(eventName: EventName, ...args: any[]): void | Promise<any> {
    const handler = this.eventHandlers[eventName];
    if (handler) return handler(this, ...args);
  }

  /**
   * 获取绘制事件名
   */
  getDrawHandler(name: string) {
    return `draw${name.replace(/^./, (str) => str.toUpperCase())}`;
  }

  /**
   * 重绘全部精灵
   */
  refresh() {
    Object.keys(this.sprites).forEach((name) => {
      this.triggerEvent(this.getDrawHandler(name));
    });
  }

  /**
   * 添加精灵
   */
  addSprite(name: string, sprite: PIXI.Sprite, handler: EventHandler) {
    this.sprites[name] = sprite;
    this.setupHandler(this.getDrawHandler(name), handler);
    this.addChild(sprite);
  }

  /**
   * 初始化数据, 不会触发数据更新事件
   */
  initData(data: Maybe<T>) {
    this.data = data;
  }

  /**
   * 获取数据
   */
  getData() {
    return this.data;
  }

  /**
   * 数据绑定, 触发数据更新事件
   */
  setData(data: Maybe<T>) {
    const oldData = this.data;
    this.data = data;
    this.triggerEvent('change', oldData);
  }

  /**
   * 第一次载入场景时触发, 用于处理异步行为
   */
  async onCreate() {
    this.willCreate = false;
    await this.triggerEvent('create');
    this.isCreated = true;
  }

  /**
   * 完成初始化后触发, 用于初始化对象
   */
  onStart() {
    this.triggerEvent('start');
    this.refresh();
    this.isStarted = true;
  }

  /**
   * 每一帧更新事件, 不要在这里重绘任何东西
   */
  onUpdate() {
    this.triggerEvent('update');
    this.updateChildren();
  }

  /**
   * 用来处理终止事件
   */
  async onTerminate() {
    this.willTerminate = false;
    await this.triggerEvent('terminate');
    this.isTerminated = true;
    GlobalEventManager.removeListener(this);
  }

  /**
   * 主循环
   */
  update() {
    if (this.isStarted) {
      this.onUpdate();
    } else if (this.willCreate) {
      this.onCreate();
    } else if (
      this.isCreated &&
      this.children.every((child) => child.isCreated !== false)
    ) {
      this.onStart();
    } else if (
      this.willTerminate &&
      this.children.every((child) => child.isTerminated !== false)
    ) {
      this.onTerminate();
    }
  }

  /**
   * 更新子对象
   */
  updateChildren() {
    this.children.forEach((child) => {
      child.update();
    });
  }

  /**
   * 终止对象
   */
  terminate() {
    this.willTerminate = true;
    this.children.forEach((child) => {
      child.terminate();
    });
  }
}
[/pre]

讲人话版JS:
[pre lang="javascript"]"use strict";
/**
* 处理全局消息通信
*/
class GlobalEventManager {
    static getListeners(eventName) {
        const listeners = this.listeners[eventName] || [];
        if (!listeners.length)
            this.listeners[eventName] = listeners;
        return listeners;
    }
    /**
     * 订阅事件
     */
    static subscribe(item, eventName) {
        const listeners = this.getListeners(eventName);
        if (listeners.find((listener) => listener === item))
            return;
        listeners.push(item);
    }
    /**
     * 取消订阅
     */
    static unsubscribe(item, eventName) {
        const listeners = this.getListeners(eventName);
        const index = listeners.indexOf(item);
        if (index >= 0)
            listeners.splice(index, 1);
    }
    /**
     * 取消全部订阅
     */
    static removeListener(item) {
        Object.keys(this.listeners).forEach((eventName) => {
            this.unsubscribe(item, eventName);
        });
    }
    /**
     * 广播事件
     */
    static dispatch(eventName, ...args) {
        const listeners = this.listeners[eventName] || [];
        listeners.forEach((item) => {
            item.triggerEvent(eventName, ...args);
        });
    }
}
GlobalEventManager.listeners = {};
class GameObjectBuilder {
    constructor() {
        this.gameObject = new GameObject();
    }
    setupHandler(eventName, eventHandler) {
        this.gameObject.setupHandler(eventName, eventHandler);
        return this;
    }
    initData(data) {
        this.gameObject.initData(data);
        return this;
    }
    addSprite(name, sprite, handler) {
        this.gameObject.addSprite(name, sprite, handler);
        return this;
    }
    build() {
        return this.gameObject;
    }
}
class GameObject extends PIXI.Container {
    /**
     * 覆写PIXI默认的宽高, 防止图像拉伸
     */
    constructor(width = 0, height = 0) {
        super();
        this.children = [];
        this.willCreate = true;
        this.willTerminate = false;
        this.isCreated = false;
        this.isTerminated = false;
        this.isStarted = false;
        this.eventHandlers = {};
        this.data = null;
        this.sprites = {};
        this._width = width;
        this._height = height;
        Object.defineProperties(this, {
            width: {
                get: () => this._width,
                set: (w) => {
                    this._width = w;
                    this.refresh();
                },
            },
            height: {
                get: () => this._height,
                set: (h) => {
                    this._height = h;
                    this.refresh();
                },
            },
        });
    }
    static builder() {
        return new GameObjectBuilder();
    }
    /**
     * 注册事件处理方法或异步方法
     */
    setupHandler(eventName, eventHandler) {
        this.eventHandlers[eventName] = eventHandler;
    }
    /**
     * 移除已注册的方法
     */
    removeHandler(eventName) {
        delete this.eventHandlers[eventName];
    }
    /**
     * 手动触发事件
     */
    triggerEvent(eventName, ...args) {
        const handler = this.eventHandlers[eventName];
        if (handler)
            return handler(this, ...args);
    }
    /**
     * 获取绘制事件名
     */
    getDrawHandler(name) {
        return `draw${name.replace(/^./, (str) => str.toUpperCase())}`;
    }
    /**
     * 重绘全部精灵
     */
    refresh() {
        Object.keys(this.sprites).forEach((name) => {
            this.triggerEvent(this.getDrawHandler(name));
        });
    }
    /**
     * 添加精灵
     */
    addSprite(name, sprite, handler) {
        this.sprites[name] = sprite;
        this.setupHandler(this.getDrawHandler(name), handler);
        this.addChild(sprite);
    }
    /**
     * 初始化数据, 不会触发数据更新事件
     */
    initData(data) {
        this.data = data;
    }
    /**
     * 获取数据
     */
    getData() {
        return this.data;
    }
    /**
     * 数据绑定, 触发数据更新事件
     */
    setData(data) {
        const oldData = this.data;
        this.data = data;
        this.triggerEvent('change', oldData);
    }
    /**
     * 第一次载入场景时触发, 用于处理异步行为
     */
    async onCreate() {
        this.willCreate = false;
        await this.triggerEvent('create');
        this.isCreated = true;
    }
    /**
     * 完成初始化后触发, 用于初始化对象
     */
    onStart() {
        this.triggerEvent('start');
        this.refresh();
        this.isStarted = true;
    }
    /**
     * 每一帧更新事件, 不要在这里重绘任何东西
     */
    onUpdate() {
        this.triggerEvent('update');
        this.updateChildren();
    }
    /**
     * 用来处理终止事件
     */
    async onTerminate() {
        this.willTerminate = false;
        await this.triggerEvent('terminate');
        this.isTerminated = true;
        GlobalEventManager.removeListener(this);
    }
    /**
     * 主循环
     */
    update() {
        if (this.isStarted) {
            this.onUpdate();
        }
        else if (this.willCreate) {
            this.onCreate();
        }
        else if (this.isCreated &&
            this.children.every((child) => child.isCreated !== false)) {
            this.onStart();
        }
        else if (this.willTerminate &&
            this.children.every((child) => child.isTerminated !== false)) {
            this.onTerminate();
        }
    }
    /**
     * 更新子对象
     */
    updateChildren() {
        this.children.forEach((child) => {
            child.update();
        });
    }
    /**
     * 终止对象
     */
    terminate() {
        this.willTerminate = true;
        this.children.forEach((child) => {
            child.terminate();
        });
    }
}
[/pre]

放弃治疗es5版本:
[pre lang="javascript"]"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments.length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments, j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
/**
* 处理全局消息通信
*/
var GlobalEventManager = /** @class */ (function () {
    function GlobalEventManager() {
    }
    GlobalEventManager.getListeners = function (eventName) {
        var listeners = this.listeners[eventName] || [];
        if (!listeners.length)
            this.listeners[eventName] = listeners;
        return listeners;
    };
    /**
     * 订阅事件
     */
    GlobalEventManager.subscribe = function (item, eventName) {
        var listeners = this.getListeners(eventName);
        if (listeners.find(function (listener) { return listener === item; }))
            return;
        listeners.push(item);
    };
    /**
     * 取消订阅
     */
    GlobalEventManager.unsubscribe = function (item, eventName) {
        var listeners = this.getListeners(eventName);
        var index = listeners.indexOf(item);
        if (index >= 0)
            listeners.splice(index, 1);
    };
    /**
     * 取消全部订阅
     */
    GlobalEventManager.removeListener = function (item) {
        var _this = this;
        Object.keys(this.listeners).forEach(function (eventName) {
            _this.unsubscribe(item, eventName);
        });
    };
    /**
     * 广播事件
     */
    GlobalEventManager.dispatch = function (eventName) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        var listeners = this.listeners[eventName] || [];
        listeners.forEach(function (item) {
            item.triggerEvent.apply(item, __spreadArrays([eventName], args));
        });
    };
    GlobalEventManager.listeners = {};
    return GlobalEventManager;
}());
var GameObjectBuilder = /** @class */ (function () {
    function GameObjectBuilder() {
        this.gameObject = new GameObject();
    }
    GameObjectBuilder.prototype.setupHandler = function (eventName, eventHandler) {
        this.gameObject.setupHandler(eventName, eventHandler);
        return this;
    };
    GameObjectBuilder.prototype.initData = function (data) {
        this.gameObject.initData(data);
        return this;
    };
    GameObjectBuilder.prototype.addSprite = function (name, sprite, handler) {
        this.gameObject.addSprite(name, sprite, handler);
        return this;
    };
    GameObjectBuilder.prototype.build = function () {
        return this.gameObject;
    };
    return GameObjectBuilder;
}());
var GameObject = /** @class */ (function (_super) {
    __extends(GameObject, _super);
    /**
     * 覆写PIXI默认的宽高, 防止图像拉伸
     */
    function GameObject(width, height) {
        if (width === void 0) { width = 0; }
        if (height === void 0) { height = 0; }
        var _this = _super.call(this) || this;
        _this.children = [];
        _this.willCreate = true;
        _this.willTerminate = false;
        _this.isCreated = false;
        _this.isTerminated = false;
        _this.isStarted = false;
        _this.eventHandlers = {};
        _this.data = null;
        _this.sprites = {};
        _this._width = width;
        _this._height = height;
        Object.defineProperties(_this, {
            width: {
                get: function () { return _this._width; },
                set: function (w) {
                    _this._width = w;
                    _this.refresh();
                },
            },
            height: {
                get: function () { return _this._height; },
                set: function (h) {
                    _this._height = h;
                    _this.refresh();
                },
            },
        });
        return _this;
    }
    GameObject.builder = function () {
        return new GameObjectBuilder();
    };
    /**
     * 注册事件处理方法或异步方法
     */
    GameObject.prototype.setupHandler = function (eventName, eventHandler) {
        this.eventHandlers[eventName] = eventHandler;
    };
    /**
     * 移除已注册的方法
     */
    GameObject.prototype.removeHandler = function (eventName) {
        delete this.eventHandlers[eventName];
    };
    /**
     * 手动触发事件
     */
    GameObject.prototype.triggerEvent = function (eventName) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        var handler = this.eventHandlers[eventName];
        if (handler)
            return handler.apply(void 0, __spreadArrays([this], args));
    };
    /**
     * 获取绘制事件名
     */
    GameObject.prototype.getDrawHandler = function (name) {
        return "draw" + name.replace(/^./, function (str) { return str.toUpperCase(); });
    };
    /**
     * 重绘全部精灵
     */
    GameObject.prototype.refresh = function () {
        var _this = this;
        Object.keys(this.sprites).forEach(function (name) {
            _this.triggerEvent(_this.getDrawHandler(name));
        });
    };
    /**
     * 添加精灵
     */
    GameObject.prototype.addSprite = function (name, sprite, handler) {
        this.sprites[name] = sprite;
        this.setupHandler(this.getDrawHandler(name), handler);
        this.addChild(sprite);
    };
    /**
     * 初始化数据, 不会触发数据更新事件
     */
    GameObject.prototype.initData = function (data) {
        this.data = data;
    };
    /**
     * 获取数据
     */
    GameObject.prototype.getData = function () {
        return this.data;
    };
    /**
     * 数据绑定, 触发数据更新事件
     */
    GameObject.prototype.setData = function (data) {
        var oldData = this.data;
        this.data = data;
        this.triggerEvent('change', oldData);
    };
    /**
     * 第一次载入场景时触发, 用于处理异步行为
     */
    GameObject.prototype.onCreate = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.willCreate = false;
                        return [4 /*yield*/, this.triggerEvent('create')];
                    case 1:
                        _a.sent();
                        this.isCreated = true;
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * 完成初始化后触发, 用于初始化对象
     */
    GameObject.prototype.onStart = function () {
        this.triggerEvent('start');
        this.refresh();
        this.isStarted = true;
    };
    /**
     * 每一帧更新事件, 不要在这里重绘任何东西
     */
    GameObject.prototype.onUpdate = function () {
        this.triggerEvent('update');
        this.updateChildren();
    };
    /**
     * 用来处理终止事件
     */
    GameObject.prototype.onTerminate = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.willTerminate = false;
                        return [4 /*yield*/, this.triggerEvent('terminate')];
                    case 1:
                        _a.sent();
                        this.isTerminated = true;
                        GlobalEventManager.removeListener(this);
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * 主循环
     */
    GameObject.prototype.update = function () {
        if (this.isStarted) {
            this.onUpdate();
        }
        else if (this.willCreate) {
            this.onCreate();
        }
        else if (this.isCreated &&
            this.children.every(function (child) { return child.isCreated !== false; })) {
            this.onStart();
        }
        else if (this.willTerminate &&
            this.children.every(function (child) { return child.isTerminated !== false; })) {
            this.onTerminate();
        }
    };
    /**
     * 更新子对象
     */
    GameObject.prototype.updateChildren = function () {
        this.children.forEach(function (child) {
            child.update();
        });
    };
    /**
     * 终止对象
     */
    GameObject.prototype.terminate = function () {
        this.willTerminate = true;
        this.children.forEach(function (child) {
            child.terminate();
        });
    };
    return GameObject;
}(PIXI.Container));
[/pre]

对了, 你问这个东西现在有啥实际价值么?
答案是暂无
不过也许把建造函数封装好了, 能很快得实现按需要载入部分窗体的功能, 而不是每次从一个类继承一个新的开始魔改?

评分

参与人数 1赞 +1 收起 理由
白嫩白嫩的 + 1 精品文章

查看全部评分

夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里
梦石
0
星屑
1343
在线时间
153 小时
注册时间
2020-4-26
回帖
146
发表于 2020-6-14 22:07:52 | 显示全部楼层
好複雜啊,可以問一下用異步的方式建立一個視窗,不會有玩家離開場景了,視窗還沒建立好的情形嗎?

点评

如果不想用loading阻塞玩家体验的话, 那就提前在加载场景的时候把资源放进去吧...  发表于 2020-6-14 22:37
回复

使用道具 举报

梦石
0
星屑
7736
在线时间
1227 小时
注册时间
2008-12-14
回帖
504
发表于 2020-6-15 00:15:24 | 显示全部楼层
最大的价值,如果官方编辑器构建界面按这一套,配上可视化拖拽控件就好了。其实应该也不难,只是官方不想做。
需要购买本人MV插件必须先加wx好友。加不上wx就是本人忙,没时间卖。原则上太久以前的插件也不想卖,因为我也忘了,维护上会不给力。wx名:alskyif    本人插件地址:
   LCK_SRPG梦幻模拟战、火焰纹章类系统
   究极立绘ADV系统

   究极换装统合系统
   究极! 回想与CG系统
   消息文字的距离调整  
   自动返回上一张地图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部