1. 程式人生 > >分享一個完整程式的程式碼(消除類遊戲)

分享一個完整程式的程式碼(消除類遊戲)

AppDelegate.cpp

#include "AppDelegate.h"
#include"WelcomeScene.h"
#include "SimpleAudioEngine.h"//聲音管理類
using namespace CocosDenshion;//聲音類處於該名稱空間中
USING_NS_CC;


AppDelegate::AppDelegate() {


}


AppDelegate::~AppDelegate() 
{
}


//if you want a different context,just modify the value of glContextAttrs
//it will takes effect on all platforms
void AppDelegate::initGLContextAttrs()
{
    //set OpenGL context attributions,now can only set six attributions:
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};


    GLView::setGLContextAttrs(glContextAttrs);
}


bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
<span style="white-space:pre">	</span>if (!glview)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>glview = GLViewImpl::create("Halloween");
<span style="white-space:pre">		</span>director->setOpenGLView(glview);
<span style="white-space:pre">		</span>glview->setFrameSize(360, 600);<span style="white-space:pre">	</span>//設定螢幕大小
<span style="white-space:pre">	</span>}
    director->getOpenGLView()->setDesignResolutionSize(360, 600, ResolutionPolicy::EXACT_FIT);//適配策略,適應螢幕
<span style="white-space:pre">	</span>




    // turn on display FPS
   /* director->setDisplayStats(true);


    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);
<span style="white-space:pre">	</span>*/
    FileUtils::getInstance()->addSearchPath("res");


    // create a scene. it's an autorelease object
    auto scene = WelcomeScene::createScene();


    // run
    director->runWithScene(scene);


    return true;
}


// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();


    // if you use SimpleAudioEngine, it must be pause
     SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
<span style="white-space:pre">	</span> 
}


// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();


    // if you use SimpleAudioEngine, it must resume here
     SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

Define.h

#pragma once
#define Screen_Width 360
#define Screen_Height 600
#define TOTAL_SPRITE 6

#define ROW 10
#define COL 6

#define SpriteWideth 48
#define BorderWideth 5
static const char * spriteNormal[10] =
{
	"1.png",
	"2.png",
	"3.png",
	"4.png",
	"5.png",
	"6.png",
	"7.png",
	"8.png",
	"9.png",
	"10.png",
};

GameScene.h
#pragma once
#include"cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
#include"Define.h"
#include"SpriteShape.h"
USING_NS_CC;
class GameScene :public cocos2d::Layer
{
public:
	static Scene * createScene();
	virtual bool init();
	virtual void onBackItemCallback(Ref * pSender);

	void initMap();
	void createSprite(int r, int c);
	Vec2 PositionOfItem(int r, int c);
	void update(float dt);
	void checkAndRemoveSprite();
	void getColChain(SpriteShape * spr, std::list<SpriteShape*>&chainList);
	void getRowChain(SpriteShape * spr, std::list<SpriteShape*>&chainList);
	void SpriteRemoveAction(SpriteShape *spr);
	void markRemove(SpriteShape* spr);
	void removeSprite();
	void FillSprite();
	bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* evt);
	void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* evt);
	SpriteShape *spriteOfPoint(Vec2 *position);
	void swapSprite();
	void MyClock(float dr);
	void gameOverCallback(Node *node);
	CREATE_FUNC(GameScene);
private:
	SpriteShape * map[ROW][COL];
	bool isAction;//表示是否正在執行動作
	bool isFillSprite;//表示是否需要進行填充操作
	bool isTouchEnable;
	bool isGameOver;
	SpriteShape *startShape;
	SpriteShape* endShape;
	int m_score;
	int m_time;

};
GameScene.cpp
#include"cocos2d.h"
#include"GameScene.h"
#include"WelcomeScene.h"
#include"SpriteShape.h"
#include"Define.h"
#include"SetScene.h"
#include "SimpleAudioEngine.h"//聲音管理類
#pragma execution_character_set("utf-8")
using namespace CocosDenshion;//聲音類處於該名稱空間中
USING_NS_CC;

