您的位置:首页 > 其它

超级2048

2015-06-27 18:32 274 查看
<1>Cube.h

//
// Cube.h
// JNTest
//
// Created by jianan on 15/6/25.
//
//

#ifndef __JNTest__Cube__
#define __JNTest__Cube__

#include "cocos2d.h"
USING_NS_CC;

class Cube : public Node
{
public:
Cube();
~Cube();
bool init(int num, int row, int col);
static Cube* create(int num, int row, int col);
public:
void doubleNum(); //数字乘以2
void setColorByNum(int num);
private:
CC_SYNTHESIZE(int, _row, Row);
CC_SYNTHESIZE(int, _col, Col);
CC_PROPERTY(int, _num, Num); //方块数字
CC_SYNTHESIZE(bool, _isLock, IsLock); //方块是否处于锁定状态,锁定的方块不可以再次发生消除
CC_SYNTHESIZE(LayerColor*, _bgLayerColor, BgLayerColor); //背景颜色
Label* _labNum; //数字标签上显示的数字
};

#endif /* defined(__JNTest__Cube__) */
<2>Cube.cpp
//
// Cube.cpp
// JNTest
//
// Created by jianan on 15/6/25.
//
//

#include "Cube.h"

Cube::Cube():_num(0), _bgLayerColor(NULL),_labNum(NULL){

}

Cube::~Cube(){

}

bool Cube::init(int num, int row, int col){

_row = row;
_col = col;

//数字
_num = num;

_isLock = false;

//背景颜色
_bgLayerColor = LayerColor::create(Color4B::BLUE, 60, 90);
_bgLayerColor->ignoreAnchorPointForPosition(false);
this->addChild(_bgLayerColor);

setColorByNum(_num);

_labNum = Label::createWithSystemFont(StringUtils::format("%d", _num), "Arial", 30);
_labNum->ignoreAnchorPointForPosition(false);
_labNum->setColor(Color3B::BLACK);
this->addChild(_labNum);

return true;
}

Cube* Cube::create(int num, int row, int col){

Cube* cube = new Cube();

if(cube && cube->init(num, row, col)){
cube->autorelease();
return cube;
}
CC_SAFE_DELETE(cube);
return NULL;
}

void Cube::doubleNum(){
setNum(getNum() * 2);
_isLock = true;
}

void Cube::setColorByNum(int num){
if(num % 16 == 0){
_bgLayerColor->setColor(Color3B::GREEN); //绿
}else if(num % 8 == 0){
_bgLayerColor->setColor(Color3B::BLUE); //蓝
}else if(num % 4 == 0){
_bgLayerColor->setColor(Color3B::RED); //红
}else if(num % 2 == 0){
_bgLayerColor->setColor(Color3B::WHITE); //白
}
}

int Cube::getNum(){
return _num;
}

void Cube::setNum(int num){
_num = num;
_labNum->setString(StringUtils::format("%d", _num));
setColorByNum(_num);
}

<3>GameScene.h

//
// GameScene.h
// JNTest
//
// Created by jianan on 15/6/23.
//
//

#ifndef __JNTest__GameScene__
#define __JNTest__GameScene__

#include "cocos2d.h"
USING_NS_CC;
#include "Cube.h"
#include <vector>
using namespace std;

#define MAP_WIDTH 10
#define MAP_HEIGHT 10

struct PT{
PT(int row, int col) : _row(row), _col(col){}
int _row;
int _col;
};

class GameScene : public Layer
{
public:
GameScene();
~GameScene();
static Scene* scene();
virtual bool init();
CREATE_FUNC(GameScene);
public:
bool onTouchBegan(Touch *touch, Event *unused); //触摸
void onTouchMoved(Touch *touch, Event *unused);
void onTouchEnded(Touch *touch, Event *unused);
void fillAfterDelayTimes(float dt);
Vec2 _touchBeganPt;
bool _onlyClick;

Vec2 getPositionByRowAndCol(int row, int col); //根据行列得到方块坐标
Cube* createOneCube(int row, int col); //根据行列,随机创造一个方块
void fill(int type = 1); //发生消除后填充方块

//上下左右移动方块
void moveUp();
void moveDown();
void moveLeft();
void moveRight();

//根据某个方块寻找最近应该移动到的方块
PT findUpCube(Cube* nowCube, int row, int col);
PT findDownCube(Cube* nowCube, int row, int col);
PT findLeftCube(Cube* nowCube, int row, int col);
PT findRightCube(Cube* nowCube, int row, int col);

//
void setAllCubeUnlock(); //设置所有方块为解锁状态
void doubleCallback(Node* node, void* pData); //node为做动作的方块, pData为数字乘以2的方块
void update(float dt); //更新函数
bool isGameOver(); //判断当前游戏是否结束
private:
Cube** _matrixCube; //地图中的方块数据
};

