Cocos2d-x《雷电大战》(5)-单例模式英雄飞机闪亮登场!

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

本文将实现用单例模式实现一个英雄飞机类的设计,单例模式是游戏开发中最常用到的一种设计模式,原理也比较简单,仔细研究下就可以掌握好。

来看看效果:

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

   1: #pragma once
   2: #ifndef __HeroPlane_H__

   3: #define __HeroPlane_H__

   4: #include "cocos2d.h"

   5: USING_NS_CC;

   6: class HeroPlane :public cocos2d::Layer{

   7: private:

   8:     HeroPlane();

   9: public:

  10:     /**

  11:     *获得单例英雄飞机的方法

  12:     *@return 英雄飞机类

  13:     */

  14:     static HeroPlane* getInstance();

  15:     virtual bool init();

  16:     /**

  17:     *取得当前英雄飞机中的精灵

  18:     *@return 飞机中精灵,实际的操作对像

  19:     */

  20:     Sprite* getPlane();

  21:         /**

  22:     *底下四个分别为触摸按下时的事件

  23:     */

  24:     virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);

  25:     virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);

  26:     virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);

  27:     virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even);

  28:  

  29: public:

  30:     unsigned int planeHp;//英雄飞机生命值

  31:     unsigned int planeScore;//英雄飞机分数值

  32:     unsigned int planeBulletNum;//英雄飞机子弹类型

  33:         unsigned int planeAttack;//英雄飞机攻击值

  34:         unsigned int planeDefend;//英雄飞机保护值

  35: private:

  36:     static HeroPlane* sharePlane;//英雄飞机静态变量

  37:     bool isHeroPlaneControl;//飞机是否被控制着

  38:     float mDeltaX;//英雄飞机随手指移动时的X偏移量

  39:     float mDeltaY;//英雄飞机随手指移动时的Y偏移量

  40:     Sprite* plane;//英雄飞机

  41:  

  42: };

  43: #endif 

