第二节说到在菜单场景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>//连击信息
};
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));
}
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)的流程结束。
效果如下:
飘字
飘字结束显示的星星矩阵