#endif /* defined(__JNTest__GameScene__) */
<4>GameScene.cpp

//
// GameScene.cpp
// JNTest
//
// Created by jianan on 15/6/23.
//
//

#include "GameScene.h"

GameScene::GameScene(){
srand((unsigned)time(NULL));
}

GameScene::~GameScene(){

}

Scene* GameScene::scene(){
Scene* scene = Scene::create();
GameScene* layer = GameScene::create();
scene->addChild(layer);
return scene;
}

bool GameScene::init(){
if(!Layer::init()){
return false;
}

EventListenerTouchOneByOne* touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(GameScene::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(GameScene::onTouchEnded, this);

_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

int size = sizeof(Cube*) * MAP_WIDTH * MAP_HEIGHT;
_matrixCube = (Cube**)malloc(size);
memset((void*)_matrixCube, 0, size);

fill(2);

scheduleUpdate();

return true;
}

bool GameScene::onTouchBegan(Touch *touch, Event *unused){

for(int row = 0; row < MAP_HEIGHT; row++){
for(int col = 0; col < MAP_WIDTH; col++){

Cube* cube = _matrixCube[row * MAP_WIDTH + col];

if(cube && cube->getNumberOfRunningActions() > 0){
return false;
}
}
}

_touchBeganPt = touch->getLocation();
_onlyClick = true;
return true;
}

void GameScene::onTouchMoved(Touch *touch, Event *unused){

for (int row = 0; row < MAP_HEIGHT; row++){
for (int col = 0; col < MAP_WIDTH; col++){

Cube* cube = _matrixCube[row * MAP_WIDTH + col];

if (cube && cube->getNumberOfRunningActions() > 0){
return;
}
}
}

_onlyClick = false;

Vec2 touchMovedPt = touch->getLocation();

if (touchMovedPt.y - _touchBeganPt.y > abs(touchMovedPt.x - _touchBeganPt.x)){
moveUp();
}
else if (_touchBeganPt.y - touchMovedPt.y > abs(touchMovedPt.x - _touchBeganPt.x)){
moveDown();
}
else if (_touchBeganPt.x - touchMovedPt.x > abs(touchMovedPt.y - _touchBeganPt.y)){
moveLeft();
}
else if (touchMovedPt.x - _touchBeganPt.x > abs(touchMovedPt.y - _touchBeganPt.y)){
moveRight();
}
}

void GameScene::onTouchEnded(Touch *touch, Event *unused){
if (_onlyClick){
return;
}
scheduleOnce(schedule_selector(GameScene::fillAfterDelayTimes), 0.4f);
}

void GameScene::fillAfterDelayTimes(float dt){
fill(2);
}

Vec2 GameScene::getPositionByRowAndCol(int row, int col){
return Vec2(32 + 64 * col, 48 + 96 * row);
}

Cube* GameScene::createOneCube(int row, int col){
Cube* cube = NULL;

int r = rand() % 100;
if(r < 20){
cube = Cube::create(2, row, col);
}else if(r < 40){
cube = Cube::create(4, row, col);
}else if(r < 70){
cube = Cube::create(8, row, col);
}else if(r < 100){
cube = Cube::create(16, row, col);
}
return cube;
}

void GameScene::fill(int type /* = 1 */){

if(type == 2){

vector<Vec2> kongVec;

for(int row = 0; row < MAP_HEIGHT; row++){
for(int col = 0; col < MAP_WIDTH; col++){
Cube* cube = _matrixCube[row * MAP_WIDTH + col];
if(!cube){
kongVec.push_back(Vec2(row, col));
}
}
}
if(kongVec.size() == 0){

}else if(kongVec.size() == 1){

Vec2 p = kongVec[0];
int row = (int)p.x;
int col = (int)p.y;
Cube* cube = _matrixCube[row * MAP_WIDTH + col];
if(!cube){
cube = createOneCube(row, col);
cube->setPosition(getPositionByRowAndCol(row, col));
this->addChild(cube);

Sequence* seq = Sequence::create(ScaleTo::create(0.2, 0.3f), ScaleTo::create(0.1, 1.0f), NULL);
cube->runAction(seq);

_matrixCube[row * MAP_WIDTH + col] = cube;
}

}else{
int idx1 = rand() % (int)kongVec.size();
Vec2 p1 = kongVec[idx1];

kongVec.erase(kongVec.begin() + idx1);

int idx2 = rand() % (int)kongVec.size();
Vec2 p2 = kongVec[idx2];

int row = (int)p1.x;
int col = (int)p1.y;

Cube* cube = _matrixCube[row * MAP_WIDTH + col];
if(!cube){
cube = createOneCube(row, col);
cube->setPosition(getPositionByRowAndCol(row, col));
this->addChild(cube);

Sequence* seq = Sequence::create(ScaleTo::create(0.2, 0.3f), ScaleTo::create(0.1, 1.0f), NULL);
cube->runAction(seq);

_matrixCube[row * MAP_WIDTH + col] = cube;
}

row = (int)p2.x;
col = (int)p2.y;

cube = _matrixCube[row * MAP_WIDTH + col];
if(!cube){
cube = createOneCube(row, col);
cube->setPosition(getPositionByRowAndCol(row, col));
this->addChild(cube);

Sequence* seq = Sequence::create(ScaleTo::create(0.2, 0.3f), ScaleTo::create(0.1, 1.0f), NULL);
cube->runAction(seq);

_matrixCube[row * MAP_WIDTH + col] = cube;
}
}
}else{
for(int row = 0; row < MAP_HEIGHT; row++){
for(int col = 0; col < MAP_WIDTH; col++){

Cube* cube = _matrixCube[row * MAP_WIDTH + col];
if(!cube){
cube = createOneCube(row, col);
cube->setPosition(getPositionByRowAndCol(row, col));
this->addChild(cube);

Sequence* seq = Sequence::create(ScaleTo::create(0.2, 0.3f), ScaleTo::create(0.1, 1.0f), NULL);
cube->runAction(seq);

_matrixCube[row * MAP_WIDTH + col] = cube;
}
}
}
}

}

void GameScene::moveUp(){
for (int col = 0; col < MAP_WIDTH; col++){
for(int row = MAP_HEIGHT - 1; row >= 0; row--){

Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];
if(!nowCube){
continue;
}

PT pt = findUpCube(nowCube, row, col);

if (pt._row == -1){ //此方块无法移动则直接返回
log("row:%d, col:%d can not move", row, col);
continue;
}

log("row:%d, col:%d should move to newRow:%d, newCol:%d", row, col, pt._row, pt._col);

int moveToRow = pt._row;
int moveToCol = pt._col;

Cube* moveEndCube = _matrixCube[moveToRow * MAP_WIDTH + moveToCol]; //用于判断此处有没有方块

if (!moveEndCube){ //如果此处没有方块,则直接移动过去
_matrixCube[row * MAP_WIDTH + col] = NULL;
_matrixCube[moveToRow * MAP_WIDTH + moveToCol] = nowCube;
nowCube->setRow(moveToRow);
nowCube->setCol(moveToCol);
nowCube->runAction(MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)));
}
else{
if (moveEndCube->getIsLock()){
continue;
}
_matrixCube[row * MAP_WIDTH + col] = NULL;

Sequence* seq = Sequence::create(
MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)),
CCCallFuncND::create(this, callfuncND_selector(GameScene::doubleCallback), moveEndCube),
NULL
);
nowCube->runAction(seq);

