首页 > 代码库 > 编写小游戏《贪头蛇》第三篇

编写小游戏《贪头蛇》第三篇

源码下载地址:http://download.csdn.net/detail/oyangyufu/7492917

点击NEW GAME按钮,进入游戏主场景


代码:

游戏背景

layer = (CCLayer*)this->getChildren()->objectAtIndex(SnakeConstants::LAYER_BACKGROUND);
		layer->setTouchEnabled(false);

		//游戏背景
		CCSize size = CCDirector::sharedDirector()->getWinSize();
		CCTMXTiledMap *pTMXTiledMap = CCTMXTiledMap::create("map.tmx");    
		pTMXTiledMap->setAnchorPoint( ccp(0.5f, 0.5f) );  
		pTMXTiledMap->setPosition(ccp(size.width/2 , size.height/2));  
		layer->addChild(pTMXTiledMap);  

退出键

		layer = (CCLayer*)this->getChildren()->objectAtIndex(SnakeConstants::LAYER_UI);
		CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
			"CloseNormal.png",
			"CloseSelected.png",
			this,
			menu_selector(SnakeScene::menuCloseCallback));
		CC_BREAK_IF(! pCloseItem);
		pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));

		CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
		pMenu->setPosition(CCPointZero);
		CC_BREAK_IF(! pMenu);
		layer->addChild(pMenu);

4个方向键:

		CCMenuItemImage* pUpImage = CCMenuItemImage::create("u1.png", "u2.png", this, menu_selector(SnakeScene::upCallBack));
		pUpImage->setAnchorPoint(ccp(0.5, 0));
		pUpImage->setPositionY(6.0f);

		CCMenuItemImage* pDownImage = CCMenuItemImage::create("d1.png", "d2.png", this, menu_selector(SnakeScene::downCallBack));
		pDownImage->setAnchorPoint(ccp(0.5, 1));
		pDownImage->setPositionY(-6.0f);

		CCMenuItemImage* pLeftImage = CCMenuItemImage::create("b1.png", "b2.png", this, menu_selector(SnakeScene::leftCallBack));
		pLeftImage->setAnchorPoint(ccp(1, 0.5));
		pLeftImage->setPositionX(-6.0f);

		CCMenuItemImage* pRightImage = CCMenuItemImage::create("f1.png", "f2.png", this, menu_selector(SnakeScene::rightCallBack));
		pRightImage->setAnchorPoint(ccp(0, 0.5));
		pRightImage->setPositionX(6.0f);

		CCMenu* ArrowMenu = CCMenu::create(pUpImage, pDownImage, pLeftImage, pRightImage, NULL);
		ArrowMenu->setPosition(50, 50);
		layer->addChild(ArrowMenu);

游戏分数:

		mScoreText = CCLabelTTF::create("Score: 0", "Plok.ttf", 20);
		mScoreText->setPosition(ccp(0, size.height - 10));
		mScoreText->setAnchorPoint(ccp(0, 0.5));
		layer->addChild(mScoreText);
游戏开始语

		mTitleText = CCLabelTTF::create("Play Game Snake!", "Plok.ttf", 30);
		mTitleText->setPosition(ccp(size.width/2, size.height/2));
		layer->addChild(mTitleText);
		mTitleText->setScale(0.0f);

游戏结束语

		mGameOverText = new CCLabelTTF();
		mGameOverText->initWithString("Game Over!", "Plok.ttf", 30);
		mGameOverText->setPosition(ccp(size.width/2, size.height/2));
		mGameOverText->retain();
		mGameOverText->autorelease();

两个定时器

		schedule(schedule_selector(SnakeScene::ScheduleTick1), 0.4f); //播放游戏开始语
		schedule(schedule_selector(SnakeScene::GameCircle), 0.5f); //判断游戏是否结束

//游戏开始语
void SnakeScene::ScheduleTick1( float dt )
{
	float scale = mTitleText->getScale();
	if(scale < 0.8)//从0倍缩放到0.8倍
	{
		mTitleText->setScale(scale+0.1);
	}
	else //删除游戏开始语
	{
		CCLayer* layer = (CCLayer*)this->getChildren()->objectAtIndex(SnakeConstants::LAYER_UI);
		unschedule(schedule_selector(SnakeScene::ScheduleTick1));
		layer->removeChild(mTitleText);

		m_bGameRunning = true;//开始运行游戏
	}
}

0.5秒蛇移动一次

