Xây dựng giao diện với Cocostudio
Ta sử dụng Cocostudio để xây dựng các Scene giao diện cho gameXây dựng Game
Main Menu scene
MainMenuScene.h#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "network/HttpClient.h"
#include "HttpHelper.h"
using namespace cocos2d;
using namespace ui;
using namespace network;
class MainMenuScene : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(MainMenuScene);
private:
void buttonClick(Ref *sender, Widget::TouchEventType type);
private:
Button *btnBasic_;
Button *btnColor_;
Button *btnCrazy_;
Button *btnMore_;
Button *btnHighScore_;
Button *btnSoundOn_;
Button *btnSoundOff_;
Button *btnFacebook_;
Button *btnLike_;
LayerColor *layerAlert_;
Button *btnNoUpdate_;
Button *btnUpdate_;
};
Ta định nghĩa các Button cho từng “menu” ở trên MainMenuScene, định nghĩa hàm buttonClick để nhận sự kiện click của các Button.
MainMenuScene.m
btnBasic_ = (Button *)sceneLayout->getChildByName("btnBasic");
btnBasic_->addTouchEventListener(CC_CALLBACK_2(MainMenuScene::buttonClick, this));
btnColor_ = (Button *)sceneLayout->getChildByName("btnColor");
btnColor_->addTouchEventListener(CC_CALLBACK_2(MainMenuScene::buttonClick, this));
btnCrazy_ = (Button *)sceneLayout->getChildByName("btnCrazy");
btnCrazy_->addTouchEventListener(CC_CALLBACK_2(MainMenuScene::buttonClick, this));
Định nghĩa hàm buttonClick
void MainMenuScene::buttonClick(Ref *sender, Widget::TouchEventType type)
{
Node *button = (Node *)sender;
if (type == Widget::TouchEventType::ENDED) {
if (button == btnBasic_) {
GameInfor::setGameMode(GameModeBasic);
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, (Scene *)InGameScene::createScene()));
} else if (button == btnColor_) {
GameInfor::setGameMode(GameModeColor);
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, (Scene *)InGameScene::createScene()));
} else if (button == btnCrazy_) {
GameInfor::setGameMode(GameModeCrazy);
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, (Scene *)InGameScene::createScene()));
} else if (button == btnHighScore_) {
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, (Scene *)HighScoreScene::createScene()));
}
}
Mỗi button click chúng ta sẽ chuyển scene với hàm replaceScene.
Ingame Scene
InGameScene.h
#include "cocos2d.h"InGameScene.m
#include "ui/CocosGUI.h"
#include "Constant.h"
using namespace cocos2d;
using namespace ui;
class InGameScene : public cocos2d::Layer
{
typedef struct tagMemory
{
int data;
int color;
} MemoryInfor;
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(InGameScene);
private:
virtual void onEnter();
virtual void onExit();
void buttonClick(Ref *sender, Widget::TouchEventType type);
void update(float fDelta);
void prepare();
void displayUIByMode();
void next();
void finishMoving();
void loseGame(bool byTime);
void gameOver(float fDelta);
SpriteFrame *createData(int dataIndex, int colorIndex);
private:
Button *btnBack_;
Button *btnNo_;
Button *btnYes_;
Button *btnSameFigure_;
Button *btnSameColor_;
Button *btnSameAll_;
Button *btnNoSame_;
Label *lblTime_;
Label *lblScore_;
Vec2 showPosition_;
int movingLength_;
Sprite *memorySprite1_;
Sprite *memorySprite2_;
Sprite *currMemorySprite_;
Sprite *nextMemorySprite_;
bool percent_[20] = {false,true,false,false,true,false,false,false,true,false,false,true,false,false,false,true,false,false,true,false};
int maxData_;
int maxColors_;
Color3B colors_[5];
int preDataIndex_;
int preColorIndex_;
MemoryInfor preInfor_;
MemoryInfor currInfor_;
GameMode gameMode_;
bool isMoving_;
int timeLevel_;
int time_;
float timeCnt_;
int score_;
int detalScore_;
int correctCnt_;
int sameCnt_;
};
void InGameScene::prepare()
{
preDataIndex_ = -1;
preColorIndex_ = -1;
preInfor_.data = -1;
preInfor_.color = -1;
maxData_ = 6;
maxColors_ = 6;
isMoving_ = false;
timeLevel_ = 8;
time_ = timeLevel_;
score_ = 0;
timeCnt_ = 0;
correctCnt_ = 0;
sameCnt_ = 0;
if (gameMode_ == GameModeBasic) {
detalScore_ = SCORE_BASIC;
} else if (gameMode_ == GameModeColor) {
detalScore_ = SCORE_COLOR;
} else {
detalScore_ = SCORE_CRAZY;
}
colors_[0] = Color3B(28, 132, 196);
colors_[1] = Color3B(151, 77, 255);
colors_[2] = Color3B(255, 98, 0);
colors_[3] = Color3B(251, 58, 60);
colors_[4] = Color3B(251, 238, 33);
colors_[5] = Color3B(150, 248, 3);
}
void InGameScene::displayUIByMode()
{
if (gameMode_ == GameModeBasic) {
sprtBg_->setVisible(true);
sprtQuestBg_->setVisible(false);
sprtBasicBg_->setVisible(true);
btnBack_->setVisible(false);
btnNo_->setVisible(true);
btnYes_->setVisible(true);
sprtColorBg_->setVisible(false);
sprtCrazyBg_->setVisible(false);
sprtQuestCrazyBg_->setVisible(false);
btnSameFigure_->setVisible(false);
btnSameColor_->setVisible(false);
btnSameAll_->setVisible(false);
btnNoSame_->setVisible(false);
} else if (gameMode_ == GameModeColor) {
sprtBg_->setVisible(true);
sprtQuestBg_->setVisible(true);
sprtColorBg_->setVisible(true);
btnBack_->setVisible(false);
btnNo_->setVisible(true);
btnYes_->setVisible(true);
sprtBasicBg_->setVisible(false);
sprtCrazyBg_->setVisible(false);
sprtQuestCrazyBg_->setVisible(false);
btnSameFigure_->setVisible(false);
btnSameColor_->setVisible(false);
btnSameAll_->setVisible(false);
btnNoSame_->setVisible(false);
} else {
sprtBg_->setVisible(false);
sprtQuestBg_->setVisible(false);
btnBack_->setVisible(false);
btnNo_->setVisible(false);
btnYes_->setVisible(false);
sprtBasicBg_->setVisible(false);
sprtColorBg_->setVisible(false);
sprtCrazyBg_->setVisible(true);
sprtQuestCrazyBg_->setVisible(true);
btnSameFigure_->setVisible(true);
btnSameColor_->setVisible(true);
btnSameAll_->setVisible(true);
btnNoSame_->setVisible(true);
}
this->next();
}
void InGameScene::next()
{
time_ = timeLevel_;
lblTime_->setString(std::to_string(time_));
preInfor_.data = currInfor_.data;
preInfor_.color = currInfor_.color;
nextMemorySprite_ = memorySprite2_;
if (currMemorySprite_ == memorySprite2_) {
nextMemorySprite_ = memorySprite1_;
}
int ra = rand() % 20;
int nextDataIndex = rand() % maxData_;
int nextColorIndex = rand() % maxColors_;
if (GameInfor::getGameMode() == GameModeBasic) {
nextColorIndex = preInfor_.color;
}
if (percent_[ra]) {
if (gameMode_ == GameModeBasic) {
nextDataIndex = preInfor_.data;
} else if (gameMode_ == GameModeColor) {
nextColorIndex = preInfor_.color;
} else {
int r2 = rand() % 3;
if (r2 == 0) {
nextDataIndex = preInfor_.data;
} else if (r2 == 1) {
nextColorIndex = preInfor_.color;
} else if (r2 == 2) {
nextDataIndex = preInfor_.data;
nextColorIndex = preInfor_.color;
}
}
}
if ((gameMode_ == GameModeBasic && nextDataIndex == preInfor_.data) ||
(gameMode_ == GameModeColor && nextColorIndex == preInfor_.color) ||
(gameMode_ == GameModeCrazy && nextDataIndex == preInfor_.data && nextColorIndex == preInfor_.color)) {
sameCnt_ ++;
if (sameCnt_ == 3) {
if (gameMode_ == GameModeBasic) {
nextDataIndex = nextDataIndex + 1 < maxData_ ? (nextDataIndex + 1) : 0;
} else if (gameMode_ == GameModeColor) {
nextColorIndex = nextColorIndex + 1 < maxColors_ ? (nextColorIndex + 1) : 0;
} else {
nextDataIndex = nextDataIndex + 1 < maxData_ ? (nextDataIndex + 1) : 0;
}
}
} else {
sameCnt_ = 0;
}
currInfor_.data = nextDataIndex;
currInfor_.color = nextColorIndex;
std::string str = "data_" + std::to_string(nextDataIndex) + ".png";
nextMemorySprite_->setSpriteFrame(str);
nextMemorySprite_->setColor(colors_[nextColorIndex]);
isMoving_ = true;
currMemorySprite_->runAction(Sequence::create(MoveTo::create(0.3, Vec2(showPosition_.x - movingLength_, showPosition_.y)), CallFunc::create(CC_CALLBACK_0(InGameScene::finishMoving, this)), NULL));
nextMemorySprite_->runAction(MoveTo::create(0.3, showPosition_));
}
SpriteFrame *InGameScene::createData(int dataIndex, int colorIndex)
{
std::string str = "data_" + std::to_string(dataIndex) + ".png";
Image *loadImage = new Image;
loadImage->autorelease();
if( loadImage->initWithImageFile(str) )
{
//make a color array which is easier to work with
Color3B srcColor = Color3B(254, 254, 254);
Color3B dstColor = colors_[colorIndex];
unsigned long srcC = (srcColor.r << 0) | (srcColor.g << 8) | (srcColor.b << 16);
unsigned long dstC = (dstColor.r << 0) | (dstColor.g << 8) | (dstColor.b << 16);
unsigned char * rawData = loadImage->getData();
int width = loadImage->getWidth();
int height = loadImage->getHeight();
//replace the colors need replacing
unsigned int * b = (unsigned int *) rawData;
for( int pixel = 0; pixel < width*height; pixel++ )
{
unsigned int p = *b;
if( (p&0x00FFFFFF) == srcC )
{
*b = (int)((p&0xFF000000) | dstC);
}
b++;
}
Texture2D *texture = new Texture2D();
texture->autorelease();
if (texture->initWithData(rawData, 4*width*height, Texture2D::PixelFormat::RGBA8888, width, height, Size(width, height))) {
auto sprtFr = SpriteFrame::createWithTexture(texture, Rect(0, 0, width, height));
return sprtFr;
}
}
return NULL;
}
void InGameScene::finishMoving()
{
currMemorySprite_->setPosition(Vec2(showPosition_.x + movingLength_, showPosition_.y));
currMemorySprite_ = nextMemorySprite_;
isMoving_ = false;
}
void InGameScene::update(float fDelta)
{
if (preInfor_.data > -1 && !isMoving_) {
//Playing
timeCnt_ += fDelta;
if (timeCnt_ >= 1.0) {
timeCnt_ -= 1.0;
time_ --;
lblTime_->setString(std::to_string(time_));
}
if (time_ == 0) {
//GameOver
preInfor_.data = -1;
isMoving_ = true;
this->loseGame(true);
}
}
}
void InGameScene::buttonClick(Ref *sender, Widget::TouchEventType type) {
if (isMoving_) {
return;
}
Node *button = (Node *) sender;
if (type == Widget::TouchEventType::ENDED) {
bool result = false;
if (button == btnYes_) {
//YES
if (preInfor_.data < 0) {
AudioHelper::play(AudioHelper::AudioType::ButtonClick);
this->displayUIByMode();
return;
} else {
if (gameMode_ == GameModeBasic &&
preInfor_.data == currInfor_.data) {
result = true;
} else if (gameMode_ == GameModeColor &&
preInfor_.color == currInfor_.color) {
result = true;
}
}
} else if (button == btnNo_) {
if (preInfor_.data > -1) {
if (gameMode_ == GameModeBasic &&
preInfor_.data != currInfor_.data) {
result = true;
} else if (gameMode_ == GameModeColor &&
preInfor_.color != currInfor_.color) {
result = true;
}
} else {
return;
}
} else if (button == btnSameFigure_) {
//Same Figure
if (preInfor_.data == currInfor_.data && preInfor_.color != currInfor_.color) {
result = true;
}
} else if (button == btnSameColor_) {
if (preInfor_.data != currInfor_.data && preInfor_.color == currInfor_.color) {
result = true;
}
} else if (button == btnSameAll_) {
if (preInfor_.data == currInfor_.data && preInfor_.color == currInfor_.color) {
result = true;
}
} else if (button == btnNoSame_) {
if (preInfor_.data != currInfor_.data && preInfor_.color != currInfor_.color) {
result = true;
}
}
if (result) {
AudioHelper::play(AudioHelper::AudioType::Right);
correctCnt_ ++;
timeCnt_ = 0;
if (correctCnt_ == 8) {
timeLevel_ = 5;
} else if (correctCnt_ == 16) {
timeLevel_ = 3;
} else if (correctCnt_ == 28) {
if (gameMode_ == GameModeCrazy) {
timeLevel_ = 2;
}
} else if (correctCnt_ == 40) {
if (gameMode_ != GameModeCrazy) {
timeLevel_ = 1;
}
}
score_ += detalScore_;
lblScore_->setString(std::to_string(score_));
this->next();
} else {
this->loseGame(false);
}
}
}
void InGameScene::loseGame(bool byTime)
{
AudioHelper::play(AudioHelper::AudioType::Wrong);
preInfor_.data = -1; //pause loop
isMoving_ = true; //disable click
Sprite *alert;
if (byTime) {
alert = Sprite::create("timeover.png");
} else {
alert = Sprite::create("selectwrong.png");
}
Vec2 origin = Director::getInstance()->getVisibleOrigin();
alert->setScale(Director::getInstance()->getContentScaleFactor());
alert->setPosition(Vec2(currMemorySprite_->getPositionX(), currMemorySprite_->getPositionY() + origin.y * 0.1));
this->addChild(alert, ZORDER_LAYER_4);
GameInfor::setBestScore(score_);
this->scheduleOnce(schedule_selector(InGameScene::gameOver), 1.2);
}
void InGameScene::gameOver(float fDelta)
{
AudioHelper::play(AudioHelper::AudioType::GameOver);
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, (Scene *)GameOverScene::createScene()));
}
Ta sử dụng các memorySprite1 và memorySprite2 để hiển thị các con vật chuyển qua lại trong màn hình game.
Hàm Next() để quyết định chọn các con vật sẽ tiếp tục hiển thị khi người chơi click button.
GameOver Scene
GameOverScene.h#include "cocos2d.h"Ta sử dụng TextFieldTFF để nhập tên người chơi.
#include "ui/CocosGUI.h"
#include "network/HttpClient.h"
#include "HttpHelper.h"
using namespace cocos2d;
using namespace ui;
using namespace network;
class GameOverScene : public cocos2d::Layer, public TextFieldDelegate
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(GameOverScene);
void onBackKeyClick();
private:
virtual bool onTouchBegan(Touch *touch, Event *unused_event);
virtual void onTouchMoved(Touch *touch, Event *unused_event);
virtual void onTouchEnded(Touch *touch, Event *unused_event);
void buttonClick(Ref *sender, Widget::TouchEventType type);
virtual bool onTextFieldInsertText(TextFieldTTF * sender, const char * text, size_t nLen);
virtual bool onTextFieldDeleteBackward(TextFieldTTF * sender, const char * delText, size_t nLen);
void submitScore();
private:
Button *btnQuit_;
Button *btnRetry_;
Button *btnFacebook_;
Button *btnSubmit_;
TextFieldTTF *txtName_;
Label *lblName_;
Sprite *txtBg_;
bool isSending;
bool clicked_;
int dy_;
};
GameOverScene.m
txtName_ = TextFieldTTF::textFieldWithPlaceHolder("Submit your name", "Arial", 35);
txtName_->setPosition(txtBg_->getPosition());
txtName_->setColor(Color3B(111, 58, 255));
txtName_->setDelegate(this);
sceneLayout->addChild(txtName_, 100);
<Còn tiếp>
No comments:
Post a Comment