cocos2d-下滑动实现游戏关卡变换

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



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

#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







转载于:https://my.oschina.net/u/1422317/blog/185797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值