cocos2d-下滑動實現遊戲關卡變換

注意: 本文使用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



GameLevel.cpp
#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();  對象


注意,參考文獻:http://luoposhusheng.blog.51cto.com/8148702/1334242

相關文章
相關標籤/搜索