#include "Snake.h"
const int KWidth = 18;
const int KHeight = 10;
const int KEggSize = 50;
Scene* Snake::createScene()
{
auto scene = Scene::create();
scene->addChild(Snake::create());
return scene;
}
Snake::Snake() : m_curDir(EDirR), m_dt(0.5f)
{
}
Snake::~Snake()
{
}
bool Snake::init()
{
if(!Layer::init())
{
return false;
}
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(Snake::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(Snake::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(Snake::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
initUI();
initMap();
initSnake();
initEgg();
schedule(schedule_selector(Snake::step), m_dt);
return true;
}
bool Snake::onTouchBegan(Touch* touche, Event* event)
{
_beganPos = touche->getLocation();
return true;
}
void Snake::onTouchMoved(Touch* touche, Event* event)
{
_movePos = touche->getLocation();
}
void Snake::onTouchEnded(Touch* touche, Event* event)
{
_endPos = touche->getLocation();
}
void Snake::initUI()
{
auto winsize = Director::getInstance()->getWinSize();
auto drawNode = DrawNode::create();
addChild(drawNode);
Vec2 point[4];
point[0] = Vec2(118, 70);
point[1] = Vec2(winsize.width - 118, 70);
point[2] = Vec2(winsize.width - 118, winsize.height - 70);
point[3] = Vec2(118, winsize.height - 70);
drawNode->drawPolygon(point, 4, Color4F(1, 0, 0, 0), 3, Color4F(1, 0, 0, 1));
auto button = Button::create("test/btn_l.png");
button->setPosition(Vec2(59, winsize.height * 2 / 5));
button->setTag(ETagBtnLeft);
button->addClickEventListener(CC_CALLBACK_1(Snake::buttonListener, this));
addChild(button);
button = Button::create("test/btn_r.png");
button->setPosition(Vec2(winsize.width - 59, winsize.height * 2 / 5));
button->setTag(ETagBtnRight);
button->addClickEventListener(CC_CALLBACK_1(Snake::buttonListener, this));
addChild(button);
button = Button::create("test/btn_t.png");
button->setPosition(Vec2(59, winsize.height * 3 / 5));
button->setTag(ETagBtnTop);
button->addClickEventListener(CC_CALLBACK_1(Snake::buttonListener, this));
addChild(button);
button = Button::create("test/btn_b.png");
button->setPosition(Vec2(winsize.width - 59, winsize.height * 3 / 5));
button->setTag(ETagBtnButtom);
button->addClickEventListener(CC_CALLBACK_1(Snake::buttonListener, this));
addChild(button);
}
void Snake::initMap()
{
for(int i = 0; i < KWidth; ++i)
{
for(int j = 0; j < KHeight; ++j)
{
m_pos[i][j] = Vec2(118 + KEggSize / 2 + KEggSize * i, 70 + KEggSize / 2 + KEggSize * j);
}
}
}
void Snake::buttonListener(Ref* ref)
{
int tag = ((Button*)ref)->getTag();
switch (tag) {
case ETagBtnLeft:
{
m_curDir = EDirL;
}
break;
case ETagBtnRight:
{
m_curDir = EDirR;
}
break;
case ETagBtnTop:
{
m_curDir = EDirT;
}
break;
case ETagBtnButtom:
{
m_curDir = EDirB;
}
break;
default:
break;
}
}
void Snake::step(float dt)
{
//先取出蛇尾,便于吃到蛋后长大
TEgg lastSnake = m_snake[m_snake.size() - 1];
//后续的蛇身都挨个跟进
for(int i = (int)m_snake.size() - 1; i > 0; --i)
{
m_snake[i].x = m_snake[i - 1].x;
m_snake[i].y = m_snake[i - 1].y;
}
//判断方向,确定蛇头位置
if(m_curDir == EDirL)
{
m_snake[0].x--;
}
else if(m_curDir == EDirR)
{
m_snake[0].x++;
}
else if(m_curDir == EDirT)
{
m_snake[0].y++;
}
else if(m_curDir == EDirB)
{
m_snake[0].y--;
}
//判断是否撞墙
if(m_snake[0].x < 0 || m_snake[0].x > KWidth - 1 || m_snake[0].y < 0 || m_snake[0].y > KHeight - 1)
{
//gameover
unschedule(schedule_selector(Snake::step));
return;
}
//判断蛇头是否撞蛇身
for(int i = 1; i < m_snake.size(); ++i)
{
if(m_snake[0].x == m_snake[i].x && m_snake[0].y == m_snake[i].y)
{
//gameover
unschedule(schedule_selector(Snake::step));
return;
}
}
//判断是否吃到egg
if(m_snake[0].x == m_egg.x && m_snake[0].y == m_egg.y)
{
m_eggs.push_back(m_egg);
initEgg();//蛋被吃了,重新生成一个
//每吃一个蛋,蛇速度增大0.02f
m_dt -= 0.01f;
unschedule(schedule_selector(Snake::step));
schedule(schedule_selector(Snake::step), m_dt);
}
//判断是否蛇应该长大了
if(m_eggs.size() > 0 && m_eggs[0].x == lastSnake.x && m_eggs[0].y == lastSnake.y)
{
m_snake.push_back(m_eggs[0]);
m_eggs.erase(m_eggs.begin());
auto sprite = Sprite::create("test/egg.png");
sprite->setPosition(m_pos[lastSnake.x][lastSnake.y]);
addChild(sprite);
m_snakeSprite.push_back(sprite);
}
//修改eggsprite位置
for(int i = 0; i < m_snakeSprite.size(); ++i)
{
m_snakeSprite[i]->setPosition(m_pos[m_snake[i].x][m_snake[i].y]);
}
}
void Snake::initSnake()
{
m_snake.clear();
m_snakeSprite.clear();
int x = 3;
int y = 5;
for(int i = 0; i < 3; ++i)
{
TEgg egg;
egg.x = x - i;
egg.y = y;
m_snake.push_back(egg);
auto sprite = Sprite::create("test/egg.png");
sprite->setPosition(m_pos[egg.x][egg.y]);
addChild(sprite);
m_snakeSprite.push_back(sprite);
}
m_eggSprite = Sprite::create("test/egg.png");
m_eggSprite->setPosition(Vec2(-200, -200));
addChild(m_eggSprite);
}
void Snake::initEgg()
{
int x = rand() % KWidth;
int y = rand() % KHeight;
bool flag = false;
for(int i = 0; i < m_snake.size(); ++i)
{
if(x == m_snake[i].x && y == m_snake[i].y)
{
flag = true;
break;
}
}
if(flag)
{
initEgg();
}
else
{
m_egg.x = x;
m_egg.y = y;
m_eggSprite->setPosition(m_pos[x][y]);
}
}