Scene* GameScene::createScene()
{
	auto scene = Scene::create();
	auto layer = GameScene::create();
	scene->addChild(layer);
	return scene;
}
bool GameScene::init()
{
	if (!Layer::init())
	{
		return false;
	}
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("res/sucai.plist");
	//設定背景圖片
	auto pDirector = Director::getInstance();
	auto pSprite = Sprite::create("res/GameBackground.png");
	pSprite->setPosition(Vec2(Screen_Width / 2, Screen_Height / 2));	//通過巨集定義,保證圖片在螢幕中間
	this->addChild(pSprite);
	//設定返回按鈕
	auto setItem = MenuItemImage::create("res/back1.png", "res/back2.png", CC_CALLBACK_1(GameScene::onBackItemCallback, this));
	setItem->setPosition(Vec2(Screen_Width / 2 , Screen_Height / 8-30));
	auto menu = Menu::create(setItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);
	//監聽移動觸控事件
	this->scheduleUpdate();
	auto touchListener = EventListenerTouchOneByOne::create();
	touchListener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
	touchListener->onTouchMoved = CC_CALLBACK_2(GameScene::onTouchMoved, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
	//_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener->clone(), this);

	isAction = false;
	isFillSprite = false;
	isTouchEnable = true;
	isGameOver = false;
	m_score = 0;
	m_time = 60;
	initMap();//初始化地圖
	//建立分數字體
	auto ptextScore = ui::Text::create(StringUtils::format("Score:  %d",0), "res/marry.ttf", 25);
	ptextScore->setTag(10);//因為下面需要在update中訪問,所以通過tag訪問
	ptextScore->setPosition(Vec2(Screen_Width/4,Screen_Height-20));
	this->addChild(ptextScore);

	auto ptextTime = ui::Text::create(StringUtils::format("Time: %d", 0), "res/marry.ttf", 25);
	ptextTime->setTag(11);//因為下面需要在update中訪問,所以通過tag訪問
	ptextTime->setPosition(Vec2(Screen_Width / 4*3, Screen_Height - 20));
	this->addChild(ptextTime);

	if (SetScene::isMusicPlay)
		SimpleAudioEngine::getInstance()->playBackgroundMusic("res/GameBackGround.wav", true);

	auto pParticle = ParticleSnow::create();
	this->addChild(pParticle);

	schedule(schedule_selector(GameScene::MyClock),1.0f);//新增控制時間倒計時的定時器
	return true;
}
bool GameScene::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* evt)
{
	startShape = NULL;
	endShape = NULL;
	if (isTouchEnable)
	{
		auto pos = touch->getLocation();
		if (pos.x > 327 || pos.x < 39 || pos.y>519 || pos.y < 69)//如果點選在外面,則不做任何操作
			return false;
		startShape = spriteOfPoint(&pos);
		if (startShape->getImgIndex() == 8)//如果是那隻豬,就消除整行
		{
			Vec2 mapPos = PositionOfItem(startShape->getRow(), startShape->getCol());//得到它在地圖中的位置
			auto pParticle = ParticleSystemQuad::create("res/leftrow.plist");
			pParticle->setPosition(mapPos);
			this->addChild(pParticle);
			pParticle = ParticleSystemQuad::create("res/rightrow.plist");
			pParticle->setPosition(mapPos);
			this->addChild(pParticle);

			int row = startShape->getRow();
			for (int c = 0; c < COL; c++)
				markRemove(map[row][c]);
			removeSprite();
		}
	}
	return isTouchEnable;
}
//實時判定移動的位置是否可以交換位置
void GameScene::onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* evt)
{
	if (!startShape || !isTouchEnable)
		return;
	int row = startShape->getRow();
	int col = startShape->getCol();
	auto pos = touch->getLocation();
	auto halfSpriteWideth = SpriteWideth / 2;
	auto halfSpriteHeight = SpriteWideth / 2;
	//判定是否向上移動到了上方的那個糖果中
	auto upRect = Rect(startShape->getPositionX() - halfSpriteWideth,
		startShape->getPositionY() + halfSpriteHeight + BorderWideth,
		SpriteWideth, SpriteWideth);
	if (upRect.containsPoint(pos))
	{
		++row;
		if (row < ROW)
		{
			endShape = map[row][col];
		}
		swapSprite();
		return;
	}
	//判定是否向xia移動到了下方的那個糖果中
	auto downRect = Rect(startShape->getPositionX() - halfSpriteWideth, 
		startShape->getPositionY() - halfSpriteHeight*3 - BorderWideth,
		SpriteWideth, SpriteWideth);
	if (downRect.containsPoint(pos))
	{
		--row;
		if (row >=0)
		{
			endShape = map[row][col];
		}
		swapSprite();
		return;
	}
	//判定是否向zuo移動到了上方的那個糖果中
	auto leftRect = Rect(startShape->getPositionX() - halfSpriteWideth*3-BorderWideth,
		startShape->getPositionY() - halfSpriteHeight,
		SpriteWideth, SpriteWideth);
	if (leftRect.containsPoint(pos))
	{
		col--;
		if (col >= 0)
		{
			endShape = map[row][col];
		}
		swapSprite();
		return;
	}
	//判定是否向右移動到了右方的那個糖果中
	auto rightRect = Rect(startShape->getPositionX() + halfSpriteWideth+BorderWideth,
		startShape->getPositionY() - halfSpriteHeight,
		SpriteWideth, SpriteWideth);
	if (rightRect.containsPoint(pos))
	{
		++col;
		if (col < COL)
		{
			endShape = map[row][col];
		}
		swapSprite();
		return;
	}
}
void GameScene::swapSprite()
{
//	isAction = true;
	isFillSprite = false;
	isTouchEnable = false;
	if (!startShape || !endShape)
		return;
	Vec2 posOfScr = startShape->getPosition();
	Vec2 posOfDes = endShape->getPosition();
	float time = 0.2;

	//交換開始位置跟結束位置
	SpriteShape * temp=new SpriteShape();
	/*map[startShape->getRow()][startShape->getCol()] = endShape;
	map[endShape->getRow()][endShape->getCol()] = startShape;*/
	temp = map[startShape->getRow()][startShape->getCol()];
	map[startShape->getRow()][startShape->getCol()] = map[endShape->getRow()][endShape->getCol()];
	map[endShape->getRow()][endShape->getCol()] = temp;

	int tempRow = startShape->getRow();
	int tempCol = startShape->getCol();
	startShape->setRow(endShape->getRow());
	startShape->setCol(endShape->getCol());
	endShape->setRow(tempRow);
	endShape->setCol(tempCol);

	//判斷移動後的開始和結束兩個精靈是否可以有消除的
	std::list<SpriteShape *>colChainListOfFirst;
	getColChain(startShape, colChainListOfFirst);
	std::list<SpriteShape *>rowChainListOfFirst;
	getRowChain(startShape, rowChainListOfFirst);
	std::list<SpriteShape *>colChainListOfSecond;
	getColChain(endShape, colChainListOfSecond);
	std::list<SpriteShape *>rowChainListOfSecond;
	getRowChain(endShape, rowChainListOfSecond);

	if (colChainListOfFirst.size() >= 3
		|| rowChainListOfFirst.size() >= 3
		|| colChainListOfSecond.size() >= 3
		|| rowChainListOfSecond.size() >= 3
		)
	{
		//可以消除,進行移動
		startShape->runAction(MoveTo::create(time, posOfDes));
		endShape->runAction(MoveTo::create(time, posOfScr));
		return;
	}
	//不可移除的話就還移回來
	else {
		map[startShape->getRow()][startShape->getCol()] = endShape;
		map[endShape->getRow()][endShape->getCol()] = startShape;

		tempRow = startShape->getRow();
		tempCol = startShape->getCol();
		startShape->setRow(endShape->getRow());
		startShape->setCol(endShape->getCol());
		endShape->setRow(tempRow);
		endShape->setCol(tempCol);
		//startShape->runAction(Sequence::create(MoveTo::create(time, posOfDes), MoveTo::create(time, posOfScr),nullptr));
		//endShape->runAction(Sequence::create(MoveTo::create(time, posOfScr), MoveTo::create(time, posOfDes), nullptr));
		return;
	}
}
SpriteShape *GameScene::spriteOfPoint(Vec2 *position)//獲得當前位置的糖果
{
	SpriteShape *spr = NULL;
	Rect rect = Rect(0, 0, 0, 0);
	Size sz;
	sz.height = SpriteWideth;
	sz.width = SpriteWideth;
	for (int r = 0; r < ROW; r++)
		for (int c = 0; c < COL; c++)
		{
			spr = map[r][c];
			if (spr)
			{
				rect.origin.x = spr->getPositionX() - (SpriteWideth / 2);
				rect.origin.y = spr->getPositionY() - (SpriteWideth / 2);
				rect.size = sz;
				if (rect.containsPoint(*position))
				{
					return spr;
				}
			}
		}
}
void GameScene::initMap()
{
	for (int r = 0; r < ROW; r++)
		for (int c = 0; c < COL; c++)
			createSprite(r, c);
}
void GameScene::createSprite(int r, int c)
{
	isAction = true;
	isTouchEnable = false;
	SpriteShape * spr = SpriteShape::create(r, c);
	Vec2 endPosition = PositionOfItem(r, c);
	Vec2 startPosition = Vec2(endPosition.x, endPosition.y + Screen_Height / 2);
	spr->setPosition(startPosition);
	float speed = startPosition.y / (1.2*Screen_Height);
	spr->runAction(MoveTo::create(speed, endPosition));//通過一個動畫進行下落動作
	this->addChild(spr);
	map[r][c] = spr;
}
//每幀呼叫是否有可以消除的
void GameScene::update(float dr)
{
	if (isAction)
	{
		isAction = false;
		for (int r = 0; r < ROW; r++)
			for (int c = 0; c < COL; c++)
			{
				SpriteShape *spr = map[r][c];
				//int index = spr->getImgIndex();
			//	if (spr->getImgIndex()==8)
			//	{
				//	auto pParticle = ParticleSystemQuad::create("res/fire.plist");
				//	pParticle->setPosition(PositionOfItem(r, c));
				//	addChild(pParticle);
				//}
				if (spr&&spr->getNumberOfRunningActions()>0)//如果正在執行動作,就不執行消除的判定
				{
					isAction = true;
					isTouchEnable = false;
				}

			}
	}
	if (!isAction)
	{
		isTouchEnable = true;
		if (isFillSprite)
		{
			if(!isGameOver)
				FillSprite();
			isFillSprite = false;
		}
		else
			checkAndRemoveSprite();
	}
	auto pscore = (ui::Text*)this->getChildByTag(10);
	pscore->setString(StringUtils::format("Score:  %d", m_score));
}
void GameScene::MyClock(float dr)
{
	m_time--;
	if (m_time >=0)
	{
		auto ptime = (ui::Text*)this->getChildByTag(11);
		ptime->setString(StringUtils::format("Time:  %d", m_time));
	}
	if (m_time == 10)
		SimpleAudioEngine::getInstance()->playEffect("res/daojishi.wav");
	if (m_time == 0)
	{
		//遊戲結束
		SimpleAudioEngine::getInstance()->pauseAllEffects();
		SimpleAudioEngine::getInstance()->playEffect("res/timeover.wav");
		auto overSprite = Sprite::create("res/GameOver.png");
		overSprite->setPosition(Vec2(Screen_Width / 2 + 10, Screen_Height - 20));
		overSprite->runAction(Sequence::create(MoveTo::create(3.0f, Vec2(Screen_Width / 2 + 10, Screen_Height / 2)),
			CallFuncN::create(CC_CALLBACK_1(GameScene::gameOverCallback, this)), nullptr));
		this->addChild(overSprite, 1);
		isTouchEnable = false;

		for (int r = 0; r < ROW; r++)
			for (int c = 0; c < COL; c++)
			{
				markRemove(map[r][c]);
			}
		removeSprite();
		isGameOver = true;
	
	}

}
void GameScene::gameOverCallback(Node *node)
{
	auto pDirector = Director::getInstance();
	auto scene = WelcomeScene::createScene();
	TransitionSplitCols * ptrans = TransitionSplitCols::create(1.0f, scene);//設定切換場景的方式,書本 P25
	pDirector->replaceScene(ptrans);	//切換場景
}
void GameScene::FillSprite()
{
	int colRemoveNumber[10] = { 0 };
	SpriteShape *spr = NULL;
	for (int c = 0; c < COL; c++)
	{
		int removeSpriteOfCol = 0;
		for (int r = 0; r < ROW; r++)//從下往上遍歷
		{
			spr = map[r][c];
			if (spr == NULL)
				removeSpriteOfCol++;
			else
			{
				if (removeSpriteOfCol > 0)
				{
					//從上往下落
					int newRow = r - removeSpriteOfCol;//比如有兩個空的,原本第5行的就要到3行去
					map[newRow][c] = spr;
					map[r][c] = NULL;
					Vec2 startPostion = spr->getPosition();
					Vec2 endPosition = PositionOfItem(newRow, c);
					float speed = (startPostion.y - endPosition.y) / Screen_Height * 3;
					spr->stopAllActions();
					spr->runAction(MoveTo::create(speed, endPosition));
					spr->setRow(newRow);
				}

			}
		}
		colRemoveNumber[c] = removeSpriteOfCol;//記錄下每一列的空行數
	}
	for (int c = 0; c < COL; c++)	//填充頂部的空的部分
	{
		for (int r = ROW - colRemoveNumber[c]; r < ROW; r++)
		{
			createSprite(r, c);
		}
	}
}
void GameScene::checkAndRemoveSprite()//判定是否有可以移除的糖果
{
	SpriteShape *spr = new SpriteShape();
	for (int r = 0; r < ROW; r++)
		for (int c = 0; c < COL; c++)
		{
			spr = map[r][c];
			if (!spr)
				continue;
			//如果糖果已經被標記為需要被移除,則不需要進行判定
			if (spr->getIsNeedRemove())
				continue;
			//先遍歷上下相鄰的糖果,把相同的糖果放到一個list中
			std::list<SpriteShape*>colChainList;
			getColChain(spr, colChainList);

			if (colChainList.size() >= 3)//如果相同的大於等於3
			{
				std::list<SpriteShape*>::iterator it;
				for (it = colChainList.begin(); it != colChainList.end(); it++)
				{
					spr = (SpriteShape*)*it;
					if (!spr)
						continue;
					markRemove(spr);
				}
			}
		}

	for (int c = 0; c < COL; c++)
		for (int r = 0; r < ROW; r++)
		{
			spr = map[r][c];
			if (!spr)
				continue;
			if (spr->getIsNeedRemove())
				continue;
			std::list<SpriteShape*>RowChainList;
			getRowChain(spr, RowChainList);
			//取更長的那個
		//	std::list<SpriteShape*>&longerList = colChainList.size()>RowChainList.size() ? colChainList : RowChainList;
			//if (longerList.size() < 3)
			//	continue;

			if (RowChainList.size() >= 3)//如果相同的大於等於3
			{
				std::list<SpriteShape*>::iterator rowit;
				for (rowit = RowChainList.begin(); rowit != RowChainList.end(); rowit++)
				{
					spr = (SpriteShape*)*rowit;
					if (!spr)
						continue;
					markRemove(spr);
				}
			}
		}
	removeSprite();
}
void GameScene::getColChain(SpriteShape * spr, std::list<SpriteShape*>&chainList)//判斷列
{
	chainList.push_back(spr);
	//向下查詢
	int neiborRow = spr->getRow() - 1;
	while (neiborRow >= 0)
	{
		SpriteShape * neiborSprite = map[neiborRow][spr->getCol()];
		if (neiborSprite&&neiborSprite->getImgIndex() == spr->getImgIndex() && !neiborSprite->getIsNeedRemove())
		{
			chainList.push_back(neiborSprite);
			neiborRow--;
		}
		else
			break;
	}
	//向上
	neiborRow = spr->getRow() + 1;
	while (neiborRow <ROW)
	{
		SpriteShape * neiborSprite = map[neiborRow][spr->getCol()];
		if (neiborSprite&&neiborSprite->getImgIndex() == spr->getImgIndex() && !neiborSprite->getIsNeedRemove())
		{
			chainList.push_back(neiborSprite);
			neiborRow++;
		}
		else
			break;
	}

}
void GameScene::getRowChain(SpriteShape * spr, std::list<SpriteShape*>&chainList)//判斷行
{
	chainList.push_back(spr);
	//向左
	int neiborCol = spr->getCol() - 1;
	while (neiborCol >= 0)
	{
		SpriteShape * neiborSprite = map[spr->getRow()][neiborCol];
		if (neiborSprite&&neiborSprite->getImgIndex() == spr->getImgIndex() && !neiborSprite->getIsNeedRemove())
		{
			chainList.push_back(neiborSprite);
			neiborCol--;
		}
		else
			break;
	}
	//向右
	neiborCol = spr->getCol() + 1;
	while (neiborCol < COL)
	{
		SpriteShape * neiborSprite = map[spr->getRow()][neiborCol];
		if (neiborSprite&&neiborSprite->getImgIndex() == spr->getImgIndex() && !neiborSprite->getIsNeedRemove())
		{
			chainList.push_back(neiborSprite);
			neiborCol++;
		}
		else
			break;
	}
}

