cocos2d-x 托付模式的巧妙运用——附源代码(二)

转载请注明出处:http://blog.csdn.net/hust_superman/article/details/38292265,谢谢。

继上一篇将了托付类的详细实现后。这篇来将一下怎样在游戏中使用实现的托付类。也就是怎样在游戏中来调用托付类来完毕一些功能。详细的应用场景和应用层会在以下介绍。

先来看一看游戏demo实现的详细图片,demo比較简单。可是资源齐全,拿到源代码后能够在源代码的基础上继续完好demo做出一款真正的游戏。好了,老规矩。先上图再说:


游戏中点击播放button后会进入游戏主界面,看到一个红色的小方块慢慢的移动到以下,最后游戏结束,结束后会有结束界面。

这个demo主要是来阐释怎样运用托付类来在游戏中使主游戏逻辑更清晰。

好了,以下来看一下详细的场景和游戏的主要层。

游戏中一个GameScene 场景,在场景中加入了托付类StatusLayer层和游戏主逻辑GameLayer层,GameLayer层中调用托付类来完毕游戏開始与游戏结束的逻辑。

以下来看一下GameScene.cpp的实现,在当中会将托付类注冊到GameLayer层中。

#include "GameScene.h"
#include "GameLayer.h"
#include "StatusLayer.h"

USING_NS_CC;

GameScene::GameScene(){
}

GameScene::~GameScene(){
}

bool GameScene::init() {
	if(Scene::init()) {
<span style="white-space:pre">	</span>//载入图片资源到缓存,方便后面使用图片资源
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("flappyrec.plist","flappyrec.png");
	auto statusLayer = StatusLayer::create();
	this->addChild(statusLayer);
	//Add the main game layer
	auto gameLayer = GameLayer::create();
	//注冊托付类到GameLayer层中
	gameLayer->setDelegator(statusLayer);
	this->addChild(gameLayer);
	return true;
	} else {
	return false;
	}
}
GameScene中比較简单。就是加入了StatusLayer层和GameLayer层,并把StatusLayer作为托付类注冊到GameLayer中。

游戏中的基本的东西都在GameLayer中,以下来看下GameLayer.h的内容

#include "cocos2d.h"

USING_NS_CC;
//游戏进行的状态枚举类
typedef enum _game_status {
	GAME_STATUS_READY = 1,
	GAME_STATUS_START,
	GAME_STATUS_OVER
} GameStatus;

/**
 * 抽象的托付类,有三个虚函数,继承这个托付类的子类须要实现
 * 这三个虚函数。以便控制游戏開始,执行,结束的推断
 */
class StatusDelegate {
public:
	/**
	* When the game start, this method will be called
	*/
	virtual void onGameStart() = 0;
	/**
	* During paying, after the score changed, this method will be called
	*/
	virtual void onGamePlaying() = 0;
	/**
	* When game is over, this method will be called
	*/
	virtual void onGameEnd() = 0;
};

const int MENU_START = 10001;

class GameLayer : public Layer {
public:
	GameLayer();
	~GameLayer();
	virtual bool init();
	CREATE_FUNC(GameLayer);	//实现注冊托付类的宏,delegator作为成员变量。能够调用托付类中的各个函数
	
	//覆写父类的onEnter函数,记得带override
	virtual void onEnter() 	//实现注冊托付类的宏。delegator作为成员变量。能够调用托付类中的各个函数override;
	//实现注冊托付类的宏,delegator作为成员变量,能够调用托付类中的各个函数
	CC_SYNTHESIZE(StatusDelegate*,delegator,Delegator);
private:
	void showStartButton();//显示開始button
	void menuStartCallback(Ref* pSender);//開始button回调函数
	void createSquares();//创建红色方块
	void moveFinished(Ref* pSender);//方块移动结束函数
private:
	Sprite* square;
	Size visibleSize;
	Point origin;

	GameStatus gameStatus;
};
上面代码中最重要的就是托付类宏的使用,这个GameScene中的以下的相应
//注冊托付类到GameLayer层中
gameLayer->setDelegator(statusLayer);

宏的作用也就是注冊到GameLayer中的详细的托付类StatusDelegate的子类StatusLayer。

以下看GameLayer.cpp的详细实现

#include "GameLayer.h"

USING_NS_CC;

GameLayer::GameLayer(){
}
GameLayer::~GameLayer() {
}

bool GameLayer::init() {
	if(!Layer::init()) {
		return false;
	}
	this->gameStatus = GAME_STATUS_READY;
	visibleSize = Director::getInstance()->getVisibleSize();
	origin = Director::getInstance()->getVisibleOrigin();
	//调用显示開始button
	this->showStartButton();

	return true;
}

