利用cocos2dx 3.2开发消灭星星(四)游戏主场景

第二节说到在菜单场景MenuScene中加入一个菜单并且加入一个开始按钮切换到GameScene,下面我们来讲一下游戏的主界面GameScene和GameLayer

一、主场景GameScene

GameScene.h

class GameScene : public Scene{
public:
	virtual bool init();
	CREATE_FUNC(GameScene);
};

GameScene.cpp

bool GameScene::init(){
	if(!Scene::init()){
		return false;
	}
	Audio::getInstance()->playBGM();
	this->addChild(GameLayer::create());
	return true;
} 

GameScene很简单,里面只有一个GameLayer层。注意Audio是我们的音效工具,我们以后再说

我们主要看一下GameLayer

二、GameLayer

头文件GameLayer.h

class GameLayer : public Layer{
public:
	virtual bool init();
	CREATE_FUNC(GameLayer);
	void floatLevelWord();<span style="white-space:pre">	</span>//飘出关卡信息
	void floatTargetScoreWord();<span style="white-space:pre">	</span>//飘出目标分数
	void removeFloatWord();<span style="white-space:pre">	</span>//移除关卡信息和目标分数
	void showStarMatrix();<span style="white-space:pre">	</span>//创造星星矩阵(所有的星星)
	virtual void update(float delta);//update
	virtual bool onTouchBegan(Touch* touch,Event* event);//接受触摸事件
	void refreshMenu();<span style="white-space:pre">	</span>//刷新顶部信息
	void showLinkNum(int size);<span style="white-space:pre">	</span>//显示连击信息
	void hideLinkNum();<span style="white-space:pre">	</span>//隐藏连击信息
	void floatLeftStarMsg(int leftNum);<span style="white-space:pre">	</span>//显示剩余星星数量
	void gotoNextLevel();<span style="white-space:pre">	</span>//跳到另一关
	void gotoGameOver();<span style="white-space:pre">	</span>//游戏结束
private:
	FloatWord* _levelMsg;<span style="white-space:pre">	</span>//关卡信息(飘字)
	FloatWord* _targetScore;<span style="white-space:pre">	</span>//目标分数(飘字)
	TopMenu* menu;<span style="white-space:pre">	</span>//顶部信息
	StarMatrix* matrix;<span style="white-space:pre">	</span>//所有星星
	Label* linkNum;<span style="white-space:pre">	</span>//连击信息
};


GameLayer好像定义了许多东西,但是我们可以从下面的私有成员可以看到,其实GameLayer就包含了4个组件。

1)关卡和目标分数信息(Layer刚启动时的飘字)

2)顶部信息栏

3)矩阵的布局(就是所有的星星)

4)连击的信息

除了onTouchBegan和update这两个函数,其余函数基本都是为这4个组件添加功能。

onTouchBegan是触摸事件发生的回调函数。

update是每帧刷新调用的回调函数。

下面我们分别对这四个组件解读。

1._levelMsg 和 _targetScore 为了实现先飘入关卡信息,再飘入目标分数,等两条信息飘出后才显示_matrix(所有的星星)

具体实现

1)在GameLayer的init函数里面调用floatLevelWord函数

this->floatLevelWord();

2)floatLevelWord飘出关卡字体(FloatWord的floatIn方法,具体见第三节)

void GameLayer::floatLevelWord(){
	Size visibleSize = Director::getInstance()->getVisibleSize();
	_levelMsg = FloatWord::create(
		ChineseWord("guanqia") + cocos2d::String::createWithFormat(": %d",GAMEDATA::getInstance()->getNextLevel())->_string,
		50, Point(visibleSize.width,visibleSize.height/3*2)
		);
	this->addChild(_levelMsg,1);
	_levelMsg->floatIn(0.5f,CC_CALLBACK_0(GameLayer::floatTargetScoreWord,this));
	Audio::getInstance()->playReadyGo();
}

3)_levelMsg 的floatIn后的回调是floatTargetScoreWord

void GameLayer::floatTargetScoreWord(){
	Size visibleSize = Director::getInstance()->getVisibleSize();
	_targetScore = FloatWord::create(
		ChineseWord("mubiao") + cocos2d::String::createWithFormat(": %d",GAMEDATA::getInstance()->getNextScore())->_string + ChineseWord("fen"),
		50, Point(visibleSize.width,visibleSize.height/3)
		);
	this->addChild(_targetScore,1);
	_targetScore->floatIn(0.5f,CC_CALLBACK_0(GameLayer::removeFloatWord,this));
}


4)_targetScore的floatIn后的回调是removeFloatWord,用于移除_levelMsg 和_targetScore

void GameLayer::removeFloatWord(){
	_levelMsg->floatOut(0.5f,nullptr);
	_targetScore->floatOut(0.5f,CC_CALLBACK_0(GameLayer::showStarMatrix,this));
}