void GameScene::markRemove(SpriteShape* spr)
{
	if (spr->getIsNeedRemove())
		return;
	spr->setIsNeedRemove(true);
}

void GameScene::removeSprite()
{
	SpriteShape *spr = new SpriteShape();
	for (int r = 0; r < ROW; r++)
		for (int c = 0; c < COL; c++)
		{
			spr = map[r][c];
			if (!spr)
				continue;
			if (spr->getIsNeedRemove())
			{
				SpriteRemoveAction(spr);
				map[r][c] = NULL;
			}
		}

}
void GameScene::SpriteRemoveAction(SpriteShape *spr)//精靈消失的動畫
{
	if(SetScene::isEffectPlay)
		SimpleAudioEngine::getInstance()->playEffect("res/xiaochu.mp3");
	m_score += 30;
	isAction = true;
	isTouchEnable = false;
	auto pFadeIn = FadeOut::create(0.6);
	auto pRotateBy = RotateBy::create(0.6f, 180);//順時針旋轉30°,同樣也有RotateTo版本
	auto pScaleBy = ScaleBy::create(0.6f, 0.5f);
	spr->runAction(Spawn::create(pFadeIn, pRotateBy, pScaleBy, nullptr));
	if (!isAction)
		spr->removeFromParent();
	isFillSprite = true;
}


