Cocos2d-x《雷電大戰》(5)-單例模式英雄飛機閃亮登場!,cocos2d飛機大戰

來源:互聯網
上載者:User

Cocos2d-x《雷電大戰》(5)-單例模式英雄飛機閃亮登場!,cocos2d飛機大戰

        林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

本文將實現用單例模式實現一個英雄飛機類的設計,單例模式是遊戲開發中最常用到的一種設計模式,原理也比較簡單,仔細研究下就可以掌握好。

來看看效果:

                                              

                                          英雄飛機一建立就閃爍3秒                                                                   英雄飛機建立後帶有噴火的小尾巴動畫                                              

Cocos2d-x版本:3.4

工程環境:VS30213


一、單例模式解析

單例模式也稱為單件模式、單子模式,可能是使用最廣泛的設計模式。其意圖是保證一個類僅有一個執行個體,並提供一個訪問它的全域訪問點,該執行個體被所有程式模組共用。有很多地方需要這樣的功能模組,如系統的日誌輸出,GUI應用必須是單滑鼠,MODEM的聯結需要一條且只需要一條電話線,作業系統只能有一個視窗管理器,一台PC連一個鍵盤。

單例的一般實現比較簡單,下面是代碼和UML圖。由於建構函式是私人的,因此無法通過建構函式執行個體化,唯一的方法就是通過調用靜態函數GetInstance。

      UML圖:

代碼實現

   1: //Singleton.h
   2: class Singleton  
   3: {
   4: public:
   5:     static Singleton* GetInstance();
   6: private:
   7:     Singleton() {}
   8:     static Singleton *singleton;
   9: };
  10: //Singleton.cpp
  11: Singleton* Singleton::singleton = NULL;
  12: Singleton* Singleton::GetInstance()
  13: {
  14:     if(singleton == NULL)
  15:         singleton = new Singleton();
  16:     return singleton;
  17: }



特點:

1.  類的建構函式外界不可訪問.

2.  提供了建立對象的介面. 

 

二、單例模式優缺點

單例模式非常好實現,直接就可以在靜態區初始化instance,然後通過getInstance返回,這種就被稱為餓漢式單例類。也有些寫法是在getInstance中new instance然後返回,這種就被稱為懶漢式單例類,但這涉及到第一次getInstance的一個判斷問題。

優點

1.減少了時間和空間的開銷(new執行個體的開銷)。

2.提高了封裝性,使得外部不易改動執行個體。

缺點

1.懶漢式是以時間換空間的方式。

2.餓漢式是以空間換時間的方式。

 

三、Cocos2d-x中設計單例模式的英雄飛機

 

這裡我實現了一個單例模式的英雄飛機類,它還帶了觸摸跟隨手指移動的功能,其實就是把Cocos2d-x《雷電大戰》(2)-精靈隨手指移動,你點哪我走哪! 這裡的代碼都整合在一起。這樣就比較合理,這個英雄飛機類還包含有分數值、血量、攻擊值、子彈類型等。這裡只是一個粗略實現,後續的功能有可以還會有改動。而且飛機還帶有噴火的功能,更加的逼真!這樣子代碼結構看起來就比較明了,而不會全放在GameMain.cpp中。然後需要建立時直接在GameMain.cpp來調用就行了。

下面來看看代碼:

標頭檔HeroPlane.h

/***功能 單例英雄飛機類*作者 林炳文(ling20081005@126.com 部落格:http://blog.csdn.net/evankaka)*時間 2015.4.6*/#pragma once#ifndef __HeroPlane_H__#define __HeroPlane_H__#include "cocos2d.h"USING_NS_CC;class HeroPlane :public cocos2d::Layer{private:HeroPlane();public:/***獲得單例英雄飛機的方法*@return 英雄飛機類*/static HeroPlane* getInstance();virtual bool init();/***取得當前英雄飛機中的精靈*@return 飛機中精靈,實際的操作對像*/Sprite* getPlane();        /***底下四個分別為觸摸按下時的事件*/virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even);public:unsigned int planeHp;//英雄飛機生命值unsigned int planeScore;//英雄飛機分數值unsigned int planeBulletNum;//英雄飛機子彈類型        unsigned int planeAttack;//英雄飛機攻擊值        unsigned int planeDefend;//英雄飛機保護值private:static HeroPlane* sharePlane;//英雄飛機靜態變數bool isHeroPlaneControl;//飛機是否被控制著float mDeltaX;//英雄飛機隨手指移動時的X位移量float mDeltaY;//英雄飛機隨手指移動時的Y位移量Sprite* plane;//英雄飛機};#endif 

英雄飛機實作類別HeroPlane.cpp

