在开发游戏之前,做好准备,将会大大降低之后或者日后开发一款新的小游戏所花费的时间。
因此开发一个灵活简单通用的框架必不可少。
第一集,给大家带来的是插件系统这个简单的模块化管理。
为何,在这里没有采取puremvc类似的ts框架?
原因很简单,过于注重MVC会影响灵活性,而且不一定容易让别人上手,当然这些都是个人选择了,我觉得这么开发效率高,而且思路清晰,就使这个插件系统了。
插件管理:
这是一个简单的插件系统关系图。
UML
1.建立一个基类BasePlugin来作为上层接口和功能提供,它继承于Laya.EventDipatcher,方便交流和流程处理。
2.我们所有的模块Plugin均继承于BasePlugin,进行各自功能开发。
3.单例PluginManager,把这些插件管理起来,然后Plugin可以通过这样一个管理器,进行交流,加载,卸载等。
4.Controller这部分就由这部分组成,至于MV的部分,后面会各自建立,然后再把这三大块串联起来。
是不是非常简单?
大家只要开发和管理自己的插件,并且按照约定的插件使用方法,就不容易影响别人开发。
举个栗子:
如果我现在有一个战斗模块,需要用到背包数据,获取用户信息,使用输入模块。我就可以通过一个配置把这些插件和数据组合起来和使用,很方便,至于View是不能影响我们的逻辑模块的,它只会受数据的变化。
此插件系统,是基于Laya.EventDispatcher和我之前文章中的数据结构库开发
PluginManager.ts
class PluginManager extends Laya.EventDispatcher {
private _plugins: Dictionary<string, BasePlugin> = new Dictionary<string, BasePlugin>();
private static _instance: PluginManager = null;
constructor() {
super();
}
public static getInstance(): PluginManager {
return this._instance || (this._instance = new this());
}
public initialize(): void {
this.addPlugin(new LoginPlugin()).init();
}
public openPlugin(pluginName:string, closeAll:boolean = true, data?:any):void{
if(closeAll){
this.closeAllPlugins();
}
let plugin:BasePlugin = this.getPlugin(pluginName);
if(plugin != null){
plugin.open(data);
}
}
public closePlugin(pluginName:string):void{
let plugin:BasePlugin = this.getPlugin(pluginName);
if(plugin != null){
plugin.close();
}
}
public closeAllPlugins():void{
for (let pair of this._plugins){
if(pair.value != null){
(pair.value as BasePlugin).close();
}
}
}
public addPlugin(plugin: any): BasePlugin {
let pluginName: string = plugin.name;
if (this._plugins.containsKeyValue(pluginName)) {
Logger.log(`plugin ${pluginName} is exists.`);
return this._plugins.get(pluginName);
}
this._plugins.addKeyValue(pluginName, plugin)
return plugin;
}
public removePlugin(pluginName: string): void {
let plugin: BasePlugin = this._plugins.get(pluginName);
if (plugin != null) {
Logger.log(`plugin ${pluginName} is no exists, cant remove.`);
return;
}
this._plugins.removeKeyValue(pluginName);
}
public getPlugin(pluginName: string): BasePlugin {
return this._plugins.get(pluginName);
}
public removePlugins(): void {
this._plugins.clear();
}
}
BasePlugin.ts
class BasePlugin extends Laya.EventDispatcher {
constructor() {
super();
}
public init() {
// Logger.log("BasePlugin init");
}
public load(assets?:any) {
if(assets !== null){
Laya.loader.load(assets, Handler.create(this, this.onComplete), Handler.create(this, this.onProgress, null, false));
}
}
private onComplete(){
this.dispatchEvent(PluginEvent.COMPLETE);
}
private onProgress(ratio:number){
let progress:number = Math.floor(ratio*100);
this.dispatchEvent(PluginEvent.PROGRESS, progress);
}
public unload() {
// Logger.log("BasePlugin unload");
}
public open(data?:any) {
// Logger.log("BasePlugin open");
}
public close() {
// Logger.log("BasePlugin close");
}
public get name(){
return this.constructor.name;
}
protected _handlerDict:Dictionary<number, Handler> = new Dictionary<number, Handler>();
public registerHandler(cmd:number, handler:Handler){
if(this._handlerDict.containsKeyValue(cmd)){
return;
}
this._handlerDict.addKeyValue(cmd, handler);
}
public async sendReq(cmd:number, req:any) {
let res:any = await this.testSend();
let handler:Handler = this._handlerDict.get(cmd);
if(handler !== null){
handler.runWith([cmd, res, req]);
}
}
// 发送事件
public dispatchEvent(type:string, data?:any){
this.event(type, data);
}
}
LoginPlugin.ts
class LoginPlugin extends BasePlugin {
constructor() {
super();
}
private _createTime:number = 0;
public open() {
// 登录界面
let page:LoginPage = UIManager.getInstance().openPage(LoginPage);
page.pow.play();
}
public close() {
Logger.log("close");
UICommon.closeLoading();
UIManager.getInstance().closePage(LoginPage);
}
public login(id:number, name:string, pwd:string):void{
let ud:UserData = new UserData();
ud.id = id;
ud.name = name;
ud.powid = 1;
this.sendReq(1, ud);
}
public init() {
this.registerHandler(1, Handler.create(this, this.onResLogin));
}
public onResLogin(cmd:number, res:any, req:any){
Logger.log("登录成功");
}
}
拿了个LoginPlugin作为例子。
此处还带有的额外的知识:
简单的Logger(其实暂时没做些什么,只是打上了个标识)
class Logger{
public static log(...args){
console.log(`[DEBUG INFO] `, ...args);
}
}
ts单例写法
private static _instance: PluginManager = null;
public static getInstance(): PluginManager {
return this._instance || (this._instance = new this());
}
不知不觉写到现在,今晚就写到这,希望能对你有点启发,或者有何不妥之处,不吝交流~
网友评论