Vec2 GameScene::PositionOfItem(int r,int c)	//一個小的精靈在地圖中顯示的位置
{
	float x = (c + 1) * SpriteWideth + BorderWideth+10;
	float y = (r + 1) * SpriteWideth + BorderWideth+40;
	return  Vec2(x, y);
}
//返回到主介面按鈕的回撥函式

void GameScene::onBackItemCallback(Ref * pSender)
{
	auto pDirector = Director::getInstance();
	auto scene = WelcomeScene::createScene();
	TransitionSplitCols * ptrans = TransitionSplitCols::create(1.0f, scene);//設定切換場景的方式,書本 P25
	pDirector->replaceScene(ptrans);	//切換場景
	//SimpleAudioEngine::getInstance()->stopBackgroundMusic();
}

SetScene.h
#pragma once
#include"cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
class SetScene :public cocos2d::Layer
{
public:
	
	static cocos2d::Scene * createScene();
	virtual bool init();
	void onOpenMusicCallback(Ref * pSender);
	void onCloseMusicCallback(Ref * pSender);
	void onOpenEffectCallback(Ref * pSender);
	void onCloseEffectCallback(Ref * pSender);
	void onBackItemCallback(Ref * pSender);
	static bool isEffectPlay;
	static bool isMusicPlay;
	CREATE_FUNC(SetScene);

};

