#include "GameLink.h"
#include "CountDownBar.h"
USING_NS_CC;
Scene* GameLink::createScene()
{
auto scene = Scene::create();
auto layer = GameLink::create();
scene->addChild(layer);
return scene;
}
bool GameLink::init()
{
if (!Layer::init())
return false;
auto map = TMXTiledMap::create("rec.tmx");
map->setAnchorPoint(Vec2(0, 0));
map->setPosition(0, 0);
addChild(map);
auto bg = Sprite::create("background.png");//LayerColor::create(Color4B(255, 255, 255, 255));
bg->setAnchorPoint(Vec2(0, 0));
bg->setPosition(0, 0);
addChild(bg);
mapLayer = map->layerNamed("Layer1");
initBoard();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameLink::touchBegan, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
position = Vec2(-1, -1);
timeOut = false;
time = FULLTIME;
bar = CountDownBar::createCountDownBar(Vec2(0, 360), 480);
addChild(bar);
scheduleUpdate();
auto button = MenuItemImage::create("button1.png", "button2.png",this,menu_selector(GameLink::findReach));
auto menu = Menu::create(button, NULL);
menu->setAnchorPoint(Vec2(0, 0));
menu->setScale(0.4);
menu->setPosition(560, 100);
addChild(menu);
return true;
}
void GameLink::initBoard()
{
int num = 0;
int cards[WIDTH*HEIGHT] = { 0 };
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
int id = mapLayer->getTileGIDAt(Vec2(i, j));
if (mapLayer->getTileGIDAt(Vec2(i, j)) == 2)//id比Tile里面的大1
++num;
}
}
srand(::time(NULL));
for (int i = 0; i < num / 2; ++i)
{
cards[i] = rand() % 5 + 1;
cards[i + num / 2] = cards[i];
}
for (int i = 0; i < num; ++i)
{
int index = rand() % (num);
int temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
//memcpy(this->cards, cards, sizeof(int)*WIDTH*HEIGHT);
for (int x = 0; x < WIDTH; ++x)
{
for (int y = 0; y < HEIGHT; ++y)
{
if (mapLayer->getTileGIDAt(Vec2(x, y)) == 2)
{
sprites[x][y] = Sprite::create(String::createWithFormat("card%d.png", cards[--num])->getCString());
this->cards[x][y] = cards[num];
}
else
{
sprites[x][y] = Sprite::create("card0.png");
this->cards[x][y] = 0;
}
sprites[x][y]->setPosition(20+x*40, 20+y*40);
addChild(sprites[x][y]);
}
}
}
bool GameLink::touchBegan(cocos2d::Touch* touch, cocos2d::Event*)
{
auto pos = touch->getLocation();
int x = pos.x / 40;
int y = pos.y / 40;
if (x < WIDTH && y < HEIGHT)
{
if (position != Vec2(-1, -1))
{
int i = (int)position.x / 40;
int j = (int)position.y / 40;
if (i != x || j != y)
{
if (cards[x][y] == cards[i][j] && canReach(x,y,i,j))
{
auto frame = SpriteFrame::create("card0.png", Rect(0, 0, 40, 40));
sprites[x][y]->setSpriteFrame(frame);
sprites[i][j]->setSpriteFrame(frame);
sprites[i][j]->setOpacity(255);
cards[x][y] = cards[i][j] = 0;
position = Vec2(-1, -1);
}
else
{
sprites[i][j]->setOpacity(255);
sprites[x][y]->setOpacity(180);
position = pos;
}
}
}
else
{
position = pos;
sprites[x][y]->setOpacity(100);
}
}
return false;
}
bool GameLink::noCorner(int x1, int y1, int x2, int y2)
{
if (x1 == x2)
{
auto start = y1 < y2 ? y1 : y2;
auto end = y1 > y2 ? y1 : y2;
for (int i = start + 1; i < end; ++i)
{
if (cards[x1][i] > 0)
return false;
}
return true;
}
else if (y1 == y2)
{
auto start = x1 < x2 ? x1 : x2;
auto end = x1 > x2 ? x1 : x2;
for (int i = start + 1; i < end; ++i)
{
if (cards[i][y1] > 0)
return false;
}
return true;
}
else
return false;
}
bool GameLink::oneCorner(int x1, int y1, int x2, int y2)
{
if (!(x1 != x2 && y1 != y2))
return false;
if (cards[x1][y2] == 0)
{
if (noCorner(x1, y1, x1, y2) && noCorner(x2, y2, x1, y2))
return true;
}
else if (cards[x2][y1] == 0)
{
if (noCorner(x1, y1, x2, y1) && noCorner(x2, y2, x2, y1))
return true;
}
else
return false;
}
bool GameLink::twoCorner(int x1, int y1, int x2, int y2)
{
/*if (!(x1 != x2 && y1 != y2))
return false;*/
for (int i = 0; i < WIDTH; ++i)
{
if (cards[i][y1] > 0)
continue;
if (noCorner(i, y1, x1, y1) && oneCorner(i, y1, x2, y2))
return true;
}
for (int i = 0; i < HEIGHT; ++i)
{
if (cards[x1][i] > 0)
continue;
if (noCorner(x1, i, x1, y1) && oneCorner(x1, i, x2, y2))
return true;
}
return false;
}
bool GameLink::canReach(int x1, int y1, int x2, int y2)
{
if (noCorner(x1, y1, x2, y2))
return true;
else if (oneCorner(x1, y1, x2, y2))
return true;
else if (twoCorner(x1, y1, x2, y2))
return true;
else
return false;
}
void GameLink::update(float dt)
{
if (time > 0)
{
bar->barUpdate(time, FULLTIME);
--time;
}
else
{
if (!timeOut)
{
timeOut = true;
}
}
}
void GameLink::findReach(Ref*)
{
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
if (cards[i][j] == 0)
continue;
for (int k = 0; k < WIDTH; ++k)
{
for (int l = 0; l < HEIGHT; ++l)
{
if (cards[k][l] == 0)
continue;
if (i == k && j == l)
continue;
if (cards[i][j] != cards[k][l])
continue;
if (canReach(i, j, k, l))
{
auto blink = Blink::create(5, 10);
auto clone = blink->clone();
sprites[i][j]->runAction(blink);
sprites[k][l]->runAction(clone);
return ;
}
}
}
}
}
return;
}