moveEndCube->setIsLock(true);
}
}
}
}

void GameScene::moveDown(){
for (int row = 0; row < MAP_HEIGHT; row++){
for (int col = 0; col < MAP_WIDTH; col++){

Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];
if (!nowCube){
continue;
}

PT pt = findDownCube(nowCube, row, col);

if (pt._row == -1){ //此方块无法移动则直接返回
log("row:%d, col:%d can not move", row, col);
continue;
}

log("row:%d, col:%d should move to newRow:%d, newCol:%d", row, col, pt._row, pt._col);

int moveToRow = pt._row;
int moveToCol = pt._col;

Cube* moveEndCube = _matrixCube[moveToRow * MAP_WIDTH + moveToCol]; //用于判断此处有没有方块

if (!moveEndCube){ //如果此处没有方块,则直接移动过去
_matrixCube[row * MAP_WIDTH + col] = NULL;
_matrixCube[moveToRow * MAP_WIDTH + moveToCol] = nowCube;
nowCube->setRow(moveToRow);
nowCube->setCol(moveToCol);
nowCube->runAction(MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)));
}
else{
if (moveEndCube->getIsLock()){
continue;
}
_matrixCube[row * MAP_WIDTH + col] = NULL;

Sequence* seq = Sequence::create(
MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)),
CCCallFuncND::create(this, callfuncND_selector(GameScene::doubleCallback), moveEndCube),
NULL
);
nowCube->runAction(seq);
moveEndCube->setIsLock(true);
}
}
}
}

