温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

【cocos2d-x从c++到js】04:cocos2d-x for js中的继承

发布时间:2020-07-14 11:23:01 阅读:9278 作者:老G 栏目:游戏开发
C++开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

对于面向对象语言来说,继承机制是代码复用的基础,很不幸的是javascript作为一个基于原型继承的语言,并没有在本身语言层面上直接作出对类继承的支持。

但是js语言拥有很强大的表现力。所以一般是js的使用者自行设计一套继承机制,这个机制必须包括几个点,对私有访问权限的模拟,对属性和类属性的不同实现,对方法覆盖的支持,对父类被覆盖方法的访问等。

cocos2d-x中,整合了两套继承机制,看《MoonWarriors》例子中的源码SysMenu.js文件 

var SysMenu = cc.Layer.extend({     _ship:null,      ctor:function () {         cc.associateWithNative( this, cc.Layer );     },     init:function () {         var bRet = false;         if (this._super()) {             winSize = cc.Director.getInstance().getWinSize();             var sp = cc.Sprite.create(s_loading);             sp.setAnchorPoint(cc.p(0,0));             this.addChild(sp, 01);              var logo = cc.Sprite.create(s_logo);             logo.setAnchorPoint(cc.p(00));             logo.setPosition(0250);             this.addChild(logo, 101);              var newGameNormal = cc.Sprite.create(s_menu, cc.rect(0012633));             var newGameSelected = cc.Sprite.create(s_menu, cc.rect(03312633));             var newGameDisabled = cc.Sprite.create(s_menu, cc.rect(033 * 212633));              var gameSettingsNormal = cc.Sprite.create(s_menu, cc.rect(126012633));             var gameSettingsSelected = cc.Sprite.create(s_menu, cc.rect(1263312633));             var gameSettingsDisabled = cc.Sprite.create(s_menu, cc.rect(12633 * 212633));              var aboutNormal = cc.Sprite.create(s_menu, cc.rect(252012633));             var aboutSelected = cc.Sprite.create(s_menu, cc.rect(2523312633));             var aboutDisabled = cc.Sprite.create(s_menu, cc.rect(25233 * 212633));              var newGame = cc.MenuItemSprite.create(newGameNormal, newGameSelected, newGameDisabled, function () {                 this.onButtonEffect();                 flareEffect(thisthisthis.onNewGame);             }.bind(this));             var gameSettings = cc.MenuItemSprite.create(gameSettingsNormal, gameSettingsSelected, gameSettingsDisabled, this.onSettings, this);             var about = cc.MenuItemSprite.create(aboutNormal, aboutSelected, aboutDisabled, this.onAbout, this);              var menu = cc.Menu.create(newGame, gameSettings, about);             menu.alignItemsVerticallyWithPadding(10);             this.addChild(menu, 12);             menu.setPosition(winSize.width / 2, winSize.height / 2 - 80);             this.schedule(this.update, 0.1);              var tmp = cc.TextureCache.getInstance().addImage(s_ship01);             this._ship = cc.Sprite.createWithTexture(tmp,cc.rect(0456038));             this.addChild(this._ship, 04);             var pos = cc.p(Math.random() * winSize.width, 0);             this._ship.setPosition( pos );             this._ship.runAction(cc.MoveBy.create(2, cc.p(Math.random() * winSize.width, pos.y + winSize.height + 100)));              if (MW.SOUND) {                 cc.AudioEngine.getInstance().setMusicVolume(0.7);                 cc.AudioEngine.getInstance().playMusic(s_mainMainMusic, true);             }              bRet = true;         }         return bRet;     },     onNewGame:function (pSender) {         var scene = cc.Scene.create();         scene.addChild(GameLayer.create());         scene.addChild(GameControlMenu.create());         cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2, scene));     },     onSettings:function (pSender) {         this.onButtonEffect();         var scene = cc.Scene.create();         scene.addChild(SettingsLayer.create());         cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2, scene));     },     onAbout:function (pSender) {         this.onButtonEffect();         var scene = cc.Scene.create();         scene.addChild(AboutLayer.create());         cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2, scene));     },     update:function () {         if (this._ship.getPosition().y > 480) {             var pos = cc.p(Math.random() * winSize.width, 10);             this._ship.setPosition( pos );             this._ship.runAction( cc.MoveBy.create(                 parseInt(5 * Math.random(), 10),                 cc.p(Math.random() * winSize.width, pos.y + 480)));         }     },     onButtonEffect:function(){         if (MW.SOUND) {             var s = cc.AudioEngine.getInstance().playEffect(s_buttonEffect);         }     } });  SysMenu.create = function () {     var sg = new SysMenu();     if (sg && sg.init()) {         return sg;     }     return null; };  SysMenu.scene = function () {     var scene = cc.Scene.create();     var layer = SysMenu.create();     scene.addChild(layer);     return scene; }; 

这个extend继承写法由John Resig创造,John Resig是JS领域的大神,而且网上有很多粉丝给他编的段子,非常有趣。

例子中使用父类cc.Layer.extend方法来启动继承,传入一个对象字面量{},这个字面量可以包含对象属性和对象方法,最终由extend来完成接口绑定,返回一个构造函数赋值给SysMenu。

对于类方法(也就是通常意义上的静态方法),使用的是js最传统的方式,直接给构造函数指定属性即可。

这种编写代码的方式非常简单,而且也很优美。更重要的是,这种写法,非常符合C++或java程序员的排版审美。

关于继承的理解。js里面的原型继承和基于类的继承方式截然不同,内部是在维护一个原型链,链上的节点与节点之间是链接关系(注意:不是赋值,也不是拷贝)。可以先看一下《权威指南》那本书是怎么讲的,不过很遗憾,那本书关于原型继承的图解画的不太好……千万不要搞代数式的替换和死记硬背,那样你很难掌握原型链的本质。

另外,强烈推荐三生石上的系列文章《JavaScript继承详解》

JavaScript继承详解

JavaScript继承详解(二)

JavaScript继承详解(三)

JavaScript继承详解(四)

JavaScript继承详解(五)

JavaScript继承详解(六)

有时间的话,我会把三生石上的文章配一些详细的原型链描述图,这样就可以很容易的掌握js的原型链了。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×