SetScene.cpp
#include"cocos2d.h"
#include"SetScene.h"
#include"Define.h"
#include"WelcomeScene.h"
#include "SimpleAudioEngine.h"//聲音管理類
using namespace CocosDenshion;//聲音類處於該名稱空間中
USING_NS_CC;
bool SetScene::isEffectPlay = true;
bool SetScene::isMusicPlay = true;
Scene* SetScene::createScene()
{
	auto scene = Scene::create();
	auto layer = SetScene::create();
	scene->addChild(layer);
	return scene;
}
bool SetScene::init()
{
	if (!Layer::init())
	{
		return false;
	}
	cocos2d::Menu *menu;
	auto pDirector = Director::getInstance();
	auto pSprite = Sprite::create("res/Set.png");
	pSprite->setPosition(Vec2(Screen_Width / 2, Screen_Height / 2));	//通過巨集定義,保證圖片在螢幕中間
	this->addChild(pSprite);
	//新增開啟音樂按鈕
	auto openMusicItem = MenuItemImage::create("res/openMusic.png", "res/openMusic2.png", CC_CALLBACK_1(SetScene::onOpenMusicCallback, this));
	openMusicItem->setPosition(Vec2(Screen_Width / 3 -20, Screen_Height / 3*2));
	menu = Menu::create(openMusicItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);

	//新增關閉音樂按鈕
	auto closeMusicItem = MenuItemImage::create("res/closeMusic.png", "res/closeMusic2.png", CC_CALLBACK_1(SetScene::onCloseMusicCallback, this));
	closeMusicItem->setPosition(Vec2(Screen_Width /3*2+20 , Screen_Height / 3*2));
	menu = Menu::create(closeMusicItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);
	//開啟音效
	auto openEffectItem = MenuItemImage::create("res/openEffect.png", "res/openEffect2.png", CC_CALLBACK_1(SetScene::onOpenEffectCallback, this));
	openEffectItem->setPosition(Vec2(Screen_Width / 3-20 , Screen_Height / 3));
	menu = Menu::create(openEffectItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);
	//關閉音效
	auto closeEffectItem = MenuItemImage::create("res/closeEffect.png", "res/closeEffect2.png", CC_CALLBACK_1(SetScene::onCloseEffectCallback, this));
	closeEffectItem->setPosition(Vec2(Screen_Width / 3*2+20, Screen_Height / 3));
	menu = Menu::create(closeEffectItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);

	//設定返回按鈕
	auto bakcItem = MenuItemImage::create("res/back1.png", "res/back2.png", CC_CALLBACK_1(SetScene::onBackItemCallback, this));
	bakcItem->setPosition(Vec2(Screen_Width / 2 + 10, Screen_Height / 8 - 30));
	menu = Menu::create(bakcItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);

	return true;
}
void SetScene::onOpenMusicCallback(Ref * pSender)
{
	SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
	isMusicPlay = true;
}
void SetScene::onCloseMusicCallback(Ref * pSender)
{	
	SimpleAudioEngine::getInstance()->stopBackgroundMusic();
	isMusicPlay = false;
}
void SetScene::onOpenEffectCallback(Ref * pSender)
{
	isEffectPlay = true;
}
void SetScene::onCloseEffectCallback(Ref * pSender)
{
	isEffectPlay = false;
}
void SetScene::onBackItemCallback(Ref * pSender)
{
	auto pDirector = Director::getInstance();
	auto scene = WelcomeScene::createScene();
	TransitionTurnOffTiles * ptrans = TransitionTurnOffTiles::create(1.0f, scene);//設定切換場景的方式,書本 P25
	pDirector->replaceScene(ptrans);	//切換場景
										//SimpleAudioEngine::getInstance()->stopBackgroundMusic();
}