5)同样,_levelMsg或_targetScore的floatOut后调用showStarMatrix,用于显示星星矩阵(所有星星)

void GameLayer::showStarMatrix(){
	matrix = StarMatrix::create(this);
	this->addChild(matrix);
}

至此,从进入GameLayer -> 飘出关卡信息(floatLevelWord)->飘出目标分数(floatTargetWord) -> 移除(removeFloatWord)->显示星星矩阵(showStarMatrix)的流程结束。


这里提到了StarMatrix这个类。我们就先讲一下单个星星的Star类

Star类就是单颗星星的包装,主要包括星星的颜色,星星的当前位置,星星的目标位置(为什么星星有两个位置?这个等下说),以及星星在矩阵中的位置(与星星矩阵相关)

class Star : public Sprite{
public:
	enum color{
		GREEN,
		RED,
		YELLOW,
		PURPLE,
		BLUE
	};
	static Star* create(int color);
	int getColor();
	void setDesPosition(const Point& p);
	inline Point getDesPosition(){return desPosition;}
	void updatePosition();
	inline int getIndexI(){return index_i;}
	inline int getIndexJ(){return index_j;}
	inline void setIndex_ij(int i,int j){index_i = i;index_j = j;}
private:
	char* getImage(int color);

public:
	static const int COLOR_MAX_NUM = 5;
	static const int STAR_WIDTH = 48;
	static const int STAR_HEIGHT = 48;
private:
	int color;
	Point desPosition;
	bool selected;
	int index_i;
	int index_j;
};

这里需要注意的有两点:1,create函数需要传入一个int值代表星星的颜色

    2,getImage函数就是通过传入的代表星星颜色的int值找到对应的图片

下面是create和getImage的代码

Star* Star::create(int color){
	Star* ret = new Star();
	if(ret && ret->initWithFile(ret->getImage(color))){
		ret->color = color;
		ret->selected = false;
		ret->autorelease();
		return ret;
	}
	CC_SAFE_DELETE(ret);
	return nullptr;
}

char* Star::getImage(int color){
	switch(color){
	case color::BLUE:
		return "blue.png";
	case color::GREEN:
		return "green.png";
	case color::YELLOW:
		return "orange.png";
	case color::RED:
		return "red.png";
	case color::PURPLE:
		return "purple.png";
	}
}
这样,我们在构造单颗星星的时候,只需要向create函数传入一个数字,就能够构造出不同颜色的星星。


好了,这样我们就大致讲完单颗星星Star类,我们再回过头来看StarMatrix

先看StarMatrix的代码

class StarMatrix : public Node{
public:
	static StarMatrix* create(GameLayer* layer);
	virtual bool init(GameLayer* layer);
	 void initMatrix();
public:
	const static int ROW_NUM = 10;
	const static int COL_NUM = 10;
private:
	Star* stars[ROW_NUM][COL_NUM];
	GameLayer* m_layer;
};

这里大家可以发现,StarMatrix其实就是对一个Star*二维数组的包装,但是这里要注意一下,StarMatrix的构造需要传入Layer(这个是为了以后通知layer进行更新操作用)

StarMatrix的init函数会调用initMatrix()方法,而initMatrix()方法实质就是初始化内置的Star*二维数组

void StarMatrix::initMatrix(){
	srand(time(0));
	for(int i=0;i<ROW_NUM;i++){
		for(int j=0;j<COL_NUM;j++){
			int color = abs(rand()%Star::COLOR_MAX_NUM);

			Star* star = Star::create(color);
			stars[i][j] = star;
			star->setPosition(getPositionByIndex(i,j) + Point(0,100));
			star->setDesPosition(getPositionByIndex(i,j));
			star->setIndex_ij(i,j);
			this->addChild(star);
		}
	}
}

1)在构造星星的时候用了随机数(应该不难想到吧)

2)初始化的时候同时对Star的一些属性进行设置(当前位置,目标位置,在矩阵中的位置)

3)getPointionByIndex是我自己写的一个可以由矩阵位置i和j得到一个Point的一个函数,下面给出代码

Point StarMatrix::getPositionByIndex(int i,int j){
	float x = j * Star::STAR_WIDTH + Star::STAR_WIDTH/2;
	float y = (StarMatrix::COL_NUM - i)*Star::STAR_HEIGHT - Star::STAR_HEIGHT/2;
	return Point(x,y);
}
其实就是由i和j得到像素位置的方法,很简单


至于这里再次出现了当前位置和目标位置,这两个位置有什么用?我们下一节再讨论,暂时可以先把他们先设置成一下。


至此,从进入GameLayer -> 飘出关卡信息(floatLevelWord)->飘出目标分数(floatTargetWord) -> 移除(removeFloatWord)->显示星星矩阵(showStarMatrix)的流程结束。
效果如下:

飘字



飘字结束显示的星星矩阵



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值