當(dāng)前位置:
首頁(yè) >
利用工厂模式实现怪物系统
發(fā)布時(shí)間:2024/7/23
39
豆豆
生活随笔
收集整理的這篇文章主要介紹了
利用工厂模式实现怪物系统
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
利用工廠模式可以有效的降低類與類的藕合性,增強(qiáng)代碼的可重用性,工廠模式主要通過(guò)虛函數(shù)的原理進(jìn)行。
當(dāng)基類指針指向一個(gè)子類對(duì)象,通過(guò)這個(gè)指針調(diào)用子類和基類同名成員函數(shù)的時(shí)候,基類聲明為虛函數(shù)「子類不寫(xiě)也可以」就會(huì)調(diào)子類的這個(gè)函數(shù),不聲明就會(huì)調(diào)用基類的。
虛析構(gòu)函數(shù)的作用
我們知道,用C++開(kāi)發(fā)的時(shí)候,用來(lái)做基類的類的析構(gòu)函數(shù)一般都是虛函數(shù)。可是,為什么要這樣做呢?下面用一個(gè)小例子來(lái)說(shuō)明: 有下面的兩個(gè)類:class ClxBase { public:ClxBase() {};virtual ~ClxBase() {};virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; };class ClxDerived : public ClxBase { public:ClxDerived() {};~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; void DoSomething() { cout << "Do something in class ClxDerived!" << endl; }; };代碼ClxBase *pTest = new ClxDerived; pTest->DoSomething(); delete pTest;的輸出結(jié)果是:Do something in class ClxDerived! Output from the destructor of class ClxDerived!這個(gè)很簡(jiǎn)單,非常好理解。但是,如果把類ClxBase析構(gòu)函數(shù)前的virtual去掉,那輸出結(jié)果就是下面的樣子了:Do something in class ClxDerived!也就是說(shuō),類ClxDerived的析構(gòu)函數(shù)根本沒(méi)有被調(diào)用!一般情況下類的析構(gòu)函數(shù)里面都是釋放內(nèi)存資源,而析構(gòu)函數(shù)不被調(diào)用的話就會(huì)造成內(nèi)存泄漏。我想所有的C++程序員都知道這樣的危險(xiǎn)性。當(dāng)然,如果在析構(gòu)函數(shù)中做了其他工作的話,那你的所有努力也都是白費(fèi)力氣。所以,文章開(kāi)頭的那個(gè)問(wèn)題的答案就是--這樣做是為了當(dāng)用一個(gè)基類的指針刪除一個(gè)派生類的對(duì)象時(shí),派生類的析構(gòu)函數(shù)會(huì)被調(diào)用。當(dāng)然,并不是要把所有類的析構(gòu)函數(shù)都寫(xiě)成虛函數(shù)。因?yàn)楫?dāng)類里面有虛函數(shù)的時(shí)候,編譯器會(huì)給類添加一個(gè)虛函數(shù)表,里面來(lái)存放虛函數(shù)指針,這樣就會(huì)增加類的存儲(chǔ)空間。所以,只有當(dāng)一個(gè)類被用來(lái)作為基類的時(shí)候,才把析構(gòu)函數(shù)寫(xiě)成虛函數(shù)工廠模式實(shí)現(xiàn)
工廠類
#ifndef __Item_H__ #define __Item_H__#include "Common.h" class Mario;// 基類,和工廠類 // 分割模塊(讓模塊之間搞內(nèi)聚,低耦合) // 多態(tài)(虛函數(shù)) class Item : public CCSprite { public:enum ItemType{IT_mushroom, IT_tortoise, IT_flower, IT_mushroomReward, IT_mushroomAddLife, IT_flagpoint};// Item* item; delete item;virtual ~Item();// 所有道具都需要調(diào)用的初始化工作bool init(){CCSprite::init();setZOrder(100);// 為道具提供動(dòng)力scheduleUpdate();return true;}Mario* _mario;static CCArray* _itemReward;static Item* _Flag;// 工廠接口static Item* create(CCDictionary* dict);// 對(duì)象的虛接口virtual void move(float dt) {}virtual void collision() {}virtual void wakeup(){}void update(float dt){move(dt);collision();}////////////////////////////// 公共輔助函數(shù)void setPositionByProperty(CCDictionary* dict){const CCString* x = dict->valueForKey("x");const CCString* y = dict->valueForKey("y");setPosition(ccp(x->intValue(), y->intValue() - 16));setAnchorPoint(ccp(0, 0));}CCTMXTiledMap* getMap(){return (CCTMXTiledMap*)getParent();}bool isLeftInWindow(){// CCPoint ptInMap = getPosition();CCRect rcItem = boundingBox();CCPoint ptInMap = ccp(rcItem.getMinX(), rcItem.getMinY());CCTMXTiledMap* map = getMap();CCPoint ptInWorld = map->convertToWorldSpace(ptInMap);if (ptInWorld.x <= winSize.width){return true;}return false;}bool isFarAwayFromMario();ItemType _type; };#if 0 class ItemFactroy { public:Item* createItem(Item::ItemType it){return Item::create(it);} }; #endif#endif工廠接口實(shí)現(xiàn)
#include "Item.h" #include "ItemMushroom.h" #include "Mario.h" #include "ItemTortoise.h" Item::~Item() {} Item* Item::create(CCDictionary* dict) {const CCString *type=dict->valueForKey("type");if (type->m_sString=="mushroom"){return ItemMushroom::create(dict);}else if (type->m_sString == "tortoise")return ItemTortoise::create(dict);return NULL;}bool Item::isOutOfWindow() {CCRect rcItem=this->boundingBox();CCRect rcMario=_mario->boundingBox();if (rcMario.getMinX()-rcItem.getMaxX()>winSize.width){return true;}return false; }使用工廠模式,就不用在游戲中加入各個(gè)怪物的頭文件,只需要包含Item.h就可以了,降低了怪物層與游戲?qū)拥呐汉闲?#xff0c;增強(qiáng)了內(nèi)聚性,同時(shí)也增強(qiáng)了代碼的重用性。
總結(jié)
以上是生活随笔為你收集整理的利用工厂模式实现怪物系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 7.Mysql数据库表引擎与字符集
- 下一篇: 操作系统之进程概念