要实现一个两个图层叠加在一起,然后点击其中的一个图层,实现另外一个图层的旋转缩放的效果。
预期效果:
1.实现两个layer添加在一个场景中。
2.实现点击一个场景能实现另一个场景的旋转缩放的功能。
3.实现layer中精灵的随机生成和自由走动。
4.实现场景中具有触摸事件的精灵。
效果图:
实现步骤:
1.首先分析一下这个效果是由两个图层组成的,先来实现一下上面的一个黄色图层
GameLayer.h:
#ifndef _______GameLayer__
#define _______GameLayer__
#include <iostream>
#include "cocos2d.h"
using namespace cocos2d;
class GameLayer:public CCLayer
{
public:
CCPoint gameLayerPosition;
CCPoint lastTouchLocation;
bool init();
CREATE_FUNC(GameLayer);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void registerWithTouchDispatcher(void);
void addRandomThings();
void runRandomMoveSequence(CCNode* node);
};
#endif /* defined(_______GameLayer__) */
GameLayer.cpp:
#include "GameLayer.h"
#include "HelloWorldScene.h"
#include "Spider.h"
bool GameLayer::init()
{
if (!CCLayer::init()) {
return false;
}
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCSprite * background = CCSprite::create("grass.png");
background->setPosition(CCPointMake(size.width/2, size.height/2));
this->addChild(background);
CCLabelTTF *label = CCLabelTTF::create("GameLayer", "Marker Felt", 44);
label->setColor(ccBLACK);
label->setPosition(CCPointMake(size.width/2, size.height/2));
label->setAnchorPoint(CCPointMake(0.5f, 1));
this->addChild(label);
this->GameLayer::addRandomThings();
this->setTouchEnabled(true);
return true;
}
void GameLayer::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
bool GameLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
//记录点击下的坐标点
lastTouchLocation = HelloWorld::locationFromTouch(pTouch);
return true;
}
void GameLayer::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
CCPoint currentTouchLocation = HelloWorld::locationFromTouch(pTouch);
//获得两点之间的差值
CCPoint moveTo = ccpSub(lastTouchLocation, currentTouchLocation);
moveTo = ccpMult(moveTo, -1);
lastTouchLocation = currentTouchLocation;
//将当前图层移动到鼠标移动的地方
this->setPosition(ccpAdd(this->getPosition(), moveTo));
CCLog("gameLayertouchMoved");
}
void GameLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
//恢复一开始的position(gameLayerPosition(0,0))
CCMoveTo* move = CCMoveTo::create(1, gameLayerPosition);
CCEaseIn* ease = CCEaseIn::create(move, 0.5f);
ease->setTag(103);
this->runAction(ease);
CCLog("gameLayertouchEnded");
}
void GameLayer::addRandomThings()
{
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
//向图层加太阳
for (int i=0; i<4; i++) {
CCSprite* firething = CCSprite::create("firething.png");
firething->setPosition(CCPointMake(CCRANDOM_0_1() * screenSize.width, CCRANDOM_0_1() * screenSize.height));
this->addChild(firething);
this->runRandomMoveSequence(firething);
}
//向图层加蜘蛛
for (int j=0; j<10; j++) {
//添加用CCNode封装了的Spider精灵,Spider具有触摸事件
Spider::spiderWithParentNode(this);
}
}
void GameLayer::runRandomMoveSequence(CCNode* node)
{
float duration = CCRANDOM_0_1() * 5 + 1;
CCMoveBy* move1 = CCMoveBy::create(duration, CCPointMake(-180, 0));
CCMoveBy* move2 = CCMoveBy::create(duration, CCPointMake(0, -180));
CCMoveBy* move3 = CCMoveBy::create(duration, CCPointMake(180, 0));
CCMoveBy* move4 = CCMoveBy::create(duration, CCPointMake(0, 180));
CCSequence* sequence = (CCSequence*)CCSequence::create(move1,move2,move3,move4,NULL);
CCRepeatForever* repeat = CCRepeatForever::create(sequence);
node->runAction(repeat);
}
2.其次实现下面的那个绿色草坪的图层
UserInterfaceLayer.h:
#ifndef _______UserInterfaceLayer__
#define _______UserInterfaceLayer__
#include <iostream>
#include "cocos2d.h"
using namespace cocos2d;
class UserInterfaceLayer:public CCLayer
{
public:
bool init();
CREATE_FUNC(UserInterfaceLayer);
bool isTouchForMe(CCPoint touchLocation);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void registerWithTouchDispatcher(void);
};
#endif /* defined(_______UserInterfaceLayer__) */
UserInterfaceLayer.cpp:
#include "UserInterfaceLayer.h"
#include "HelloWorldScene.h"
#include "GameLayer.h"
bool UserInterfaceLayer::init()
{
if (!CCLayer::init()) {
return false;
}
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCSprite * background = CCSprite::create("ui-frame.png");
background->setPosition(CCPointMake(size.width/2, size.height));
background->setAnchorPoint(CCPointMake(0.5, 1));
this->addChild(background,0,101);
CCLabelTTF* label = CCLabelTTF::create("Here be your Game Scores etc", "Courier", 22);
label->setColor(ccBLACK);
label->setPosition(CCPointMake(size.width/2, size.height));
label->setAnchorPoint(CCPointMake(0.5f, 1));
this->addChild(label);
this->setTouchEnabled(true);
return true;
}
void UserInterfaceLayer::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
}
//判断是否点击了我所在的范围
bool UserInterfaceLayer::isTouchForMe(CCPoint touchLocation)
{
CCNode * node = this->getChildByTag(101);
//boundBox方法是返回当前node所占的rect
return node->boundingBox().containsPoint(touchLocation);
}
bool UserInterfaceLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
CCPoint location = pTouch->getLocation();
bool isTouchHandled = this->isTouchForMe(location);
if (isTouchHandled) {
CCNode * node = this->getChildByTag(101);
((CCSprite*)node)->setColor(ccRED);
}
GameLayer *gameLayer = HelloWorld::sharedhelloworld()->gameLayer();
CCRotateBy * rotate = CCRotateBy::create(16, 360);
//gameLayer->runAction(rotate);
CCScaleTo * scale1 = CCScaleTo::create(8, 0);
CCScaleTo *scale2 = CCScaleTo::create(8, 1);
CCSequence* sequence = CCSequence::create(scale1,scale2,NULL);
sequence->setTag(111);
gameLayer->stopActionByTag(111);
gameLayer->setRotation(0);
gameLayer->setScale(1);
gameLayer->runAction(rotate);
gameLayer->runAction(sequence);
return true;
}
void UserInterfaceLayer::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
CCNode* node = this->getChildByTag(101);
((CCSprite*)node)->setColor(ccGREEN);
CCLog("uiLayertouchMoved");
}
void UserInterfaceLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
CCNode * node = this->getChildByTag(101);
((CCSprite*)node)->setColor(ccWHITE);
CCLog("uiLayertouchEnded");
}
3.接着是一个带有触摸功能的Spider类
Spider.h:
#ifndef _______Spider__
#define _______Spider__
#include <iostream>
#include "cocos2d.h"
using namespace cocos2d;
//CCLayer是默认继承了触摸协议的,这里蜘蛛类只要是继承CCNode类然后继承CCTargetedTouchDelegate
class Spider:public CCNode,public CCTargetedTouchDelegate
{
public:
CCSprite* spiderSprite;
int numUpdates;
static Spider* spiderWithParentNode(CCNode* parentNode);
bool initWithParentNode(CCNode* parentNode);
//spider触摸事件
void update(float delta);
void moveAway(float duration,CCPoint moveTo);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
};
#endif /* defined(_______Spider__) */
Spider.cpp:
#include "Spider.h"
#include "HelloWorldScene.h"
Spider* Spider::spiderWithParentNode(CCNode* parentNode)
{
//类似宏定义CREAT_FUNC创建对象
Spider* pRet = new Spider();
if (pRet&&pRet->initWithParentNode(parentNode)) {
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return pRet;
}
}
bool Spider::initWithParentNode(CCNode* parentNode) //参数指GameLayer层
{
//注意:要执行某个节点的scheduleUpdate方法必须要把它添加到层上去
parentNode->addChild(this);//this指当前具有触摸事件的node节点
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
spiderSprite = CCSprite::create("spider.png");
spiderSprite->setPosition(CCPointMake(CCRANDOM_0_1()*screenSize.width, CCRANDOM_0_1()*screenSize.height));
this->addChild(spiderSprite);
//添加触摸事件
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, -1, true);
this->scheduleUpdate();
}
//点击蜘蛛随机移动
void Spider::moveAway(float duration, cocos2d::CCPoint moveTo)
{
spiderSprite->stopAllActions();
CCMoveBy* move = CCMoveBy::create(duration, moveTo);
spiderSprite->runAction(move);
}
void Spider::update(float delta)
{
numUpdates++;
if (numUpdates > 50) {
numUpdates = 0;
CCPoint moveTo = CCPointMake(CCRANDOM_0_1()*200 - 100, CCRANDOM_0_1()*100 - 50);
this->moveAway(2, moveTo);
}
}
bool Spider::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
CCPoint touchLocation = HelloWorld::locationFromTouch(pTouch);
bool isTouchHandled = spiderSprite->boundingBox().containsPoint(touchLocation);
if (isTouchHandled) {
numUpdates = 0;
CCPoint moveTo;
float moveDistance = 60;
//float rand = CCRANDOM_0_1();
if (CCRANDOM_0_1() < 0.25f)
{
moveTo = CCPointMake(moveDistance, moveDistance);
}
else if (CCRANDOM_0_1() <0.5f)
{
moveTo = CCPointMake(-moveDistance, moveDistance);
}
else if(CCRANDOM_0_1() <0.75)
{
moveTo = CCPointMake(moveDistance, -moveDistance);
}
else
{
moveTo = CCPointMake(-moveDistance, -moveDistance);
}
this->moveAway(0.1f, moveTo);
}
return isTouchHandled;
return true;
}
4.然后是合成界面,也就是主场景界面
HelloworldScene.h:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "GameLayer.h"
using namespace cocos2d;
class HelloWorld : public cocos2d::CCLayer
{
public:
// Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
virtual bool init();
// there's no 'id' in cpp, so we recommend to return the class instance pointer
static cocos2d::CCScene* scene();
static CCPoint locationFromTouch(CCTouch* touch);
// preprocessor macro for "static create()" constructor ( node() deprecated )
CREATE_FUNC(HelloWorld);
static HelloWorld* sharedhelloworld();
GameLayer* gameLayer();
};
#endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp:
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "GameLayer.h"
#include "UserInterfaceLayer.h"
using namespace cocos2d;
using namespace CocosDenshion;
static HelloWorld * helloWorld = NULL;
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
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
helloWorld = this;
GameLayer* gameLayer = GameLayer::create();
this->addChild(gameLayer,1,201);
UserInterfaceLayer* userInterfaceLayer = UserInterfaceLayer::create();
this->addChild(userInterfaceLayer,2,202);
return true;
}
HelloWorld*HelloWorld::sharedhelloworld()
{
return helloWorld;
}
GameLayer*HelloWorld::gameLayer()
{
CCNode * node = this->getChildByTag(201);
return (GameLayer *)node;
}
CCPoint HelloWorld::locationFromTouch(CCTouch* touch)
{
return touch->getLocation();
}
源码下载:http://download.csdn.net/detail/s10141303/6247313