void SnakeScene::GameCircle( float dt )
{
	if(m_bGameRunning) 
	{
		if(!mSnake->Move())//0结束
		{
			OnGameOver();
		}

		HandleNewSnakePosition();
	}
}

蛇的称动及碰撞检测

boolean Snake::Move()
{
	mLastMoveDirection = mDirection;

	if(m_bGrow) 
	{
		m_bGrow = false;
		/* If the snake should grow,
		* simply add a new part in the front of the tail,
		* where the head currently is. */
		SnakeTailPart* newTailPart = new SnakeTailPart(m_pSnakeHead);//每一节
		newTailPart->setScale(0.6f);
		this->addChild(newTailPart);
		marrTail.insertObject(newTailPart, 0);//marrTail管理整条蛇 
	} 
	else 
	{

		if(marrTail.count() > 0)
		{
			/* First move the end of the tail to where the head currently is. */
			SnakeTailPart* tailEnd = (SnakeTailPart*)marrTail.lastObject();
			marrTail.removeLastObject(false);
			tailEnd->SetCell(*m_pSnakeHead);

			marrTail.insertObject(tailEnd, 0);
		}

	}

	/* The move the head into the direction of the snake. 重设蛇头的位置*/
	m_pSnakeHead->SetCell(GetNextX(), GetNextY());
	//检查蛇头跟蛇尾相撞
	for(int i = marrTail.count() - 1; i >= 0; i--) 
	{
		if(m_pSnakeHead->IsInSameCell(*(SnakeTailPart*)marrTail.objectAtIndex(i)))
		{
			return false;
		}
	}

	return true;
}
创建蛇与青蛙

		//主角蛇
		mSnake = new Snake(RIGHT, 0, SnakeConstants::CELLS_VERTICAL/2);
		mSnake->autorelease();
		mSnake->GetHead()->Animate(1);
		mSnake->Grow();
		layer = (CCLayer*)this->getChildren()->objectAtIndex(SnakeConstants::LAYER_SNAKE);
		layer->addChild(mSnake);

		//青蛙
		mFrog = new Frog(0, 0);
		mFrog->autorelease();
		mFrog->Animate(1);
		this->SetFrogToRandomCell();//随机出现一个青蛙
		layer = (CCLayer*)this->getChildren()->objectAtIndex(SnakeConstants::LAYER_FOOD);
		layer->addChild(mFrog);

检测蛇是否吃了青蛙

void SnakeScene::HandleNewSnakePosition()
{
	const SnakeHead* snakeHead = mSnake->GetHead();

	if(snakeHead->GetCellX() < 0 || snakeHead->GetCellX() >= SnakeConstants::CELLS_HORIZON 
		|| snakeHead->GetCellY() < 0 || snakeHead->GetCellY() >= SnakeConstants::CELLS_VERTICAL) //蛇活动的区域
	{
		OnGameOver();
	}
	else if(snakeHead->IsInSameCell(*mFrog))//蛇吃了青蛙加分、显示下一个青蛙
	{
		m_nScore += 50;

		char score[128] = {0};
		sprintf(score, "Score: %d", m_nScore);
		mScoreText->setString(score);

		mSnake->Grow();
		PlayMunchSound();//吃到的声音
		this->SetFrogToRandomCell();//随机显示下一个青蛙

方向键回调函数,根据上下左右键方向旋转蛇的方向

void SnakeScene::upCallBack( CCObject* sender )
{
	mSnake->SetDirection(UP);
}

void SnakeScene::downCallBack( CCObject* sender )
{
	mSnake->SetDirection(DOWN);
}

void SnakeScene::leftCallBack( CCObject* sender )
{
	mSnake->SetDirection(LEFT);
}

void SnakeScene::rightCallBack( CCObject* sender )
{
	mSnake->SetDirection(RIGHT);
void Snake::SetDirection( const Direction dirction )
{
	if(mLastMoveDirection != Opposite(dirction)) 
	{
		mDirection = dirction;
		m_pSnakeHead->SetRotation(dirction);
	}
}
蛇的方向度

void SnakeHead::SetRotation(const Direction dirction)
{
	switch(dirction) 
	{
	case UP:
		this->setRotation(180);
		break;
	case DOWN:
		this->setRotation(0);
		break;
	case LEFT:
		this->setRotation(90);
		break;
	case RIGHT:
		this->setRotation(270);
		break;
	}
}