SpriteShape.h
#pragma once
#include"cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
class SpriteShape :public cocos2d::Sprite
{
public:
	SpriteShape();
	static SpriteShape * create(int row, int col);
	CC_SYNTHESIZE(int, m_row, Row);
	CC_SYNTHESIZE(int, m_col, Col);
	CC_SYNTHESIZE(int, m_imgIndex, ImgIndex);
	CC_SYNTHESIZE(bool, m_isNeedRemove, IsNeedRemove);
	CREATE_FUNC(SpriteShape);

};
SpriteShape.cpp
#include"cocos2d.h"
#include"SpriteShape.h"
#include"Define.h"
USING_NS_CC;
SpriteShape::SpriteShape() :m_isNeedRemove(false)
{

}
SpriteShape* SpriteShape::create(int row, int col)
{
	SpriteShape *spr = new SpriteShape();
	int randNum = rand() % 20;
	spr->m_row = row;
	spr->m_col = col;
	if (randNum == 0)//20分之1的概率出現那隻豬
	{
		spr->m_imgIndex = 8;
		spr->initWithSpriteFrameName(spriteNormal[8]);
	}
	else
	{
		spr->m_imgIndex = rand() % TOTAL_SPRITE;//10
		spr->initWithSpriteFrameName(spriteNormal[spr->m_imgIndex]);	//通過index載入圖片
	}
	spr->m_isNeedRemove = false;
	spr->setRow(row);
	spr->setCol(col);
	spr->autorelease();
	return spr;
}

WelcomeScene.h
#pragma once
#include"cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
class WelcomeScene:public cocos2d::Layer
{
public:
	static cocos2d::Scene * createScene();
	virtual bool init();
	virtual void onStartItemCallback(Ref * pSender);
	virtual void onExitItemCallback(Ref * pSender);
	virtual void onSetItemCallback(Ref * pSender);
	CREATE_FUNC(WelcomeScene);

};

WelcomeScene.cpp
#include"cocos2d.h"
#include"WelcomeScene.h"
#include"GameScene.h"
#include"Define.h"
#include "SimpleAudioEngine.h"//聲音管理類
#include"SetScene.h"
using namespace CocosDenshion;//聲音類處於該名稱空間中
USING_NS_CC;

Scene* WelcomeScene::createScene()
{
	auto scene = Scene::create();
	auto layer = WelcomeScene::create();
	scene->addChild(layer);
	return scene;
}
bool WelcomeScene::init()
{
	if (!Layer::init())
	{
		return false;
	}
	cocos2d::Menu *menu;
	auto pDirector = Director::getInstance();
	auto pSprite = Sprite::create("res/Welcome.png");
	pSprite->setPosition(Vec2(Screen_Width/2,Screen_Height/2));	//通過巨集定義,保證圖片在螢幕中間
	this->addChild(pSprite);

	//新增開始按鈕
	auto pNormalSprite = Sprite::create("res/start.png");	//匯入兩張圖片作為精靈,代表按鈕正常和選定的樣子
	auto pSelectedSprite = Sprite::create("res/start2.png");
	pNormalSprite->setOpacity(220);//透明度設定0-255
	pNormalSprite->setScale(0.8f);//圖片太大了,縮放一半
	pSelectedSprite->setScale(0.8f);
	auto StartItem = MenuItemSprite::create(pNormalSprite, pSelectedSprite, nullptr,
		CC_CALLBACK_1(WelcomeScene::onStartItemCallback, this));
	StartItem->setPosition(Vec2(Screen_Width/2 + 15,Screen_Height/6));
	menu = Menu::create(StartItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);
	
	//新增退出按鈕
	auto exitItem = MenuItemImage::create("res/EXIT1.png", "res/EXIT2.png", CC_CALLBACK_1(WelcomeScene::onExitItemCallback, this));
	exitItem->setPosition(Vec2(Screen_Width / 6*5+25, Screen_Height / 8));
	menu = Menu::create(exitItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);

	//新增設定按鈕
	auto setItem = MenuItemImage::create("res/SET1.png", "res/SET2.png", CC_CALLBACK_1(WelcomeScene::onSetItemCallback, this));
	setItem->setPosition(Vec2(Screen_Width / 8 -20, Screen_Height /8));
	menu = Menu::create(setItem, NULL);//選單項放到選單裡
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 1);
	//新增背景音樂
	if(SetScene::isMusicPlay)
		SimpleAudioEngine::getInstance()->playBackgroundMusic("WelcomeBackground.mp3", true); 

	auto pParticle = ParticleSystemQuad::create("res/fire.plist");
	pParticle->setPosition(Vec2(Screen_Width / 2, 0));
	this->addChild(pParticle);

	return true;
}

void WelcomeScene::onStartItemCallback(Ref * pSender)
{
	auto pDirector = Director::getInstance();
	auto scene = GameScene::createScene();
	TransitionPageTurn * ptrans = TransitionPageTurn::create(1.0f, scene, true);//設定切換場景的方式,書本 P25
	pDirector->replaceScene(ptrans);	//切換場景
	//SimpleAudioEngine::getInstance()->stopBackgroundMusic();
	SimpleAudioEngine::getInstance()->playEffect("res/WelcomeToGame.wav");//預設為不重複播放
}
void WelcomeScene::onSetItemCallback(Ref * pSender)
{
	auto pDirector = Director::getInstance();
	auto scene =SetScene::createScene();
	TransitionPageTurn * ptrans = TransitionPageTurn::create(1.0f, scene, true);//設定切換場景的方式,書本 P25
	pDirector->replaceScene(ptrans);	//切換場景
}
void WelcomeScene::onExitItemCallback(Ref * pSender)
{
	Director::getInstance()->end();
}
ok!!! 

複製貼上都很多啊~~自己慢慢研究把,圖片聲音資源似乎不能上傳啊,需要的留言把

主介面:


遊戲介面: