昨天在网上看到了一个大神在mac下写的2048算法,看后觉得很长见识,算法什么的我最头痛了,看了源码之后,自己建了了项目移植到windows的vs2012下,改的地方很少,主要就是mac和win下的转码问题,这里贴出来,并讲讲如何在windows下移植到安卓下。
先建个工程,然后
#include"MovedTiled.h"
bool MovedTiled:: init(){
if (!Node::init())
{
return false;
}
//背景层
auto bk=LayerColor::create(Color4B(200, 200, 200, 255),GAME_TILED_WIDTH,GAME_TILED_HEIGHT);
this->addChild(bk);
bk->setTag(110);
//数字层
int n=rand()%10;
this->m_number=n>2?2:4;
auto label=Label::createWithSystemFont(StringUtils::format("%d",this->m_number), "宋体", 40);
switch (this->m_number) {
case 2:
bk->setColor(Color3B(230,220,210));
case 4:
bk->setColor(Color3B(230,210,190));
break;
}
label->setTag(10);
label->setColor(Color3B::BLACK);
bk->addChild(label);
label->setPosition(Point(
GAME_TILED_WIDTH/2
,GAME_TILED_HEIGHT/2));
return true;
}
//让这个值翻倍
void MovedTiled::doubleNumber(){
this->m_number=this->m_number*2;
auto bk=this->getChildByTag(110);
Label *label=(Label *)bk->getChildByTag(10);
label->setString(StringUtils::format("%d",m_number));
//动画
bk->runAction(
Sequence::create(
ScaleTo::create(0.2, 0.8),
ScaleTo::create(0.2, 1.2),
ScaleTo::create(0.2, 1)
, NULL));
switch (this->m_number) {
case 2:
bk->setColor(Color3B(230,220,210));
case 4:
bk->setColor(Color3B(230,210,190));
break;
case 8:
bk->setColor(Color3B(230,150,100));
label->setColor(Color3B(255,255,255));
break;
case 16:
bk->setColor(Color3B(230,120,80));
label->setColor(Color3B(255,255,255));
break;
case 32:
bk->setColor(Color3B(230,100,90));
label->setColor(Color3B(255,255,255));
break;
case 64:
bk->setColor(Color3B(230,70,60));
label->setColor(Color3B(255,255,255));
break;
case 128:
bk->setColor(Color3B(230,190,60));
label->setColor(Color3B(255,255,255));
break;
case 256:
bk->setColor(Color3B(230,190,60));
label->setColor(Color3B(255,255,255));
break;
case 512:
bk->setColor(Color3B(230,190,60));
label->setColor(Color3B(255,255,255));
break;
case 1024:
case 2048:
label->setScale(0.5);
bk->setColor(Color3B(210,180,30));
label->setColor(Color3B(255,255,255));
}
}
//在某个位置显示这个块
void MovedTiled::showAt(int r,int c){
moveTo( r,c);
//动画
auto bk=this->getChildByTag(110);
bk->runAction(
Sequence::create(
ScaleTo::create(0.2, 0.8),
ScaleTo::create(0.2, 1.2),
ScaleTo::create(0.2, 1)
, NULL));
}
//移动到r行,c列
void MovedTiled:: moveTo(int r,int c){
this->m_row=r;
this->m_col=c;
this->setPosition(Point(m_col*GAME_TILED_WIDTH+GAME_TILED_BOARD_WIDTH*(m_col+1),
m_row*GAME_TILED_HEIGHT+
GAME_TILED_BOARD_WIDTH*(m_row+1)));
CCLOG("%f,%f",this->getPositionX(),this->getPositionY());
}
#include"GameScene.h"
#include "gamedefine.h"
#include "GameOver.h"
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
bool GameScene::init(){
if (!Layer::init())
{
return false;
}
//初始化游戏标题
auto labelGame=Label::createWithBMFont("fonts/futura-48.fnt","2048");
labelGame->setPosition(Point(labelGame->getContentSize().width/2,GAME_SCREEN_HEIGHT-labelGame->getContentSize().height/2));
labelGame->setScale(0.5f);
this->addChild(labelGame);
//初始化网格
int tiledmapwidth=GAME_TILED_WIDTH*GAME_COLS+GAME_TILED_BOARD_WIDTH*(GAME_COLS+1);
int tiledmapheight=GAME_TILED_HEIGHT*GAME_ROWS+GAME_TILED_BOARD_WIDTH*(GAME_ROWS+1);
//auto colorBack=LayerColor::create(Color4B(160,200,150,255),tiledmapwidth,tiledmapheight);
colorBack=LayerColor::create(Color4B(160,200,150,255),tiledmapwidth,tiledmapheight);
//colorBack->setAnchorPoint(Point(colorBack->getContentSize().width/2,colorBack->getContentSize().height/2));
colorBack->setPosition(Point((GAME_SCREEN_WIDTH-tiledmapwidth)/2,(GAME_SCREEN_HEIGHT-tiledmapheight)/2));
this->addChild(colorBack);
//初始化分数
m_score=0;
//初始化分数标题
auto labelScore=Label::createWithBMFont("fonts/futura-48.fnt","Score:0");
labelScore->setPosition(Point(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT-labelGame->cocos2d::Node::getContentSize().height));
this->addChild(labelScore);
labelScore->setTag(120);
labelScore->setScale(0.8);
//初始化网格的每一个块
for (int row=0; row<GAME_ROWS; row++) {
for (int col=0; col<GAME_COLS; col++) {
auto layerTiled=LayerColor::create(Color4B(70, 70, 70, 255),
GAME_TILED_WIDTH,
GAME_TILED_HEIGHT);
layerTiled->setPosition(
Point(GAME_TILED_WIDTH*col+
GAME_TILED_BOARD_WIDTH*(col+1),
GAME_TILED_HEIGHT*row+
GAME_TILED_BOARD_WIDTH*(row+1)));
colorBack->addChild(layerTiled);
}
}
//初始化逻辑网格数组
for(int i=0;i<GAME_ROWS;i++)
{
for(int j=0;j<GAME_COLS;j++)
{
map[i][j]=0; //空白
}
}
//初始化数字块
newMovedTiled();
//触摸的处理
auto event=EventListenerTouchOneByOne::create();
event->onTouchBegan=[&](Touch*tou,Event*eve){
m_x=tou->getLocation().x;
m_y=tou->getLocation().y;
m_startMove=true;
return true;
};
event->onTouchMoved=[&](Touch*tou,Event*eve){
int x=tou->getLocation().x;
int y=tou->getLocation().y;
if(m_startMove&&(abs(m_x-x)>10||abs(m_y-y)>10)){
m_startMove=false;
E_MOVE_DIR dir;
if(abs(m_x-x)>abs(m_y-y)){
if(m_x<x){
dir=E_MOVE_DIR::RIGHT;
}else
{
dir=E_MOVE_DIR::LEFT;
}
}else
{
if(m_y<y){
dir=E_MOVE_DIR::UP;
}else
{
dir=E_MOVE_DIR::DOWN;
}
}
moveAllTiled(dir);
}
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(event,this);
//分数
return true;
}
void GameScene::moveAllTiled(E_MOVE_DIR dir){
//移动所有的块
m_sound_clear=false;
switch (dir)
{
case E_MOVE_DIR::UP:
moveup();
break;
case E_MOVE_DIR::DOWN:
moveDown();
break;
case E_MOVE_DIR::LEFT:
moveleft();
break;
case E_MOVE_DIR::RIGHT:
moveright();
break;
default:
break;
}
//播放音乐
if(m_sound_clear)
{
SimpleAudioEngine::getInstance()->playEffect("moveClear.wav");
}else
{
SimpleAudioEngine::getInstance()->playEffect("move1.wav");
}
//分数变化
Label * labelScore=(Label *)this->getChildByTag(120);
labelScore->setString(StringUtils::format("score:%d",m_score));
//判定输赢
//产生新的块
newMovedTiled();
}
void GameScene::newMovedTiled(){
auto tiled=MovedTiled::create();
int freeCount=16-m_allTiled.size();
if(freeCount==0)//没有空白区域
{//判定游戏输赢
//上 ,下 左 右 是否还能移动
for(int r=0;r<GAME_ROWS;r++)
{
for(int c=0;c<GAME_COLS;c++)
{ //第r行 第c列的数值
int num=m_allTiled.at(map[r][c]-1)->m_number;
int objNum=0;
//上
if(r+1<GAME_ROWS)
{
objNum=m_allTiled.at(map[r+1][c]-1)->m_number;
if(num==objNum)
{return ;}
}
//下
if(r-1>=0)
{
objNum=m_allTiled.at(map[r-1][c]-1)->m_number;
if(num==objNum)
{return ;}
}
//左
if(c-1>=0)
{
objNum=m_allTiled.at(map[r][c-1]-1)->m_number;
if(num==objNum)
{return ;}
}
//右
if(c+1<GAME_COLS)
{
objNum=m_allTiled.at(map[r][c+1]-1)->m_number;
if(num==objNum)
{return ;}
}
}
}
//跳转场景
auto scene=GameOver::createScene();
Director::getInstance()->replaceScene(TransitionFadeDown::create(0.5, scene));
return;
}
int num=rand()%freeCount;
int row=0;
int col=0;
int count=0;
bool find=false;
for (; row<GAME_ROWS; row++) {
for(col=0;col<GAME_COLS;col++)
{ if(map[row][col]==0)
{
count++;//记录空白的数量
if(count>=num)
{
find=true;
break;
}
}
}
if (find) {
break;
}
}
colorBack->addChild(tiled);
tiled->showAt(row, col);
m_allTiled.pushBack(tiled);
map[row][col]=m_allTiled.getIndex(tiled)+1;
}
void GameScene::moveup(){
CCLOG("moveup");
//向上移动所有的块
for (int col=0; col <GAME_COLS ;col++)
{
for (int row=GAME_ROWS-1;row>=0; row--)
{
if(map[row][col]>0){
for (int row1 =row; row1 < GAME_ROWS-1; row1++)
{
if(map[row1+1][col]==0){
map[row1+1][col]=map[row1][col];
map[row1][col]=0;
m_allTiled.at(map[row1+1][col]-1)->moveTo(row1+1,col);
}else
{//判断是否可以消除
int numObj=m_allTiled.at(map[row1+1][col]-1)->m_number;
int numNow=m_allTiled.at(map[row1][col]-1)->m_number;
if(numObj==numNow){
//map[row1][col]=0;
m_sound_clear=true;
m_score+=numObj*2;
m_allTiled.at(map[row1+1][col]-1)->doubleNumber();
m_allTiled.at(map[row1][col]-1)->removeFromParent();
int index=map[row1][col];
//消除最前面的
m_allTiled.erase(map[row1][col]-1);
for (int r = 0; r < GAME_ROWS; r++)
{
for (int c = 0; c < GAME_COLS; c++)
{
if(map[r][c]>index){
map[r][c]--;
}
}
}
map[row1][col]=0;
}
break;
}
}
}
}
}
}
void GameScene::moveDown(){
CCLOG("movedown");
for (int col=0; col<GAME_COLS; col++) {
for(int row=0;row<GAME_ROWS;row++)
{
if(map[row][col]>0)
{
for(int row1=row;row1>0;row1--)
{
if(map[row1-1][col]==0)
{
map[row1-1][col]=map[row1][col];
map[row1][col]=0;
m_allTiled.at(map[row1-1][col]-1)->moveTo(row1-1, col);
}
else
{//判断,是否可以消除
int numObj=m_allTiled.at(map[row1-1][col]-1)->m_number;
int numNow=m_allTiled.at(map[row1][col]-1)->m_number;
if(numObj==numNow)
{
m_sound_clear=true;
m_score+=numObj*2;
m_allTiled.at(map[row1-1][col]-1)->doubleNumber();
m_allTiled.at(map[row1][col]-1)->removeFromParent();
int index=map[row1][col];
m_allTiled.erase(map[row1][col]-1);
for (int r=0; r<GAME_ROWS; r++)
{
for (int c=0; c<GAME_COLS; c++) {
if(map[r][c]>index)
{map[r][c]--;
}
}
}
map[row1][col]=0;
}
break;
}
}
}
}
}
}
void GameScene::moveleft(){
CCLOG("moveleft");
for (int row=0; row<GAME_ROWS; row++) {
for(int col=0;col<GAME_COLS;col++)
{
if(map[row][col]>0)
{
for(int col1=col;col1>0;col1--)
{
if(map[row][col1-1]==0)
{
map[row][col1-1]=map[row][col1];
map[row][col1]=0;
m_allTiled.at(map[row][col1-1]-1)->moveTo(row, col1-1);
}
else
{//判断,是否可以消除
int numObj=m_allTiled.at(map[row][col1-1]-1)->m_number;
int numNow=m_allTiled.at(map[row][col1]-1)->m_number;
if(numObj==numNow)
{
m_sound_clear=true;
m_score+=numObj*2;
m_allTiled.at(map[row][col1-1]-1)->doubleNumber();
m_allTiled.at(map[row][col1]-1)->removeFromParent();
int index=map[row][col1];
m_allTiled.erase(map[row][col1]-1);
for (int r=0; r<GAME_ROWS; r++)
{
for (int c=0; c<GAME_COLS; c++) {
if(map[r][c]>index)
{map[r][c]--;
}
}
}
map[row][col1]=0;
}
break;
}
}
}
}
}
}
void GameScene::moveright(){
CCLOG("moveright");
for (int row=0; row<GAME_ROWS; row++) {
for(int col=GAME_COLS-1;col>=0;col--)
{
if(map[row][col]>0)
{
for(int col1=col;col1<GAME_COLS-1;col1++)
{
if(map[row][col1+1]==0)
{
map[row][col1+1]=map[row][col1];
map[row][col1]=0;
m_allTiled.at(map[row][col1+1]-1)->moveTo(row, col1+1);
}
else
{//判断,是否可以消除
int numObj=m_allTiled.at(map[row][col1+1]-1)->m_number;
int numNow=m_allTiled.at(map[row][col1]-1)->m_number;
if(numObj==numNow)
{
m_sound_clear=true;
m_score+=numObj*2;
m_allTiled.at(map[row][col1+1]-1)->doubleNumber();
m_allTiled.at(map[row][col1]-1)->removeFromParent();
int index=map[row][col1];
m_allTiled.erase(map[row][col1]-1);
for (int r=0; r<GAME_ROWS; r++)
{
for (int c=0; c<GAME_COLS; c++) {
if(map[r][c]>index)
{map[r][c]--;
}
}
}
map[row][col1]=0;
}
break;
}
}
}
}
}
}
Scene*GameScene::createScene(){
auto scene=Scene::create();
auto layer=GameScene::create();
scene->addChild(layer);
return scene;
}
核心代码就这些,虽然少但却不算简单,其他地方很简单就不贴了,后面我会贴出代码。下载地址
这里就不多说编译的事了,我这里讲讲如何移植到安卓下,首先环境变量设置运行coco2dx下的setup.py
打开eclipse
导入项目,如图打开之后选择安卓版本,拷贝这个目录下的java文件到
拷贝之后,修改mk文件用ecplise开发过c++的小伙伴应该很熟悉这种方法,当然可以在命令行下输入编译命令,但没有这种方法简单,编译成功了
刷新一下修改一下横竖屏
因为手机屏幕分辨率尺寸跟游戏代码的设定尺寸差好多,需要的自己编译修改下吧。