/***功能 單例英雄飛機類*作者 林炳文(ling20081005@126.com 部落格:http://blog.csdn.net/evankaka)*時間 2015.4.6*/#include"HeroPlane.h"USING_NS_CC;HeroPlane* HeroPlane::sharePlane = NULL;//注意,靜態變數的寫法!HeroPlane::HeroPlane(){plane = NULL;planeHp=10000;//英雄飛機生命值planeScore=0;//英雄飛機分數值planeBulletNum=1;//英雄飛機子彈類型,預設初始化為第一種isHeroPlaneControl = false;        planeAttack=100;//英雄飛機攻擊值        planeDefend=100;//英雄飛機保護值}//取得英雄飛機的方法,只能通過這個方法HeroPlane* HeroPlane::getInstance(){if (NULL == sharePlane){sharePlane = new HeroPlane();sharePlane->init();sharePlane->autorelease();}return sharePlane;}bool HeroPlane::init(){Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();SpriteFrameCache *frameCache = SpriteFrameCache::getInstance();frameCache->addSpriteFramesWithFile("heroplane.plist", "heroplane.png");//載入全域資源plane = Sprite::createWithSpriteFrameName("plane1.png");//產生飛機plane->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 5));this->addChild(plane, 0, 1);Blink *blink = Blink::create(3,8);//閃爍動畫Animation* animation = Animation::create();animation->setDelayPerUnit(0.1f);animation->addSpriteFrame(frameCache->getSpriteFrameByName("plane1.png"));animation->addSpriteFrame(frameCache->getSpriteFrameByName("plane2.png"));Animate* animate = Animate::create(animation);//幀動畫plane->runAction(blink);//執行閃爍動畫plane->runAction(RepeatForever::create(animate));// 執行幀動畫//開啟觸摸事件,讓飛機跟隨手指移動auto listen = EventListenerTouchOneByOne::create();listen->onTouchBegan = CC_CALLBACK_2(HeroPlane::onTouchBegan, this);listen->onTouchMoved = CC_CALLBACK_2(HeroPlane::onTouchMoved, this);listen->onTouchEnded = CC_CALLBACK_2(HeroPlane::onTouchEened, this);listen->onTouchCancelled = CC_CALLBACK_2(HeroPlane::onTouchCancelled, this);listen->setSwallowTouches(false);Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, this);return true;}Sprite* HeroPlane::getPlane(){if (NULL == plane)return NULL;return plane;}bool  HeroPlane::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){Point mHeroPos = plane->getPosition();Point mBeganPos = touch->getLocationInView();mBeganPos = Director::getInstance()->convertToGL(mBeganPos);//判斷當前手指按下地區是否是英雄飛機的地區,並且計算飛機要移動時的位移量if (mBeganPos.x > mHeroPos.x - plane->getContentSize().width / 2 && mBeganPos.x<mHeroPos.x + plane->getContentSize().width / 2 &&mBeganPos.y>mHeroPos.y - plane->getContentSize().height / 2 && mBeganPos.y < mHeroPos.y + plane->getContentSize().height / 2){isHeroPlaneControl = true;//計算位移量mDeltaX = mBeganPos.x - mHeroPos.x;mDeltaY = mBeganPos.y - mHeroPos.y;}return true;}void HeroPlane::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event){if (isHeroPlaneControl){Point mMovedPos = touch->getLocationInView();mMovedPos = Director::getInstance()->convertToGL(mMovedPos);Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();float x = mMovedPos.x - mDeltaX;//記得減去位移量float y = mMovedPos.y - mDeltaY;if (x <= plane->getContentSize().width / 2 + origin.x)//x到達螢幕左邊界x = plane->getContentSize().width / 2 + origin.x;else if (x >= visibleSize.width - plane->getContentSize().width / 2)//x到達螢幕右邊界x = visibleSize.width - plane->getContentSize().width / 2;if (y <= plane->getContentSize().height / 2 + origin.y)//y到達螢幕下邊界y = plane->getContentSize().height / 2 + origin.y;else if (y >= visibleSize.height - plane->getContentSize().height / 2)//x到達螢幕上邊界y = visibleSize.height - plane->getContentSize().height / 2;//飛機跟隨手指移動plane->setPosition(Vec2(x, y));}}void HeroPlane::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){isHeroPlaneControl = false;}void  HeroPlane::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){isHeroPlaneControl = false;}

這裡的英雄飛機第一次擷取時,會閃爍幾下。並且帶有噴火的小尾巴(其實就是不斷的重複切換兩張圖片實現的,看上面的幀動畫)

 使用方法:

   1: HeroPlane *heroPlane = HeroPlane::getInstance();
   2: this->addChild(heroPlane);

每次要取得當前的英雄飛機類,用HeroPlane::getInstance()即可,也就是說每次返回都是同一個執行個體,所以你就可以儲存英雄的分數、血量、攻擊值到一個外部的檔案中,然後遊戲每次啟動時,從這個檔案讀取資料就可以,就可以接著上次的英雄飛機設定的參數了。這些功能我打算留在後頭再來實現。

                                                

                                           英雄飛機一建立就閃爍3秒                                                                         英雄飛機建立後帶有噴火的小尾巴動畫       


        林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.