美文网首页
Cocos Creator设计方便维护的面向对象结构的一种方式

Cocos Creator设计方便维护的面向对象结构的一种方式

作者: gz008 | 来源:发表于2018-08-15 20:38 被阅读0次

1.通常的写一个类的方式

cc.Class({

    extends: cc.Component,

    properties: {
        label: {
            default: null,
            type: cc.Label
        },
        // defaults, set visually when attaching this script to the Canvas
        text: 'Hello, World!'
    },

    // use this for initialization
    onLoad: function () {
        this.label.string = this.text;
    },

    // called every frame
    update: function (dt) {

    },

    //设置UI相关函数
    showHello() {

    },
    
    //触摸事件相关函数
    onTouchHello() {

    },
    
    //网络消息相关函数
    onMsgHello() {

    },

});

缺陷
通常来说,一个类里面会包含不止一个showXXX()onTouchXXX()onMsgXXX(),这样会导致这个类文件过于庞大,可能一个类会包含几千行代码,找某个东西的时候不是很清晰,那么如何解决这个问题?

2.C++里面一般会如何维护一个庞大的类

HelloWorld.png
//HelloWorld.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Scene
{
public:

    static cocos2d::Scene* scene();

    ...

    //
    void showHello();

    //
    void onTouchHello(Ref* sender);

    //
    void onMsgHello();

};

#endif // __HELLOWORLD_SCENE_H__

//HelloWorld.cpp
#include "HelloWorld.h"

Scene* HelloWorld::scene()
{
     return HelloWorld::create();
}
//HelloWorldShowUI.cpp
#include "HelloWorld.h"

void HelloWorld::showHello()
{

}
//HelloWorldTouchEvent.cpp
#include "HelloWorld.h"

void HelloWorld::onTouchHello(Ref* sender)
{
    
}
//HelloWorldMsgCallfunc.cpp
#include "HelloWorld.h"

void HelloWorld::onMsgHello()
{

}

如上所示,我们可以把一个类分成多个文件,不同的文件对应不同种类的相关函数,这样的话,寻找相应的函数就会方便很多。那么,如何用JS实现这种多文件描述同一个类结构?

3.JS设计一种多文件描述同一个类的方式

关键点

  • JS的实例可以获取成员的定义
Object.getOwnPropertyDescriptor(obj, prop)
  • JS的实例可以动态增加成员
Object.defineProperty(obj, prop, descriptor)

想法

  • HelloWorld的每个种类(showXXX、onTouchXXX、onMsgXXX)的函数的集合分别组成一个类
  • HelloWorld构造函数里面,获取其他文件中的函数属性并定义到自身原型链中

实现

  • 脚本的文件结构


    脚本文件结构
//HelloWorld.js
cc.Class({
    extends: cc.Component,

    properties: {
        label: {
            default: null,
            type: cc.Label
        },
        // defaults, set visually when attaching this script to the Canvas
        text: 'Hello, World!'
    },

    // use this for initialization
    onLoad: function () {
        this.showHello()
    },

    // called every frame
    update: function (dt) {

    },

});
//HelloWorldShowUI.js
cc.Class({
    extends: cc.Component,

    properties: {
    },
    
    showHello() {
        this.label.string = this.text;
    },
});
//HelloWorldTouchEvent.js
cc.Class({
    extends: cc.Component,

    properties: {
    },
    
    onTouchHello() {

    },

});
//HelloWorldMsgCallfunc.js
cc.Class({
    extends: cc.Component,

    properties: {
    },
    
    onMsgHello() {

    },

});
  • HelloWorld构造函数或onLoad里面导入其他文件
cc.Class({
    extends: cc.Component,

    properties: {
        label: {
            default: null,
            type: cc.Label
        },
        // defaults, set visually when attaching this script to the Canvas
        text: 'Hello, World!'
    },

    // use this for initialization
    onLoad: function () {
        //提取其他文件中的函数到当前对象
        let scripts = [
            'HelloWorldShowUI',
            'HelloWorldMsgCallfunc',
            'HelloWorldTouchEvent',
        ]
        for (let i = 0; i < scripts.length; i++) {
            let script = scripts[i]
            let cls = require(script)
            let instance = new cls()
            this.transferProto2Object(this, instance)
        }
        this.showHello()
    },

    // called every frame
    update: function (dt) {

    },
    
    //导入其他类中的属性到当前实例
    //每个类都支持继承,且最终必须继承自cc.Component,把cc.Component当成探索终点
    transferProto2Object: function (obj, instance) {
        let regex3 = new RegExp('__\\w+__')  
        let proto = instance.__proto__
        //最大搜索深度3,即当前只能继承一次
        let afterfilter = []
        let inherit = 3
        for (let i = 0; i < inherit; i++) {
            if (proto.__classname__ != 'cc.Component') {
                //过滤系统函数
                let notsystem = Object.keys(proto)
                // cc.log("notsystem = ", notsystem)
                for (let i =0; i < notsystem.length; i++) {
                    let test = regex3.test(notsystem[i])
                    if (!test) {
                        let descriptor = Object.getOwnPropertyDescriptor(proto, notsystem[i])
                        afterfilter.push({
                            name: notsystem[i],
                            descriptor: descriptor,
                        })
                    }
                }
                proto = proto.__proto__
            } else {
                break
            }
        }
        //定义到当前类对象
        for (;;) {
            if (afterfilter.length == 0) {
                break
            }
            let element = afterfilter.pop()
            Object.defineProperty(obj.__proto__, element.name, element.descriptor)          
        }

    },
});

缺陷
节点的触摸事件必须使用代码注册,无法使用拖拽方式

相关文章

  • Cocos Creator设计方便维护的面向对象结构的一种方式

    1.通常的写一个类的方式 缺陷:通常来说,一个类里面会包含不止一个showXXX(),onTouchXXX(),o...

  • 面向对象实例--常用组件

    1.面向对象: 易维护: 采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部...

  • JavaForAndroid-04

    一、面向对象面向对象是一种编程方式、是一种思维方式,不是一种编程语言。如何学习?语法、思维方式、设计原则、设计模式...

  • cocos creator 入门简介

    cocos creator 入门简介 一、安装cocos creator 与IDE cocos creator下载...

  • 基础面试题

    1. 什么是面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰。...

  • 2020最新PHP面试100题(一)

    一、什么是面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰。主...

  • C#设计模式:六大原则(上)

      面向对象设计原则,是一种指导思想,在程序设计过程中,要尽量的去遵守这些原则,用于解决面向对象设计中的可维护性,...

  • 九、面向对象

    一、什么是面向过程、面向对象 面向过程与面向对象都是我们编程中,编写程序的一种思维方式。  面向过程的程序设计方式...

  • Java基础-面向对象

    理解什么是面向过程、面向对象 面向过程与面向对象都是我们编程中,编写程序的一种思维方式。 面向过程的程序设计方式,...

  • PHP面试题:什么事面向对象?主要特征是什么?

    什么事面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰。主要特...

网友评论

      本文标题:Cocos Creator设计方便维护的面向对象结构的一种方式

      本文链接:https://www.haomeiwen.com/subject/qdrbbftx.html