直接进入正题,准备工作:环境搭建什么的不在本教程的范围内就不说了,接下准备图片资源什么的。背景图,LOGO,开始结束图片什么的。蛇的图片可没地找只好自己动手P了一个。包括头部躯干弯的,直的,尾巴。吃的的东西我准备了3个小球,用TP打包好。
新建cocos工程名为snake.打开工程.打开AppDelegate。.cpp文件加入1行如下设定屏幕尺寸新建载入场景用于载入资源代码如下
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("snake");
director->setOpenGLView(glview);
}
director->setOpenGLView(glview);
//glview->setFrameSize(480,800);
glview->setDesignResolutionSize(480,800, ResolutionPolicy::SHOW_ALL);
loadingsnece载入资源
void LoadingScene::onEnter(){
// add background to current scene
Sprite *background = Sprite::create("logo.png");
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
background->setPosition(origin.x + visibleSize.width/2, origin.y + visibleSize.height/2);
this->addChild(background);
// start ansyc method load the atlas.png
Director::getInstance()->getTextureCache()->addImageAsync("ui.png", CC_CALLBACK_1(LoadingScene::loadingCallBack, this));
}
SpriteFrameCache* cache = SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("ui.plist","ui.png");
建立个蛇节snakenode类继承臼sprite䖵节的宽度为50,在这里我们跟据sprite里的gettag()决定snakenode的图片及方向,具体看代码
const int SNAKE_HEAD_UP=0;
const int SNAKE_HEAD_DOWN=2;
const int SNAKE_HEAD_LEFT=3;
const int SNAKE_HEAD_RIGHT=1;
const int SNAKE_BODY_UP=4;
const int SNAKE_BODY_DOWN=6;
const int SNAKE_BODY_LEFT=7;
const int SNAKE_BODY_RIGHT=5;
const int SNAKE_CORNER_LEFT_UP=16;
const int SNAKE_CORNER_LEFT_DOWN=18;
const int SNAKE_CORNER_UP_LEFT=19;
const int SNAKE_CORNER_UP_RIGHT=17;
const int SNAKE_TAIL_UP=8;
const int SNAKE_TAIL_DOWN=10;
const int SNAKE_TAIL_LEFT=11;
const int SNAKE_TAIL_RIGHT=9;
const int SNAKE_CORNER_RIGHT_UP=12;
const int SNAKE_CORNER_RIGHT_DOWN=14;
const int SNAKE_CORNER_DOWN_LEFT=15;
const int SNAKE_CORNER_DOWN_RIGHT=13;
void SnakeNode::setSnakeNode(int tag){
this->setTag(tag);
this->setSpriteFrame(this->getFrameNameByTag( tag));
this->setSnakeNodeRotate();
}
void SnakeNode::setSnakeNodeRotate(){
int tag=this->getTag();
int rotate=90*(tag%4);
if(tag==SNAKE_CORNER_RIGHT_UP||tag==SNAKE_CORNER_DOWN_LEFT)
rotate=180;
if(tag==SNAKE_CORNER_RIGHT_DOWN || tag==SNAKE_CORNER_UP_LEFT)
rotate=90;
if(tag==SNAKE_CORNER_LEFT_UP||tag==SNAKE_CORNER_DOWN_RIGHT)
rotate=270;
if(tag==SNAKE_CORNER_LEFT_DOWN||tag==SNAKE_CORNER_UP_RIGHT)
rotate=0;
this->setRotation(rotate);
}
SpriteFrame* SnakeNode::getFrameNameByTag(int tag){
switch(tag){
case SNAKE_HEAD_UP:
case SNAKE_HEAD_DOWN:
case SNAKE_HEAD_LEFT:
case SNAKE_HEAD_RIGHT:
return SpriteFrameCache::getInstance()->getSpriteFrameByName("snake_head.png");
case SNAKE_BODY_UP:
case SNAKE_BODY_DOWN:
case SNAKE_BODY_LEFT:
case SNAKE_BODY_RIGHT:
return SpriteFrameCache::getInstance()->getSpriteFrameByName("snake_body.png");
case SNAKE_CORNER_DOWN_LEFT:
case SNAKE_CORNER_LEFT_DOWN:
case SNAKE_CORNER_RIGHT_DOWN:
case SNAKE_CORNER_UP_LEFT:
case SNAKE_CORNER_DOWN_RIGHT:
case SNAKE_CORNER_LEFT_UP:
case SNAKE_CORNER_RIGHT_UP:
case SNAKE_CORNER_UP_RIGHT:
return SpriteFrameCache::getInstance()->getSpriteFrameByName("snake_corner.png");
case SNAKE_TAIL_UP:
case SNAKE_TAIL_DOWN:
case SNAKE_TAIL_LEFT:
case SNAKE_TAIL_RIGHT:
return SpriteFrameCache::getInstance()->getSpriteFrameByName("snake_tail.png");
}
return NULL;
}
这里建立了一个snake类继承自node类,还是直接上代码
class Snake :
public Node
{
public:
Snake(void);
~Snake(void);
CREATE_FUNC(Snake);
void createSnake();
void play();
void setDirection(int direction);
int getDirection();
bool IsDie(Rect rect);
Vector<SnakeNode*> getSnakeNodes();
void addSnakeNode();
void resetSnake();
private:
void setSnakeNode(Sprite *SnakeNode);
Point getNext();
int getInsertTag(int oldTag, int newTag);
int direction;
Vector<SnakeNode*> node;
};
蛇的位置移动更新方式为头部向前移动一格,取出尾巴插入头的后面有点邪恶…根据头部的tag及控制的方向没置tag及图片,然后将vector的最后一个变成尾郜,当蛇吃到一个球时尾部不变,在头部后面插入一个新的snakenode。
void Snake::play(){
SnakeNode *snakeNode=node.back();
//int tag=snakeNode->getTag();
snakeNode->setPosition(node.front()->getPosition());
snakeNode->setSnakeNode(this->getInsertTag(node.front()->getTag(),this->getDirection()));
node.insert(1,snakeNode);
if(node.front()->getTag()!=this->getDirection()){
node.front()->setTag(this->getDirection());
node.front()->setSnakeNodeRotate();
}
node.front()->setPosition(getNext());
node.popBack();
snakeNode=node.back();
snakeNode->setSnakeNode(snakeNode->getTag()%4+8);
}
现在我们的贪吃蛇己经能够前进了,在GameLayer中我们这过触摸屏幕来控制蛇的移动方向.当头部方向为上下时触摸屏幕门左右邹分来控制,头部弓向为左右时通过判断屏幕上下控制,代码如下,
void GameLayer::setSnakeDirection(Point p){
if(bSetDirection) return;
if(snake->getDirection()%2==0){
if(p.x>SCREEN_WIDTH/2)
snake->setDirection(SNAKE_HEAD_RIGHT);
else
snake->setDirection(SNAKE_HEAD_LEFT);
}
else{
if(p.y>SCREEN_HEIGHT/2)
snake->setDirection(SNAKE_HEAD_UP);
else
snake->setDirection(SNAKE_HEAD_DOWN);
}
bSetDirection=true;
}
下面是判断蛇出界及碰到自己身体的代码
bool Snake::IsDie(Rect rect){
if(!rect.containsPoint(node.front()->getPosition()))
return true;
Rect box=node.front()->getBoundingBox();
auto point=node.front()->getPosition();
point.x=point.x*SNAKE_WIDTH;
point.y=point.y*SNAKE_WIDTH;
for(SnakeNode *snakenode:node){
if(snakenode->getTag()>SNAKE_HEAD_LEFT)
if(snakenode->getBoundingBox().containsPoint(point))
return true;
}
return false;
}
接下来我们要在屏幕上放置球了,要求球的位置不能被放在蛇的身上,下面的代码得到一个随机的位置及球
void GameLayer::setBall(){
if(ball==NULL){
ball=Sprite::create();
this->addChild(ball,1);
}
vector<Point> tmpList;
for(int i=1;i<SCREEN_WIDTH/SNAKE_WIDTH-1;i++)
for(int j=1;j<SCREEN_HEIGHT/SNAKE_WIDTH-1;j++){
Point point(i*SNAKE_WIDTH,j*SNAKE_WIDTH);
if(!this->IsSnakeContainsBall(point))
tmpList.push_back(point);
}
int tmpListSize=tmpList.size();
if(tmpListSize>0){
int tmp=CCRANDOM_0_1()*(tmpListSize-1);
ball->setPosition(tmpList.x,tmpList.y);
String str;
tmp=CCRANDOM_0_1()*3;
switch (tmp){
case 0:
str="football.png";
break;
case 1:
str="Volleyball.png";
break;
case 2:
str="basketball.png";
break;
}
ball->setSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(str._string));
}
}
下面的代码是通过头部的buildingbox是否包含球的坐标点来判断是否吃到球
bool GameLayer::IsEatBall(){
if(snake->getSnakeNodes().front()->boundingBox().containsPoint(ball->getPosition())){
score++;
return true;}
return false;
}
贪吃蛇的主要部分就完成了,计分,难度设置,死亡动画,声效可自行添加