英雄飞机实现类HeroPlane.cpp

   1: #include"HeroPlane.h"
   2: USING_NS_CC;

   3: HeroPlane* HeroPlane::sharePlane = NULL;//注意,静态变量的写法!

   4: HeroPlane::HeroPlane(){

   5:     plane = NULL;

   6:     planeHp=10000;//英雄飞机生命值

   7:     planeScore=0;//英雄飞机分数值

   8:     planeBulletNum=1;//英雄飞机子弹类型,默认初始化为第一种

   9:     isHeroPlaneControl = false;

  10:         planeAttack=100;//英雄飞机攻击值

  11:         planeDefend=100;//英雄飞机保护值

  12:  

  13: }

  14: //取得英雄飞机的方法,只能通过这个方法

  15: HeroPlane* HeroPlane::getInstance()

  16: {

  17:     if (NULL == sharePlane){

  18:         sharePlane = new HeroPlane();

  19:         sharePlane->init();

  20:         sharePlane->autorelease();

  21:     }

  22:     return sharePlane;

  23: }

  24: bool HeroPlane::init(){

  25:  

  26:     Size visibleSize = Director::getInstance()->getVisibleSize();

  27:     Point origin = Director::getInstance()->getVisibleOrigin();

  28:  

  29:     SpriteFrameCache *frameCache = SpriteFrameCache::getInstance();

  30:     frameCache->addSpriteFramesWithFile("heroplane.plist", "heroplane.png");//加载全局资源

  31:  

  32:     plane = Sprite::createWithSpriteFrameName("plane1.png");//生成飞机

  33:     

  34:     plane->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 5));

  35:     this->addChild(plane, 0, 1);

  36:  

  37:     Blink *blink = Blink::create(3,8);//闪烁动画

  38:     Animation* animation = Animation::create();

  39:     animation->setDelayPerUnit(0.1f);

  40:     animation->addSpriteFrame(frameCache->getSpriteFrameByName("plane1.png"));

  41:     animation->addSpriteFrame(frameCache->getSpriteFrameByName("plane2.png"));

  42:     Animate* animate = Animate::create(animation);//帧动画

  43:  

  44:     plane->runAction(blink);//执行闪烁动画

  45:     plane->runAction(RepeatForever::create(animate));// 执行帧动画

  46:  

  47:     //开启触摸事件,让飞机跟随手指移动

  48:     auto listen = EventListenerTouchOneByOne::create();

  49:     listen->onTouchBegan = CC_CALLBACK_2(HeroPlane::onTouchBegan, this);

  50:     listen->onTouchMoved = CC_CALLBACK_2(HeroPlane::onTouchMoved, this);

  51:     listen->onTouchEnded = CC_CALLBACK_2(HeroPlane::onTouchEened, this);

  52:     listen->onTouchCancelled = CC_CALLBACK_2(HeroPlane::onTouchCancelled, this);

  53:     listen->setSwallowTouches(false);

  54:     Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, this);

  55:  

  56:     return true;

  57: }

  58: Sprite* HeroPlane::getPlane(){

  59:     if (NULL == plane)

  60:         return NULL;

  61:     return plane;

  62: }

  63: bool  HeroPlane::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){

  64:  

  65:     Point mHeroPos = plane->getPosition();

  66:     Point mBeganPos = touch->getLocationInView();

  67:     mBeganPos = Director::getInstance()->convertToGL(mBeganPos);

  68:  

  69:     //判断当前手指按下区域是否是英雄飞机的区域,并且计算飞机要移动时的偏移量

  70:     if (mBeganPos.x > mHeroPos.x - plane->getContentSize().width / 2 && mBeganPos.x<mHeroPos.x + plane->getContentSize().width / 2 &&

  71:         mBeganPos.y>mHeroPos.y - plane->getContentSize().height / 2 && mBeganPos.y < mHeroPos.y + plane->getContentSize().height / 2){

  72:         isHeroPlaneControl = true;

  73:         //計算偏移量

  74:         mDeltaX = mBeganPos.x - mHeroPos.x;

  75:         mDeltaY = mBeganPos.y - mHeroPos.y;

  76:  

  77:     }

  78:  

  79:     return true;

  80: }

  81: void HeroPlane::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event){

  82:     if (isHeroPlaneControl){

  83:         Point mMovedPos = touch->getLocationInView();

  84:         mMovedPos = Director::getInstance()->convertToGL(mMovedPos);

  85:  

  86:         Size visibleSize = Director::getInstance()->getVisibleSize();

  87:         Point origin = Director::getInstance()->getVisibleOrigin();

  88:         float x = mMovedPos.x - mDeltaX;//記得減去偏移量

  89:         float y = mMovedPos.y - mDeltaY;

  90:  

  91:         if (x <= plane->getContentSize().width / 2 + origin.x)//x到达屏幕左边界

  92:             x = plane->getContentSize().width / 2 + origin.x;

  93:         else if (x >= visibleSize.width - plane->getContentSize().width / 2)//x到达屏幕右边界

  94:             x = visibleSize.width - plane->getContentSize().width / 2;

  95:  

  96:         if (y <= plane->getContentSize().height / 2 + origin.y)//y到达屏幕下边界

  97:             y = plane->getContentSize().height / 2 + origin.y;

  98:         else if (y >= visibleSize.height - plane->getContentSize().height / 2)//x到达屏幕上边界

  99:             y = visibleSize.height - plane->getContentSize().height / 2;

 100:  

 101:         //飞机跟随手指移动

 102:         plane->setPosition(Vec2(x, y));

 103:     }

 104: }

 105: void HeroPlane::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){

 106:     isHeroPlaneControl = false;

 107: }

 108: void  HeroPlane::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){

 109:     isHeroPlaneControl = false;

 110: }

这里的英雄飞机第一次获取时,会闪烁几下。

使用方法:

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

每次要取得当前的英雄飞机类,用HeroPlane::getInstance()即可,也就是说每次返回都是同一个实例,所以你就可以保存英雄的分数、血量、攻击值到一个外部的文件中,然后游戏每次启动时,从这个文件读取数据就可以,就可以接着上次的英雄飞机设定的参数了。这些功能我打算留在后头再来实现。

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

时间: 2024-10-11 05:17:57

Cocos2d-x《雷电大战》(5)-单例模式英雄飞机闪亮登场!的相关文章

Cocos2d-x游戏《雷电大战》开源啦!要源码要资源快快来~~

写在前面的话:这是笔者开发的第二个小游戏<雷电大战>,之前就过这个游戏和<赵云要格斗>一样,最终将会开源.由于自己的一些个人原因.这个游戏还没有完成,但是许多网友都过来寻求代码或资源,本着开源的精神,笔者今天将它们共享给出大家. 注:目前游戏还没有完成,代码全是笔者原创,资源有一部分原创,有一部分网上搜集. 若是觉得本项目对你有用,那么请给辛苦的笔者的GitHub右上角Star一颗星星!不胜感激---- 下载地址 https://github.com/appleappleapple