void GameLayer::onEnter() {
	Layer::onEnter();
	//TODO
}
/**
 * 显示開始button,并为button注冊回调函数
 */
void GameLayer::showStartButton() {
	Sprite* startBtn = Sprite::createWithSpriteFrameName("play.png");
	Sprite* startBtnActive = Sprite::createWithSpriteFrameName("play.png");
	startBtn->setScale(0.6f);//缩放
	startBtnActive->setScale(0.6f);//缩放
	startBtnActive->setPositionY(4);//使button向上移动4个单位
	//将上述精灵作为菜单进行加入
	auto menuStartItem = MenuItemSprite::create(startBtn,startBtnActive,NULL,
			CC_CALLBACK_1(GameLayer::menuStartCallback,this));
	auto menuStart = Menu::create(menuStartItem,NULL);
	menuStart->setPosition(Vec2(this->visibleSize.width/2, this->visibleSize.height/2));
	menuStart->setTag(MENU_START);
	this->addChild(menuStart,10);

}
/**
 * 按下開始菜单后的回调函数。主要是调用托付类中的onGameStart函数来实现游戏的開始
 * 同一时候移除開始button并创建游戏主界面中的红色小方块
 */
void GameLayer::menuStartCallback(Ref* pSender) {
	if(this->gameStatus == GAME_STATUS_OVER) {
		return ;
	}
	if(this->gameStatus == GAME_STATUS_READY) {
		log("start");
		//托付StatusLayer中的onGameStart函数来运行游戏開始逻辑
		this->delegator->onGameStart();
		this->getChildByTag(MENU_START)->runAction(FadeOut::create(0.4f));
		this->removeChildByTag(MENU_START,true);
		this->gameStatus = GAME_STATUS_START;
		this->createSquares();//创建红色小方块
	} else if(this->gameStatus  == GAME_STATUS_START) {
		//TODO
	}
}
/**
 * 创建红色小方块。并在移动5s后游戏结束
 */
void GameLayer::createSquares(){
	//加入方块精灵
	square = Sprite::createWithSpriteFrameName("whitebird.png");
	square->setPosition(Vec2(visibleSize.width/2,visibleSize.height/2));
	square->setColor(Color3B::RED);
	this->addChild(square);
	//游戏開始。5秒后游戏结束
	auto move = MoveTo::create(5.0f,Vec2(square->getPositionX(),origin.y));
	//移动结束后回调函数
	auto moveDone = CallFuncN::create(CC_CALLBACK_1(GameLayer::moveFinished,this));
	auto sequence = Sequence::createWithTwoActions(move,moveDone);
	square->runAction(sequence);
}
/**
 * 移动结束后的回调函数。也就是游戏结束,
 * 当中能够开到delegator->onGameEnd的运用
 * 这个是直接使用托付类的onGameEnd来控制游戏结束
 * 是不是瞬间感觉这个类清晰了很多,
 */
void GameLayer::moveFinished(Ref* pSender) {
	//托付StatusLayer中的onGameEnd函数运行游戏结束的逻辑
	this->delegator->onGameEnd();
	this->removeChild(square,true);
}
上面代码中须要特别注意的就是托付类调用onGameStart()函数和onGameEnd()函数,都是使用的前面介绍的那个托付类的宏
CC_SYNTHESIZE(StatusDelegate*,delegator,Delegator);
直接使用delegator来调用托付类中的函数。相当于实现了层与层之间的通信。

//托付StatusLayer中的onGameEnd函数运行游戏结束的逻辑
this->delegator->onGameEnd();

上面这段代码是这篇博客最主要想表达的,当你把详细的托付类都实现好了,那么在游戏主逻辑中你会发现原来能够这么轻松清晰高效的来调用这些东西,代码看着就清晰,并且看到的代码逻辑都是如此的简单。由于你都在托付类中详细的实现了。

好了。这篇文章和上一篇文章表达的就是托付类的详细实现。拥有好托付类,能够是游戏主逻辑更清晰。并且也能够在游戏的层与层之间进行传递參数。避免了静态变量的运用,也简化了主游戏层的代码量,不显得那么臃肿。

以下附上demo的源代码,源代码中有详细的资源文件。下载好源代码后能够自己建立个新project来把游戏完好,实现这个小游戏。

下载地址:点击下载

好了,这篇主要讲了托付类的详细应用,下一篇写一下游戏中的物理碰撞规则的应用。

posted @ 2017-08-03 14:31  cxchanpin  阅读(186)  评论(0)    收藏  举报