void GameScene::moveLeft(){
for (int row = 0; row < MAP_HEIGHT; row++){
for (int col = 0; col < MAP_WIDTH; col++){

Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];
if (!nowCube){
continue;
}

PT pt = findLeftCube(nowCube, row, col);

if (pt._col == -1){ //此方块无法移动则直接返回
log("row:%d, col:%d can not move", row, col);
continue;
}

log("row:%d, col:%d should move to newRow:%d, newCol:%d", row, col, pt._row, pt._col);

int moveToRow = pt._row;
int moveToCol = pt._col;

Cube* moveEndCube = _matrixCube[moveToRow * MAP_WIDTH + moveToCol]; //用于判断此处有没有方块

if (!moveEndCube){ //如果此处没有方块,则直接移动过去
_matrixCube[row * MAP_WIDTH + col] = NULL;
_matrixCube[moveToRow * MAP_WIDTH + moveToCol] = nowCube;
nowCube->setRow(moveToRow);
nowCube->setCol(moveToCol);
nowCube->runAction(MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)));
}
else{
if (moveEndCube->getIsLock()){
continue;
}
_matrixCube[row * MAP_WIDTH + col] = NULL;

Sequence* seq = Sequence::create(
MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)),
CCCallFuncND::create(this, callfuncND_selector(GameScene::doubleCallback), moveEndCube),
NULL
);
nowCube->runAction(seq);
moveEndCube->setIsLock(true);
}
}
}
}

void GameScene::moveRight(){
for (int row = 0; row < MAP_HEIGHT; row++){
for (int col = MAP_WIDTH - 1; col >= 0; col--){

Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];
if (!nowCube){
continue;
}

PT pt = findRightCube(nowCube, row, col);

if (pt._col == -1){ //此方块无法移动则直接返回
log("row:%d, col:%d can not move", row, col);
continue;
}

log("row:%d, col:%d should move to newRow:%d, newCol:%d", row, col, pt._row, pt._col);

int moveToRow = pt._row;
int moveToCol = pt._col;

Cube* moveEndCube = _matrixCube[moveToRow * MAP_WIDTH + moveToCol]; //用于判断此处有没有方块

if (!moveEndCube){ //如果此处没有方块,则直接移动过去
_matrixCube[row * MAP_WIDTH + col] = NULL;
_matrixCube[moveToRow * MAP_WIDTH + moveToCol] = nowCube;
nowCube->setRow(moveToRow);
nowCube->setCol(moveToCol);
nowCube->runAction(MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)));
}
else{
if (moveEndCube->getIsLock()){
continue;
}

_matrixCube[row * MAP_WIDTH + col] = NULL;

Sequence* seq = Sequence::create(
MoveTo::create(0.3f, getPositionByRowAndCol(moveToRow, moveToCol)),
CCCallFuncND::create(this, callfuncND_selector(GameScene::doubleCallback), moveEndCube),
NULL
);

nowCube->runAction(seq);
moveEndCube->setIsLock(true);
}
}
}
}

