注意: 本文使用cocos2dx 2.2 版本
触摸滑动选关卡的实现
实现这一功能,有这么几个效果(实现方式)
1. 关卡显示
2. 手指触摸滑动,切换关卡
怎么做
1. 关卡显示 :读取图片显示
2. 手指触摸滑动,切换关卡 :实现触摸移动功能
相关技术:
1. 读取图片用plist文件 ,关卡图片文件用xml文件封装,以后维护比较方便
2. 选关卡:把所有关卡加载到一个节点,触摸滑动改变节点显示位置即可实现选关卡
设计:
1. 一个关卡类,一个关卡管理类
2. 选关卡类,实现触摸等
1. 首先创建一个helloworld 程序,在此基础上进行修改
添加游戏关卡类 文件 GameLevel.h 包括关卡类和关卡管理类
#ifndef __GAMELEVEL_H__
#define __GAMELEVEL_H__
#pragma once
#include "cocos2d.h"
class CGameLevel:public cocos2d::CCObject
{
/*
关卡数据类
m_gameMapName : 关卡地图图片文件的名字
m_levelTowerName: 关卡等级图标装饰的图片文件名
*/
public:
~CGameLevel(void);
static CGameLevel* create(std::string m_gameMapName, std::string m_levelTowerName);
private:
CGameLevel(void);
bool init(std::string m_gameMapName, std::string m_levelTowerName);
/*
CC_SYNTHESIZE_READONLY 宏定义
声明了std::string, m_gameMapName, m_levelTowerName 为类的成员变量
并且有公有方法 GetGameMapName(),GetLevelTowerName()
*/
CC_SYNTHESIZE_READONLY(std::string, m_gameMapName, GameMapName);
CC_SYNTHESIZE_READONLY(std::string, m_levelTowerName, LevelTowerName);
};
class CGameLevel_Manager:public cocos2d::CCObject
{
//关卡管理类
public:
virtual ~CGameLevel_Manager();
static CGameLevel_Manager* SingletonCGameLevel_Manager(); // 单例类
bool init();
CGameLevel* GetGameLevel(int index); // 获取某个关卡
private:
CGameLevel_Manager();
/*
CC_SYNTHESIZE_READONLY 宏定义
声明了int totalLevelCount为类的成员变量
并且有公有方法:GetTotalLevelCount()
*/
CC_SYNTHESIZE_READONLY(int, totalLevelCount, TotalLevelCount);
cocos2d::CCArray* gameLevelArray; //保存关卡对象的数组
};
#endif
#include "GameLevel.h"
#include "cocos2d.h"
using namespace cocos2d;
CGameLevel::CGameLevel(void)
{
}
CGameLevel::~CGameLevel(void)
{
}
bool CGameLevel::init(std::string m_gameMapName, std::string m_levelTowerName)
{
this->m_gameMapName = m_gameMapName;
this->m_levelTowerName = m_levelTowerName;
return true;
}
CGameLevel* CGameLevel::create(std::string m_gameMapName, std::string m_levelTowerName)
{
CGameLevel* gl = new CGameLevel();
if (gl->init(m_gameMapName, m_levelTowerName))
{
gl->autorelease();
return gl;
}
return NULL;
}
//**************************************************************************************
CGameLevel_Manager::CGameLevel_Manager(void)
{
totalLevelCount = 0;
gameLevelArray = NULL;
}
CGameLevel_Manager::~CGameLevel_Manager(void)
{
}
CGameLevel_Manager* GameLevelManager= NULL;
CGameLevel_Manager* CGameLevel_Manager::SingletonCGameLevel_Manager()
{
//实现单列类
if (NULL == GameLevelManager)
{
GameLevelManager= new CGameLevel_Manager();
GameLevelManager->init();
}
return GameLevelManager;
}
bool CGameLevel_Manager::init()
{
tinyxml2::XMLDocument* doc=new tinyxml2::XMLDocument();
doc->LoadFile("levels_game.xml");
tinyxml2::XMLElement *root_node=doc->RootElement();
std::string count_str= root_node->Attribute("count"); //获得关卡总数
this->totalLevelCount = cocos2d::CCString::create(count_str)->intValue();
tinyxml2::XMLElement *level_node=root_node->FirstChildElement("level");
gameLevelArray = cocos2d::CCArray::create();
gameLevelArray->retain();
//读取xml数据
while(level_node)
{
std::string myMap =level_node->Attribute("bg");
std::string myLevelIcon =level_node->Attribute("towers_icon");
CGameLevel* gamelevel = CGameLevel::create(myMap, myLevelIcon); //创建关卡类对象
gameLevelArray->addObject(gamelevel); //将关卡对象添加到数组
level_node = level_node->NextSiblingElement();
}
delete doc;
return true;
}
CGameLevel* CGameLevel_Manager::GetGameLevel(int index)
{
//获得某个关卡对象
return dynamic_cast<CGameLevel*>(this->gameLevelArray->objectAtIndex(index));
}
然后添加选关卡类 头文件 SelectGameLevel.h
#ifndef __SELECTGAMELEVEL_H__
#define __SELECTGAMELEVEL_H__
#include "cocos2d.h"
using namespace cocos2d;
class CSelectGameLevel:public cocos2d::CCLayer
{
public:
~CSelectGameLevel(void);
bool init();
static cocos2d::CCScene* scene();
CREATE_FUNC(CSelectGameLevel);
protected:
//触摸
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
void UpdateGameLevelsNode(int level); //改变关卡后重新设置节点位置
private:
int selected_gameLevel ; //选中的关卡
cocos2d::CCNode* gameLevelsNode; //关卡节点
cocos2d::CCPoint start_drag_point; //手指开始点击的屏幕点
cocos2d::CCPoint start_drag_moved_point; //节点上的点
private:
CSelectGameLevel(void);
};
#endif
SelectGameLevel.cpp
#include "SelectGameLevel.h"
#include "GameLevel.h"
#include "cocos2d.h"
using namespace cocos2d;
CSelectGameLevel::CSelectGameLevel(void)
{
selected_gameLevel = 0;
gameLevelsNode = NULL;
start_drag_point = ccp(0,0);
start_drag_moved_point = ccp(0,0);
}
CSelectGameLevel::~CSelectGameLevel(void)
{
}
cocos2d::CCScene* CSelectGameLevel::scene()
{
//创建场景
cocos2d::CCScene* scene = cocos2d::CCScene::create();
CSelectGameLevel* layer = CSelectGameLevel::create();
scene->addChild(layer);
return scene;
}
bool CSelectGameLevel::init()
{
if (!cocos2d::CCLayer::init())
{
return false;
}
cocos2d::CCSize win_size = cocos2d::CCDirector::sharedDirector()->getWinSize();
//加载背景plist文件到缓存
cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("stages_bg.plist");
//背景
cocos2d::CCSprite* bg = cocos2d::CCSprite::createWithSpriteFrameName("ss_bg.png");
this->addChild(bg);
bg->setPosition(ccp(win_size.width/2, win_size.height/2));
cocos2d::CCSprite* bg2=cocos2d::CCSprite::createWithSpriteFrameName("ss_bg_CN.png");
this->addChild(bg2);
bg2->setPosition(ccp(win_size.width/2,win_size.height/2));
//关卡数据
CGameLevel_Manager* GameLevelManager= CGameLevel_Manager::SingletonCGameLevel_Manager();
int levelCount = GameLevelManager->getTotalLevelCount();
//关卡显示节点
gameLevelsNode = cocos2d::CCNode::create();
this->addChild(gameLevelsNode);
gameLevelsNode->setPosition(ccp(0,0));
//加载关卡图片文件到缓存
cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("stages_theme1.plist");
//将所有关卡加载到节点
for (int i=0; i<levelCount; i++)
{
std::string mymap = GameLevelManager->GetGameLevel(i)->getGameMapName();
std::string mytowner = GameLevelManager->GetGameLevel(i)->getLevelTowerName();
cocos2d::CCSprite* level_map = cocos2d::CCSprite::createWithSpriteFrameName(mymap.c_str());
gameLevelsNode->addChild(level_map);
level_map->setPosition(ccp(win_size.width/2+i*win_size.width, win_size.height/2));
cocos2d::CCSprite* level_icon = cocos2d::CCSprite::createWithSpriteFrameName(mytowner.c_str());
gameLevelsNode->addChild(level_icon);
level_icon->setPosition(ccp(win_size.width/2+i*win_size.width, 100 ));
}
this->setTouchEnabled(true);
return true;
}
void CSelectGameLevel::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
cocos2d::CCTouch* touch=dynamic_cast<cocos2d::CCTouch*> (pTouches->anyObject());
start_drag_point=touch->getLocation();
start_drag_moved_point=gameLevelsNode->getPosition();
}
void CSelectGameLevel::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
cocos2d::CCTouch* touch=dynamic_cast<cocos2d::CCTouch*> (pTouches->anyObject());
float px = touch->getLocation().x - start_drag_point.x;
float py = 0;
float new_node_x = start_drag_moved_point.x + px;
float new_node_y = start_drag_moved_point.y + py;
gameLevelsNode->setPosition(ccp(new_node_x,new_node_y));
}
void CSelectGameLevel::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
cocos2d::CCTouch* touch=dynamic_cast<cocos2d::CCTouch*> (pTouches->anyObject());
int cur_select_level = this->selected_gameLevel;
float px = touch->getLocation().x -start_drag_point.x; //手指最后离开的点减去手指开始触摸的点
if (px>200)
{
cur_select_level = this->selected_gameLevel-1;
if (cur_select_level<0) //向右边移动,上一关
{
cur_select_level = 0;
}
}
else if (px < -200)
{
cur_select_level = this->selected_gameLevel+1;
int totalCount = CGameLevel_Manager::SingletonCGameLevel_Manager()->getTotalLevelCount()-1;
if (totalCount<cur_select_level)
{
cur_select_level = totalCount;
}
}
this->UpdateGameLevelsNode(cur_select_level); //更新关卡显示
}
void CSelectGameLevel::UpdateGameLevelsNode(int level)
{
cocos2d::CCSize win_size=cocos2d::CCDirector::sharedDirector()->getWinSize();
selected_gameLevel = level;
gameLevelsNode->setPositionX(-1*selected_gameLevel*win_size.width);
}
最后在main.cpp 里面修改屏幕大小
eglView->setFrameSize(960, 640);
在AppDelegate.cpp 里面注释掉HelloWorld,添加我们的测试
//CCScene *pScene = HelloWorld::scene();
CCScene *pScene = CSelectGameLevel::scene();
注意,参考文献:http://luoposhusheng.blog.51cto.com/8148702/1334242