Cocos2d-x《雷电大战》(4)-策略模式实现不同子弹切换!!

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文从设计模式中的策略模式入手,主讲了飞机大战中英雄飞机切换不同的子弹.这里分为三种子弹.第一种:每次发一个子弹,垂直发射;第二种:每次发两个子弹,两个都是垂直发射:第三种;每次发三个子弹,两边的子弹有一定的角度,而中间的子弹垂直发射;设计模式是游戏开发经常用到的思想,建议有兴趣的同学可以好好研究下!好了,下面开始吧. 效果如下: Cocos2d-x版本:3.4 工程环境:VS30213 一

Cocos2d-x《雷电大战》(3)-子弹无限发射

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现雷电游戏中,游戏一開始,英雄飞机就无限发射子弹的功能. 这里的思想是单独给子弹弄一个层.在这个层不设置一个定时器,每隔一个时间,依据当前英雄飞机传入的位置,生成子弹,并设置子弹的移动事件,和移动后的事件(就是把子弹删除掉,节省内存). 终于效果: Cocos2d-x版本号:3.4 project环境:VS30213 一.英雄子弹层 1.HeroBulletLayer.h /** *

Cocos2d-x 《雷电大战》-精灵随手指移动,你点哪我走哪!

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现飞机游戏中,人的手指按着飞机,就能拖着飞机走动,这里实现了当你手指按在手机的图片上,手指一直按着屏幕,飞机就会跟着你走.同时,还加入了边界判断条件,让飞机在你的视野内移动,实现的效果完全和我们手机上的飞机游戏一样. 效果: Cocos2d-x版本:3.4 工程环境:VS30213 一.代码编写 1.头文件GameMain.h /** *@作者 林炳文(邮箱:[email prote

javascript飞机大战-----003创建英雄机

/* 英雄机:因为英雄机只有一辆所以不需要用构造函数 */ var Hero = { //初始图片 self:null, //初始left left:0, //初始top top:0, //生命值 life:3, //加载进来的图和爆照的图 imgs:['image/hero.gif','image/hero-bang.gif'], //初始化 init:function(){ //创建一个元素 var img = document.createElement('img'); //将图片路径赋值

Cocos2d-x 《雷电大战》-双层地图无限滚动

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现飞机射击游戏中的地图无限滚动的功能,这里分为两个层,一个层无限向下滚动,一个层无限向上滚动,这样子结合起来效果就非常有层次感,也非常逼真,这里我把地图层都写成一个类,自己把地图改下,就可以成为你自己的了!下面,我们开始吧 先来看看效果: Cocos2d-x版本:3.4 工程环境:VS30213 一.实现思路 其实就是两张图片,然后同时一起向下(向上)滚动,当一张图片完全出视野后,就

Cocos2d-x《雷电大战》-双层地图无限滚动

本文要实现飞机射击游戏中的地图无限滚动的功能,这里分为两个层,一个层无限向下滚动,一个层无限向上滚动,这样子结合起来效果就非常有层次感,也非常逼真,这里我把地图层都写成一个类,自己把地图改下,就可以成为你自己的了!下面,我们开始吧 先来看看效果: Cocos2d-x版本:3.4 工程环境:VS30213 一.实现思路 其实就是两张图片,然后同时一起向下(向上)滚动,当一张图片完全出视野后,就把它调到最上面.形成两个图片交替出现,不过,一般为游戏中我们都感觉像是一张图片,那是因为两张图片的头尾连接

安卓飞机大战(五) 飞机瞬移的解决方法

在游戏开发时,角色可以随手指移动,但是当手指移动到屏幕另一个位置时,角色可以瞬移 解决方法如下: 在手指触摸屏幕时进行判定,如果手指点到了角色并且在屏幕上进行滑动,角色才移动 具体代码如下: 定义一个值a 当手指点到了角色并且在屏幕上进行滑动,a的值变为1,当手指离开屏幕,a的值变为0,当a=1时角色才进行移动. if(event.getAction()==MotionEvent.ACTION_DOWN&&event.getX()>=myplane.x&&event.

Cocos2d-x《雷电大战》(6) 智能敌机AI来袭--飞行路径算法设计与实现(上)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现飞机类游戏中的一连串飞机的跟随出和和并行出出.而网上找了一些Cocos2dx开发的飞行类游戏,都只找到一些简单的智能敌机.基本上没什么AI,这样游戏玩起来就太没意思了.然后又去找敌机飞行路径的相关资料,发现相关的也很少.想想还是自己来设计吧! 飞机类游戏设计中,智机的飞行路径设计和智能子弹的设计绝对一个飞行类游戏好坏是的核心.敌机智能也是分级别的.BOSS机就不说了,而飞行游戏由于