PT GameScene::findUpCube(Cube* nowCube, int row, int col){
int moveToRow = -1;

for(int upRow = row + 1; upRow < MAP_HEIGHT; upRow++){
Cube* cube = _matrixCube[upRow * MAP_WIDTH + col];
if (!cube){ //为空,则继续查找
moveToRow = upRow;
}

if (cube && cube->getNum() == nowCube->getNum()){
if (cube->getIsLock()){
return PT(moveToRow, col);
}
return PT(upRow, col);
}

if (cube && cube->getNum() != nowCube->getNum()){
return PT(moveToRow, col);
}

}
return PT(moveToRow, col);
}

PT GameScene::findDownCube(Cube* nowCube, int row, int col){
int moveToRow = -1;

for (int upRow = row - 1; upRow >= 0; upRow--){
Cube* cube = _matrixCube[upRow * MAP_WIDTH + col];
if (!cube){ //为空,则继续查找
moveToRow = upRow;
}

if (cube && cube->getNum() == nowCube->getNum()){
if (cube->getIsLock()){
return PT(moveToRow, col);
}
return PT(upRow, col);
}

if (cube && cube->getNum() != nowCube->getNum()){
return PT(moveToRow, col);
}

}
return PT(moveToRow, col);
}

PT GameScene::findLeftCube(Cube* nowCube, int row, int col){
int moveToCol = -1;

for (int leftCol = col - 1; leftCol >= 0; leftCol--){
Cube* cube = _matrixCube[row * MAP_WIDTH + leftCol];
if (!cube){ //为空,则继续查找
moveToCol = leftCol;
}

if (cube && cube->getNum() == nowCube->getNum()){
if (cube->getIsLock()){
return PT(row, moveToCol);
}
return PT(row, leftCol);
}

if (cube && cube->getNum() != nowCube->getNum()){
return PT(row, moveToCol);
}

}
return PT(row, moveToCol);
}

PT GameScene::findRightCube(Cube* nowCube, int row, int col){
int moveToCol = -1;

for (int leftCol = col + 1; leftCol < MAP_WIDTH; leftCol++){
Cube* cube = _matrixCube[row * MAP_WIDTH + leftCol];
if (!cube){ //为空,则继续查找
moveToCol = leftCol;
}

if (cube && cube->getNum() == nowCube->getNum()){
if (cube->getIsLock()){
return PT(row, moveToCol);
}
return PT(row, leftCol);
}

if (cube && cube->getNum() != nowCube->getNum()){
return PT(row, moveToCol);
}

}
return PT(row, moveToCol);
}

void GameScene::setAllCubeUnlock(){

for(int row = 0; row < MAP_HEIGHT; row++){
for(int col = 0; col < MAP_WIDTH; col++){

Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];
if(nowCube && nowCube->getIsLock()){
nowCube->setIsLock(false);
}
}
}
}

void GameScene::update(float dt){
bool isMoving = false;

for(int i = 0; i < MAP_WIDTH * MAP_HEIGHT; i++){
Cube* cube = _matrixCube[i];
if(cube && cube->getNumberOfRunningActions() > 0){
isMoving = true;
break;
}
}

if(!isMoving){
setAllCubeUnlock();
}

if(isGameOver()){
unscheduleUpdate();
Director::getInstance()->replaceScene(TransitionFade::create(1.0f, GameScene::scene()));
}
}

void GameScene::doubleCallback(Node* node, void* pData){
node->removeFromParent();
node = NULL;

Cube* cube = (Cube*)(pData);
cube->doubleNum();
cube->setIsLock(true);
}

bool GameScene::isGameOver(){
for(int row = 0; row < MAP_HEIGHT; row++){
for(int col = 0; col < MAP_WIDTH; col++){
Cube* nowCube = _matrixCube[row * MAP_WIDTH + col];

if(!nowCube){
continue;
}

PT ptUp = findUpCube(nowCube, row, col);
PT ptDown = findDownCube(nowCube, row, col);
PT ptLeft = findLeftCube(nowCube, row, col);
PT ptRight = findRightCube(nowCube, row, col);

if (ptUp._row != -1 || ptDown._row != -1 || ptLeft._col != -1 || ptRight._col != -1){
return false;
}
}
}

return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: