Skip to content

Commit

Permalink
add reset & undo to stage scene
Browse files Browse the repository at this point in the history
  • Loading branch information
kerlw committed Jun 12, 2015
1 parent a400e46 commit 5333a4d
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 35 deletions.
7 changes: 6 additions & 1 deletion Classes/CampaignData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ static DataFileHelper* s_pDataFileHelper = nullptr;

CampaignData* CampaignData::loadData(const std::string& path) {
auto campaign = new (std::nothrow) CampaignData();
unsigned char* data = FileUtils::getInstance()->getFileData(path, "rb", nullptr);
/**
* For android, the 3rd parameter of FileUtils::getFileData(...) could be nullptr,
* but for linux, it could not be nullptr, suck!
*/
ssize_t size;
unsigned char* data = FileUtils::getInstance()->getFileData(path, "rb", &size);
if (!data)
return campaign;

Expand Down
31 changes: 26 additions & 5 deletions Classes/StageScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ bool StageScene::init()
}


void StageScene::menuResetCallback(Ref* pSender) {
if (m_pBox)
m_pBox->reset();
}

void StageScene::menuUndoCallback(Ref* pSender) {
if (m_pBox)
m_pBox->undo();
}

void StageScene::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
Expand Down Expand Up @@ -99,19 +109,30 @@ bool StageScene::loadStageData(const StageData* pData) {
//add Sudoku Box to scene
m_pBox = SudokuBox::create();
m_pBox->initWithStageData(*pData);
m_pBox->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y + CELL_SIZE));
m_pBox->setPosition(Vec2(visibleSize.width/2 + origin.x, (visibleSize.height + CELL_SIZE)/2 + origin.y));
this->addChild(m_pBox);

auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
//reset menu item
auto resetItem = MenuItemImage::create("reset.png", "reset.png",
CC_CALLBACK_1(StageScene::menuResetCallback, this));
resetItem->setPosition(Vec2(origin.x + resetItem->getContentSize().width/2,
origin.y + visibleSize.height - resetItem->getContentSize().height/2));

//undo menu item
auto undoItem = MenuItemImage::create("undo.png", "undo.png",
CC_CALLBACK_1(StageScene::menuUndoCallback, this));
undoItem->setPosition(Vec2(origin.x + undoItem->getContentSize().width/2,
origin.y + visibleSize.height - CELL_SIZE - undoItem->getContentSize().height/2));

//close menu item
auto closeItem = MenuItemImage::create("close.png", "close.png",
CC_CALLBACK_1(StageScene::menuCloseCallback, this));

closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));

// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
auto menu = Menu::create(closeItem, resetItem, undoItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);

Expand Down
2 changes: 2 additions & 0 deletions Classes/StageScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class StageScene : public Layer

// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);
void menuResetCallback(cocos2d::Ref* pSender);
void menuUndoCallback(cocos2d::Ref* pSender);

bool loadStageData(const StageData* pData);

Expand Down
130 changes: 109 additions & 21 deletions Classes/SudokuBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,34 +94,45 @@ void SudokuBox::onItemDragedAtPoint(const Vec2& point, int numberIndex) {
if (m_pData[pos] == numberIndex + 1)
return;

m_pData[pos] = numberIndex + 1;

//create the sprite and set the position.
Sprite* sprite = numberIndex >= 0 ?
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(FRAME_NAME[numberIndex]))
: nullptr;

//remove the old one if there is an old sprite.
Sprite* old = m_mapSprites[pos];
m_mapSprites[pos] = sprite;
if (old) {
this->removeChild(old);
old = nullptr;
}
operation op;
op.pos = pos;
op.oldValue = m_pData[pos];
op.value = numberIndex + 1;

//add the new one if it is not null.
if (sprite) {
sprite->ignoreAnchorPointForPosition(false);
sprite->setAnchorPoint(Vec2(0, 1));
sprite->setPosition(Vec2((pos % m_iCols) * CELL_SIZE, (m_iRows - pos / m_iCols) * CELL_SIZE));
this->addChild(sprite, 0);
}
setNumber(pos, numberIndex + 1);
m_vctOps.push_back(op);
} else {
//its a original cell, ignore
log("position %d is a original cell", pos);
}
}

void SudokuBox::setNumber(int pos, int value) {
int numberIndex = value - 1;
m_pData[pos] = value;

//create the sprite and set the position.
Sprite* sprite = numberIndex >= 0 ?
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(FRAME_NAME[numberIndex]))
: nullptr;

//remove the old one if there is an old sprite.
Sprite* old = m_mapSprites[pos];
m_mapSprites[pos] = sprite;
if (old) {
this->removeChild(old);
old = nullptr;
}

//add the new one if it is not null.
if (sprite) {
sprite->ignoreAnchorPointForPosition(false);
sprite->setAnchorPoint(Vec2(0, 1));
sprite->setPosition(Vec2((pos % m_iCols) * CELL_SIZE, (m_iRows - pos / m_iCols) * CELL_SIZE));
this->addChild(sprite, 0);
}
}

bool SudokuBox::checkResult() {
bool ret = true;
//XXX optimization: only check the error index and changed index.
Expand Down Expand Up @@ -229,3 +240,80 @@ void SudokuBox::refreshErrorTipsLayer() {
}
}
}

void SudokuBox::draw(Renderer *renderer, const Mat4& transform, uint32_t flags) {
Layout::draw(renderer, transform, flags);

m_command.init(_globalZOrder);
m_command.func = CC_CALLBACK_0(SudokuBox::onDraw, this, transform);
renderer->addCommand(&m_command);
}

void SudokuBox::onDraw(const Mat4& transform) {
int rows = m_stagedata.grids_in_row;
int cols = m_stagedata.grids_in_col;
if (rows <= 0 || cols <= 0)
return;

Director* director = Director::getInstance();
CCASSERT(nullptr != director, "Director is null when seting matrix stack");
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);

CHECK_GL_ERROR_DEBUG();

Color4B gridColors[] = {
Color4B(0, 255, 255, 255),
Color4B(255, 0, 255, 255)
};

int linW = 3;
glLineWidth(linW);
Size size = getContentSize();
float width = size.width / cols;
float height = size.height / rows;

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
Color4B cl = gridColors[(j+(i%2))%2];
DrawPrimitives::setDrawColor4B(cl.r, cl.g, cl.b, cl.a);
Vec2 vertices[] = {
Vec2(width*j+linW, height*i+linW),
Vec2(width*j+linW, height*(i+1)-linW),
Vec2(width*(j+1)-linW, height*(i+1)-linW),
Vec2(width*(j+1)-linW, height*i+linW)
};
DrawPrimitives::drawPoly(vertices, 4, true);
}
}

CHECK_GL_ERROR_DEBUG();
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

void SudokuBox::reset() {
memcpy(m_pData, m_pOrgData, sizeof(int) * m_iCols * m_iRows);

auto it = m_mapSprites.begin();
while (it != m_mapSprites.end()) {
this->removeChild(it->second);
++it;
}

m_vctOps.clear();
m_mapSprites.clear();
m_setErrors.clear();
refreshErrorTipsLayer();
}

void SudokuBox::undo() {
auto it = m_vctOps.rbegin();
if (it == m_vctOps.rend())
return;

setNumber(it->pos, it->oldValue);
m_vctOps.pop_back();

checkResult();
refreshErrorTipsLayer();
}
19 changes: 17 additions & 2 deletions Classes/SudokuBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ USING_NS_CC;

class SudokuBox: public ui::Layout {
public:
typedef struct operation {
int pos;
int oldValue;
int value;
} operation;
SudokuBox();
virtual ~SudokuBox();

Expand All @@ -31,11 +36,18 @@ class SudokuBox: public ui::Layout {
/** after check result, refresh error tips */
void refreshErrorTipsLayer();

void reset();
void undo();

virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags) override;
void onDraw(const Mat4& transform);

CC_CONSTRUCTOR_ACCESS:
virtual bool init()
override ;
virtual bool init() override ;
bool containsPoint(const Vec2& point) const;
void setNumber(int pos, int value);

private:
int* m_pOrgData;
int* m_pData;
int m_iCols;
Expand All @@ -44,6 +56,9 @@ override ;
std::map<int, Sprite*> m_mapSprites;
std::set<int> m_setErrors;
std::map<int, Sprite*> m_mapErrorMask;
CustomCommand m_command;

std::vector<operation> m_vctOps;
};

#endif /* SUDOKUBOX_H_ */
12 changes: 8 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ I wanna give her a gift -- a sudoku game, but she is too young to play the real
* 【done】make some stage data internal 内置一些关卡数据
* 【done】make the game continuable, stage by stage 让游戏一关关的延续
* 【done】point out the error 给出错误提示
* 【TODO】load campaign or stage data from file 从文件加载战役、关卡数据
* 【TODO】add bacground images to each cell 每个格子加入背景
* 【done】load campaign or stage data from file 从文件加载战役、关卡数据
* 【done】add reset/undo for each stage 在关卡中增加重置/撤消支持【TODO】add bacground images to each cell 每个格子加入背景
* 【doing】add main scene, campaign scene 增加主界面、战役界面
+ an editor for the game 完成一个编辑器
* 【doing】edit single stage at first 从编辑单个场景开始着手
* 【TODO】edit campaigns which is made up by stages 编辑由stage组成的战役
* 【done】edit single stage at first 从编辑单个关卡开始着手
* 【done】edit campaigns which is made up by stages 编辑由关卡组成的战役
* 【done】generator random puzzle according to specified size 根据指定的尺寸生成随机的谜题
* 【doing】specify the resource for the campaign/stage 为战役/关卡设置特定的资源

###How to compile 如何编译代码
* cocos2d-x 3.6 needed 需要cocos2d-x 3.6
Expand All @@ -47,4 +50,5 @@ for android: 编译目标android平台的话则运行
###Contact me 联系我
If you are a programmer and have interest in this project, mail me! Any help would be appreciated.
如果你是对这个项目感兴趣的程序猿,联系我!欢迎一切助力,谢谢了先。

Email: [email protected]
Binary file removed Resources/CloseNormal.png
Binary file not shown.
Binary file removed Resources/CloseSelected.png
Binary file not shown.
Binary file added Resources/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/reset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/undo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions proj.android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.papalegend.kidsudoku"
android:versionCode="2"
android:versionName="0.0.0.2"
android:versionCode="3"
android:versionName="0.0.0.3"
android:installLocation="auto">

<uses-sdk android:minSdkVersion="9"/>
Expand Down

0 comments on commit 5333a4d

Please sign in to comment.