zoukankan      html  css  js  c++  java
  • Cocos2d-x简单的Demo

    和很多游戏引擎一样Cocos2dx有导演(CCDirector)、场景(CCScene)、层(CCLayer)、菜单(CCMenu)、精灵(CCSprite)这些概念。

    这些东西都继承了节点类(CCNode)。他们都具有(addChild)方法能将某些场景加入另一个场景中。某些精灵加入某个精灵中。这是用树做的。因为整个游戏只有一个导演类。那么也就是说这是树的根。

    然后这些节点能绑定事件。

    CCNode::schedule


    源码中这里用了适配模式。

    void CCNode::schedule(SEL_SCHEDULE selector)
    {
        this->schedule(selector, 0.0f, kCCRepeatForever, 0.0f);
    }
    
    void CCNode::schedule(SEL_SCHEDULE selector, float interval)
    {
        this->schedule(selector, interval, kCCRepeatForever, 0.0f);
    }
    .......


    Cocos2dx有自己的一套垃圾回收装置。算法是当类被引用时+1类没有被引用时-1当为0时自动回收。

    但这只是对crate()出来的类。而是用new开辟出的空间我们可以用宏定义清除。

    #define CC_SAFE_DELETE(p)            do { if(p) { delete (p); (p) = 0; } } while(0)
    #define CC_SAFE_DELETE_ARRAY(p)     do { if(p) { delete[] (p); (p) = 0; } } while(0)
    #define CC_SAFE_FREE(p)                do { if(p) { free(p); (p) = 0; } } while(0)
    #define CC_SAFE_RELEASE(p)            do { if(p) { (p)->release(); } } while(0)
    #define CC_SAFE_RELEASE_NULL(p)        do { if(p) { (p)->release(); (p) = 0; } } while(0)
    #define CC_SAFE_RETAIN(p)            do { if(p) { (p)->retain(); } } while(0)
    #define CC_BREAK_IF(cond)            if(cond) break

    以下是我简单做的代码中的一个核心类

    #include "HelloWorldScene.h"
    #include "SimpleAudioEngine.h"
    #include "GameOverLayer.h"
    
    USING_NS_CC;
    
    CCScene* HelloWorld::scene()
    {
        // 'scene' is an autorelease object
        CCScene *scene = CCScene::create();
        
        // 'layer' is an autorelease object
        HelloWorld *layer = HelloWorld::create();
    	
        // add layer as a child to scene
        scene->addChild(layer);
    
        // return the scene
        return scene;
    }
    
    // on "init" you need to initialize your instance 初始化该类,C++是在构造函数中初始化
    bool HelloWorld::init()
    {
        //////////////////////////////
        // 1. super init first
    	if ( !CCLayerColor::initWithColor(ccc4(0,255,0,255))) //红 绿 蓝 alpha(透明度)
        {
            return false;
        }
    #if 0
        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
    
        /////////////////////////////
        // 2. add a menu item with "X" image, which is clicked to quit the program
        //    you may modify it.
    
        // add a "close" icon to exit the progress. it's an autorelease object
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                            "CloseNormal.png",
                                            "CloseSelected.png",
                                            this,
                                            menu_selector(HelloWorld::menuCloseCallback));
        
    	pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                    origin.y + pCloseItem->getContentSize().height/2));
    
        // create menu, it's an autorelease object
        CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
        pMenu->setPosition(CCPointZero);
        this->addChild(pMenu,1);  //第一个参数表示层,第2个参数是z轴的位置,第二个参数越大那么就越靠前。
    
        /////////////////////////////
        // 3. add your codes below...
    
        // add a label shows "Hello World"
        // create and initialize a label
        
        CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
        
        // position the label on the center of the screen
        pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - pLabel->getContentSize().height));
    
        // add the label as a child to this layer
        this->addChild(pLabel, 1);
    
        // add "HelloWorld" splash screen"
        CCSprite* pSprite = CCSprite::create("HelloWorld.png");
    
        // position the sprite on the center of the screen
        pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    
        // add the sprite as a child to this layer
        this->addChild(pSprite, 0);
    #endif
    	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //获取长宽
    	CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();   //获取原点坐标
    	CCSprite* pSprite = CCSprite::create("Player.png");
    	
    	pSprite->setPosition(ccp(origin.x+20,origin.y+visibleSize.height/2));
    	this->addChild(pSprite,0);                                          //第二个参数是显示优先级
    #if 0
    	CCMenuItemImage *pMenuItem = CCMenuItemImage::create("button2.png",
    		"button2.png",
    		"button2.png",
    		this,
    		menu_selector(HelloWorld::responsFunc)
    		);
    	pMenuItem->setPosition(ccp(30,30));
    	CCMenu* pMenu = CCMenu::create(pMenuItem,NULL);
    	this->addChild(pMenu);
    #endif
    	//Class::crate()不需要手动 new 需要手动释放
    	_projs = new CCArray;                   //设置飞镖
    	_targets = new CCArray;                 //设置目标
    	//添加一个精灵并且一开始就能移动.
    	srand(time(NULL));
    	this->schedule(schedule_selector(HelloWorld::gameLogic),2);
    	this->schedule(schedule_selector(HelloWorld::update));
    	//ps:this->schedule(schedule_selector(HelloWorld::gameLogic,2));会发生鬼畜
    	this->setTouchEnabled(true);
    
    	CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav",true); 
        
    	_successCount = 0;
    	return true;
    }
    
    void HelloWorld::update(float delta)  //delta = 1.0/fps
    {
    	CCArray *projToDelete = new CCArray;
    	CCArray *targetToDelete= new CCArray;
    	CCObject *itarget;
    	CCObject *iproj;
    	CCARRAY_FOREACH(_targets,itarget)
    	{
    		CCSprite *target = (CCSprite*)itarget;       //设置当前目标转化为经理
    		CCRect targetZone = CCRectMake(target->getPositionX(),     //获取目标的边界
    			target->getPositionY(),
    			target->getContentSize().width,
    			target->getContentSize().height);
    		CCARRAY_FOREACH(_projs,iproj)                //循环判定是否有飞镖打中目标
    		{
    			CCSprite *proj = (CCSprite*)iproj;                  
    			CCRect projZone = CCRectMake(proj->getPositionX(),       //获取飞镖边界
    				proj->getPositionY(),
    				proj->getContentSize().width,
    				proj->getContentSize().height);
    			if(projZone.intersectsRect(targetZone))                 //如果有交集
    			{
    				if(++_successCount>=5)
    				{
    					CCScene *overScene = GameOverLayer::scene();
    					CCDirector::sharedDirector()->replaceScene(overScene); //跳转场景
    				}
    				projToDelete->addObject(proj);                          //将需要清除的飞镖和目标加入队列
    				targetToDelete->addObject(target);                       
    			}
    		} //end of iterate proj
    	}   //end of iterate target
    
    	CCARRAY_FOREACH(projToDelete,iproj)                          //循环清除飞镖
    	{
    		_projs->removeObject(iproj); 
    		CCSprite *proj = (CCSprite*)iproj;
    		proj->removeFromParentAndCleanup(true);
    	}
    	CCARRAY_FOREACH(targetToDelete,itarget)                      //循环清除目标
    	{
    		_targets->removeObject(itarget);
    		CCSprite *target = (CCSprite*)itarget;
    		target->removeFromParentAndCleanup(true);
    	}
    	CC_SAFE_RELEASE(targetToDelete);
    	CC_SAFE_RELEASE(projToDelete);
    }
    HelloWorld::~HelloWorld()
    {
    	CC_SAFE_RELEASE(_projs);
    	CC_SAFE_RELEASE(_targets);
    }
    void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
    {
    	CCTouch *touch =(CCTouch*)pTouches->anyObject();  //获取触摸点坐标   
    	CCPoint locInView = touch->getLocationInView();   //获得触摸点UI坐标
    	CCPoint loc = CCDirector::sharedDirector()->convertToGL(locInView); //将UI坐标转换为GL坐标 
    	if(loc.x < 30) return;
    	CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav");
    	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    	
    	CCSprite *proj = CCSprite::create("Projectile.png");
    	proj->setPosition(ccp(30,visibleSize.height/2));
    	
    	double ax = 30;
    	double ay = visibleSize.height/2;
    	double D = sqrt(visibleSize.width*visibleSize.width+visibleSize.height*visibleSize.height);
    	double d = sqrt((loc.x-ax)*(loc.x-ax)+(loc.y-ay)*(loc.y-ay));
    	double cx = (loc.x-ax)*D/d+ax;
    	double cy = (loc.y-ay)*D/d+ay;
    
    	CCMoveTo *move = CCMoveTo::create(D/320,ccp(cx,cy));
    	CCCallFuncN *dis = CCCallFuncN::create(this,callfuncN_selector(HelloWorld::disappear));
    	CCSequence *actions = CCSequence::create(move,dis,NULL);  //如果CCSequence最后没加NULL编译能通过运行会弹对话框;
    	proj->runAction(actions);
    	this->addChild(proj);     //将精灵加入层中
    	_projs->addObject(proj);  //将精灵加入数组中
    	proj->setTag(2);  //设置飞镖标记为2;
    }
    void HelloWorld::gameLogic(float t)  // t就是上面的第2个参数  schedule(...,2) 是2 这么一个参数
    {
    	this->crateTarget();
    }
    //
    void HelloWorld::crateTarget()
    {
    	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    	CCSprite *mytarget = CCSprite::create("Target.png");
    	int y = rand()%(int)(visibleSize.height);
    	mytarget->setPosition(ccp(visibleSize.width-30,y));
    	this->addChild(mytarget);
    	_targets->addObject(mytarget); //将怪兽加入数组
    	mytarget->setTag(1);           //设置怪物标记为1
    	CCMoveTo *move = CCMoveTo::create(2,ccp(30,y));  //第一个参数是运动时间,第二个参数是运动方向点
    	CCCallFuncN *selfDefineAction = CCCallFuncN::create(this,callfuncN_selector(HelloWorld::disappear));
    	CCSequence *actions = CCSequence::create(move,selfDefineAction,NULL);
    	mytarget->runAction(actions);
    }
    void HelloWorld::responsFunc(CCObject *obj)
    {
    	//CCLog("click");
    	CCMoveTo *move = CCMoveTo::create(2,ccp(30,40));  //第一个参数是运动时间,第二个参数是运动方向点
    	CCCallFuncN *selfDefineAction = CCCallFuncN::create(this,callfuncN_selector(HelloWorld::disappear));
    	CCSequence *action = CCSequence::create(move,selfDefineAction,NULL);
    	target->runAction(action);
    }
    void HelloWorld::disappear(CCNode *who)       
    {
    	//who->setPosition(ccp(20,20));
    	//who->setScale(2);                //放大两倍
    	int tag = who->getTag();
    	if(1 == tag)
    	{
    		CCLog("mylog-----------------target disappear
    ");
    		_targets->removeObject(who);
    		CCScene *overScene = GameOverLayer::scene();
    		CCLog("mylog-----------------get GameOverLayer::scene
    ");
    		GameOverLayer *layer =(GameOverLayer*)overScene->getChildByTag(100);
    		CCLog("mylog-----------------get layer by Tag
    ");
    		/*CCLabelTTF *tmp = layer->_label;
    		if(tmp==NULL) CCLog("mylog-----------------tmp==null
    ");
    		CCLog("mylog-----------------get _label
    ");
    		tmp->getString();
    		CCLog("mylog-----------------getString()
    ");
    		tmp->setString("You lose");
    		CCLog("mylog-----------------set _label=You lose
    ");*/
    		CCDirector::sharedDirector()->replaceScene(overScene);
    		CCLog("mylog-----------------success Change Scene
    ");
    	}
    	else if(2 == tag)
    	{
    		_projs->removeObject(who);
    	}
    	who->removeFromParentAndCleanup(true);
    }
    void HelloWorld::menuCloseCallback(CCObject* pSender)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    	CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    #else
        CCDirector::sharedDirector()->end();
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        exit(0);
    #endif
    #endif
    }
    




  • 相关阅读:
    程序的局部性原理2
    程序的局部性原理
    ROM
    学习Spring Security OAuth认证(一)-授权码模式
    mybatis*中DefaultVFS的logger乱码问题
    maven生命周期绑定要点
    spring security antMatchers相关内容
    JSTL
    什么是CSS hack?
    Java中获得当前静态类的类名
  • 原文地址:https://www.cnblogs.com/leejuen/p/5547458.html
Copyright © 2011-2022 走看看