• 「cocos2dx」虚拟摇杆实现(1)


    cocos2d的虚拟摇杆有现在的类库可供调用,国内的同伴也将其移植为了cocos2d-x的,也有自己实现的。
    在网上找了一篇实现 cocos2d-x摇杆JoyStick,地址为:http://blog.csdn.net/jukai7/article/details/8623033

    作者讲得很清楚了,本着不重复发明轮子的原则,我把代码抄了一份,以后项目中应该能用得到。
    代码下载地址:http://vdisk.weibo.com/s/BqB5v/1368522809

     HelloWorldScene.h代码:

    #ifndef __HELLOWORLD_SCENE_H__
    #define __HELLOWORLD_SCENE_H__
    
    #include "cocos2d.h"
    USING_NS_CC;
    
    enum
    {
        TileMapNode = 0,
    };
    
    
    class HelloWorld : public cocos2d::CCLayer
    {
    public:
        // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
        virtual bool init();  
    
        // there's no 'id' in cpp, so we recommand to return the exactly class pointer
        static cocos2d::CCScene* scene();
        
        // a selector callback
        void menuCloseCallback(CCObject* pSender);
    
        virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
        virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
        virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
    
        float heronsformula(float x1,float y1,float x2,float y2,float x3,float y3);  
        bool triangleContainPoint(float x1,float y1,float x2,float y2,float x3,float y3,float px,float py);  
      
        CC_SYNTHESIZE(cocos2d::CCTMXTiledMap*, _tileMap, TileMap);
        CC_SYNTHESIZE(cocos2d::CCTMXLayer*, _background, Background);
    
        // implement the "static node()" method manually
        CREATE_FUNC(HelloWorld);
    
    
    private:
        void flying(float dt);  
      
        cocos2d::CCSprite *joystick;  
        //中心点O  
        cocos2d::CCPoint O;  
        //大圆半径  
        float R;  
      
        cocos2d::CCSprite *plane;  
        //飞机飞行的速度分量值  
        float speedX;  
        float speedY;  
        //是否飞行的标志  
        bool isFlying;  
    };
    
    #endif  // __HELLOWORLD_SCENE_H__

     HelloWorldScene.cpp代码:

    #include "HelloWorldScene.h"
    using namespace cocos2d;
    
    CCScene* HelloWorld::scene()
    {
        CCScene * scene = NULL;
        do 
        {
            // 'scene' is an autorelease object
            scene = CCScene::create();
            CC_BREAK_IF(! scene);
    
            // 'layer' is an autorelease object
            HelloWorld *layer = HelloWorld::create();
            CC_BREAK_IF(! layer);
    
            // add layer as a child to scene
            scene->addChild(layer);
        } while (0);
    
        // return the scene
        return scene;
    }
    
    // on "init" you need to initialize your instance
    bool HelloWorld::init()
    {
        bool bRet = false;
        do 
        {
            //////////////////////////////////////////////////////////////////////////
            // super init first
            //////////////////////////////////////////////////////////////////////////
    
            CC_BREAK_IF(! CCLayer::init());
    
            //////////////////////////////////////////////////////////////////////////
            // add your codes below...
            //////////////////////////////////////////////////////////////////////////
    
            // 1. Add a menu item with "X" image, which is clicked to quit the program.
    
            // Create a "close" menu item with close icon, it's an auto release object.
            CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                "CloseNormal.png",
                "CloseSelected.png",
                this,
                menu_selector(HelloWorld::menuCloseCallback));
            CC_BREAK_IF(! pCloseItem);
    
            // Place the menu item bottom-right conner.
            pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
    
            // Create a menu with the "close" menu item, it's an auto release object.
            CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
            pMenu->setPosition(CCPointZero);
            CC_BREAK_IF(! pMenu);
    
            // Add the menu to HelloWorld layer as a child layer.
            this->addChild(pMenu, 5);
    
            CCSize size = CCDirector::sharedDirector()->getWinSize();
    
            //创建瓦片地图
            this->setTileMap(CCTMXTiledMap::create("pd_tilemap1.tmx"));
            _tileMap->setAnchorPoint(ccp(0.0f, 0.0f));        //设置瓦片地图的锚点为屏幕正中间
            _tileMap->setPosition(ccp(0, 0));                //设置瓦片地图的位置为屏幕左下角
            this->setBackground(_tileMap->layerNamed("Layer1"));
            this->addChild(_tileMap, 2, TileMapNode);        //加入场景层
    
            //获取Objects对象层
            CCLOG("_tileMap %d", _tileMap->retainCount());
            CCTMXObjectGroup *objects = _tileMap->objectGroupNamed("Objects");
            CCLOG("_tileMap %d", _tileMap->retainCount());
            CC_BREAK_IF(!objects);    //如果失败,退出
    
            //获取SpawnPoint的字典(包含坐标,高和宽等信息)
            CCDictionary *spawnPoint = objects->objectNamed("SpawnPoint");
            CC_BREAK_IF(!spawnPoint);    //如果失败,退出
    
            //分别取x和y坐标的值
            int x = spawnPoint->valueForKey("x")->intValue();
            int y = spawnPoint->valueForKey("y")->intValue();
    
            plane = CCSprite::create("hartnett.jpg");    
            plane->setPosition(ccp(size.width/2, size.height/2));
            plane->setScale(0.3f);
            this->addChild(plane, 2);
    
            //创建摇杆下面部分  
            CCSprite *joystick1 = CCSprite::create("joystick1.png");  
            //设置透明度,锚点,位置  
            joystick1->setOpacity(191);  
            joystick1->setAnchorPoint(ccp(0, 0));  
            joystick1->setPosition(ccp(0, 0));
            joystick1->setColor(ccWHITE);
            //大圆半径  
            R=joystick1->getContentSize().width/2;  
            //中心点  
            O = ccp(R, R);  
            //添加进布景  
            this->addChild(joystick1, 3);  
      
            //创建摇杆上面圆圈部分  
            joystick = CCSprite::create("joystick2.png");  
            //设置位置为摇杆中心点并添加进布景  
            joystick->setPosition(ccp(O.x, O.y));
            joystick->setColor(ccRED);
            joystick->setScale(0.8f);
            this->addChild(joystick, 4);
    
            //初始化需要的变量  
            isFlying = false;  
            speedX = speedY = 0;
    
            //设置可触摸  
            this->setTouchEnabled(true);
    
            //每帧要执行的函数  
            this->schedule(schedule_selector(HelloWorld::flying)); 
    
            bRet = true;
        } while (0);
    
        return bRet;
    }
    
    void HelloWorld::menuCloseCallback(CCObject* pSender)
    {
        // "close" menu item clicked
        CCDirector::sharedDirector()->end();
    }
    
    void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
    {
        CCTouch *touch = (CCTouch*)pTouches->anyObject();  
        CCPoint location = touch->getLocation();  
      
        CCRect rect=joystick->boundingBox();  
        if (rect.containsPoint(location))  
        {  
            isFlying=true;  
        }  
    }
    
    void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
    {
        CCTouch *touch = (CCTouch*)pTouches->anyObject();  
        CCPoint location = touch->getLocation();  
      
        //判断触摸滑动点是否在摇杆范围内  
        bool inRange = pow(O.x - location.x, 2) + pow(O.y - location.y, 2) < pow(R, 2);  
        if (isFlying && inRange)
        {  
            CCPoint position=plane->getPosition();  
            joystick->setPosition(location);  
      
            float r = R * 2 / 6;  
            float d = R * 2 / 3;  
    
            //上,区域2或5  
            if(triangleContainPoint(O.x, O.y, O.x - r, O.y + r, O.x  +r, O.y + r, location.x, location.y)  
                || CCRectMake(O.x - r, O.y + r, d, d).containsPoint(location))
            {  
                speedX=0;  
                speedY=1;  
            }  
    
            //下,区域6或11  
            else if (triangleContainPoint(O.x, O.y, O.x - r, O.y - r, O.x + r, O.y - r, location.x, location.y)  
                || CCRectMake(O.x - r, O.y - r - d, d, d).containsPoint(location))
            {  
                speedX=0;  
                speedY=-1;  
            }  
    
            //左,区域4或7  
            else if (triangleContainPoint(O.x, O.y, O.x - r, O.y + r, O.x - r, O.y - r, location.x, location.y)  
            || CCRectMake(O.x - r - d, O.y - r, d, d).containsPoint(location))
            {  
                speedX=-1;  
                speedY=0;  
            }  
    
            //右,区域9或8  
            else if (triangleContainPoint(O.x, O.y, O.x + r, O.y + r, O.x + r, O.y - r, location.x, location.y)  
            || CCRectMake(O.x + r, O.y - r, d, d).containsPoint(location))
            {  
                speedX=1;  
                speedY=0;  
            }  
    
            //右上,区域3  
            else if (location.x - (O.x + r) > 0 && location.y - (O.y + r) > 0)
            {  
                speedX = 0.7f;  
                speedY = 0.7f;  
            }  
    
            //左上,区域1  
            else if (location.x - (O.x - r) < 0 && location.y - (O.y + r) > 0)
            {  
                speedX=-0.7f;  
                speedY=0.7f;  
            }  
    
            //左下,区域10  
            else if (location.x - (O.x - r) < 0 && location.y - (O.y - r) < 0)
            {  
                speedX = -0.7f;  
                speedY = -0.7f;  
            }  
    
            //右下,区域12  
            else if (location.x - (O.x + r) > 0 && location.y - (O.y - r) < 0)
            {  
                speedX = 0.7f;  
                speedY = -0.7f;  
            }
        }
    }
    
    void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
    {
        isFlying = false;  
        joystick->setPosition(O);  
        speedX = speedY = 0;  
    }
    
    
    void HelloWorld::flying(float dt)  
    {  
        if (isFlying && (speedX != 0 || speedY != 0))
        {  
            //飞机飞行  
            CCPoint position=ccp(plane->getPosition().x+speedX, plane->getPosition().y + speedY);  
      
            CCSize size=CCDirector::sharedDirector()->getWinSize();  
            CCRect rect=CCRectMake(0, 0, size.width, size.height);  
      
            //判断触摸点是否在屏幕内  
            if(rect.containsPoint(position))
            {  
                plane->setPosition(position);  
            }  
      
        }  
    }  
    
    float HelloWorld::heronsformula(float x1,float y1,float x2,float y2,float x3,float y3)  
    {  
        //求边长a  
        float a = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));  
        //求边长b  
        float b = sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2));  
        //求边长c  
        float c = sqrt(pow(x3 - x1, 2) + pow(y3 - y1, 2));  
        //求半周长s  
        float s = (a + b + c) / 2;  
      
        //根据海伦公式返回三角形面积  
        return sqrt(s * (s - a) * (s - b) * (s - c));  
    }  
      
    //判断三个新三角形面积和是否等于原先三角形面积的函数的实现  
    bool HelloWorld::triangleContainPoint(float x1,float y1,float x2,float y2,float x3,float y3,float px,float py)  
    {  
        //求S1的面积  
        float s1=heronsformula(x1,y1,x2,y2,px,py);  
        //求S2的面积  
        float s2=heronsformula(x2,y2,x3,y3,px,py);  
        //求S3的面积  
        float s3=heronsformula(x3,y3,x1,y1,px,py);  
        //求S的面积  
        float s=heronsformula(x1,y1,x2,y2,x3,y3);  
      
        //返回S是否等于S1,S2,S3的和  
        return abs(s-(s1+s2+s3))<0.001f;  
    }  
  • 相关阅读:
    TCC
    使用RocketMQ实现分布式事务
    CentOS关机
    使用grub手动引导linux和windows
    CentOS下X Window与命令行界面的切换
    Centos下 为firefox安装flash插件
    tar.xz文件如何解压
    用Linux命令wget进行整站下载
    CentOS关闭火狐浏览器Flash过期提示
    CentOS普通用户添加sudo权限
  • 原文地址:https://www.cnblogs.com/awakenjoys/p/cocos2d.html
Copyright © 2020-2023  润新知