注意: 本文使用cocos2dx 2.2 版本 node
觸摸滑動選關卡的實現
實現這一功能,有這麼幾個效果(實現方式)
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 this
#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 spa
#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); code
在AppDelegate.cpp 裏面註釋掉HelloWorld,添加咱們的測試 xml
//CCScene *pScene = HelloWorld::scene();
CCScene *pScene = CSelectGameLevel::scene(); 對象