引言
我们今天所要说的就是Cocos2dx(这里面主要还是Cocos2dx 2.2.3实现的。)去实现一个象棋的整个框架。个人也算消化学习中。ok~一切开始。
首先,我们要知道游戏其实和演戏一样;游戏里面有”导演“去负责场景的切换和场景保存等其他工作,而每一个场景中呢又有许多的幕。一幕一幕才能构成一个场景。
那在象棋中我们先来自导自演一幅简单的”开幕式“吧~
象棋开场
1、想要演戏就得要有服装,那我们就必须把资源文件拷贝到创建的工程中的”resource“文件夹下。
一般我们默认从资源文件夹里直接去加载我们所需要的资源图片。懂的人都懂得,不做多余赘述,一张图表待过。
2、我们在有了资源之后呢,就会想怎么才能去建立一个场景呢。因为只有建立了场景,我们才能在上面演戏。
在Cocos中呢,渲染树的概念是很重要的。因为渲染树是cocos的数据结构。也可以成为model,而mvc在这里也有了很大的应用。view就是我们导演出来的场景。每个场景这下有每一幕(在cocos里面被称为层:CCLayer)。然后我们再去进行逻辑控制,并且让我们的屏幕每隔1/60秒去刷新我们的渲染树,所以我们就会看到变化的场景了。另外因为有渲染树的存在,所以树上的结点全部都是结点类型的。这当然啦~~囧。
ok,那么我们的第一个场景就产生了:
#ifndef SceneStart_H
#define SceneStart_H
#include "cocos2d.h"
USING_NS_CC;
class SceneStart:public CCLayer
{
public:
SceneStart();
static CCScene* scene();
CREATE_FUNC(SceneStart)
bool init();
void Welcome_Scene_Init();
void Touch_Enable();
bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
bool chess_Beclicled(CCTouch *pTouch);
void gotomiddle();
bool collision();
void update(float delta);//
private:
CCSprite *_red;
CCSprite *_black;
bool chess_selected;
bool isRed;
};
#endif // SceneStart_H
这里我们创建了一个头文件,cocos里的场景加载很有意思。没有特殊要求几乎都是大同小异的,上面这段代码中的函数命名还是很规范的,所以没有文档的话一般认真看都回看懂的。除非本人的英语四级成绩是假的 ==!
#include "SceneStart.h"
#include "SceneGame.h"
SceneStart::SceneStart()
{
}
CCScene* SceneStart::scene()
{
CCScene*s = CCScene::create();
SceneStart *layer = SceneStart::create();
s->addChild(layer);
return s;
}
bool SceneStart::init()
{
CCLayer::init();
Welcome_Scene_Init();
Touch_Enable();
return true;
}
void SceneStart::Welcome_Scene_Init()
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite * Picred = CCSprite::create("bkg2.png");
CCSprite * Picblack = CCSprite::create("bkg1.png");
this->addChild(Picred);
this->addChild(Picblack);
_red = Picred;
_black = Picblack;
Picred->setPosition(ccp(winSize.width/2-150,winSize.height/2));
Picblack->setPosition(ccp(winSize.width/2+150,winSize.height/2));
Picred->setScale(2.0f);
Picblack->setScale(2.0f);
}
void SceneStart::Touch_Enable()
{
setTouchEnabled(true);
setTouchMode(kCCTouchesOneByOne);
}
bool SceneStart::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
return true;
}
void SceneStart::ccTouchEnded(CCTouch *pTouch, CCEvent *)
{
if(chess_Beclicled(pTouch))
{
gotomiddle();
}
}
void SceneStart::gotomiddle()
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCMoveTo *moveto1 = CCMoveTo::create(1.0f,ccp(winSize.width/2,winSize.height/2));
CCMoveTo *moveto2 = CCMoveTo::create(1.0f,ccp(winSize.width/2,winSize.height/2));
CCRotateBy *rotateby1 = CCRotateBy::create(1.0f,360);
CCRotateBy *rotateby2 = CCRotateBy::create(1.0f,-360);
CCSpawn *spawn1 = CCSpawn::createWithTwoActions(moveto1,rotateby1);
CCSpawn *spawn2 = CCSpawn::createWithTwoActions(moveto2,rotateby2);
_red->runAction(spawn1);
_black->runAction(spawn2);
scheduleUpdate();
}
bool SceneStart::chess_Beclicled(CCTouch *pTouch)
{
CCPoint ptClicked = pTouch->getLocation();
chess_selected = false;
if(_red->boundingBox().containsPoint(ptClicked))
{
isRed = true;
chess_selected = true;
}
else if(_black->boundingBox().containsPoint(ptClicked))
{
isRed = false;
chess_selected = true;
}
return chess_selected;
}
void SceneStart::update(float)
{
if(collision())
CCDirector::sharedDirector()->replaceScene(SceneGame::scene(SceneStart::isRed));
}
bool SceneStart::collision()
{
float red_x = _red->getPositionX();
float black_x = _black->getPositionX();
if(abs(red_x-black_x)<_red->getContentSize().width)
return true;
else
return false;
}
好吧,这里的C++文件是对头文件的解释。大量的函数存在是对业务和逻辑分离的最好证明。又嘴贫了~~。这两个文件加载好了就可以了吗?NONONO~~一切都还只是开始,因为是在Linux下QT平台下做的Cocos开发,主要是为了移植Android方便才上了我们薛哥的当了~~囧。当然啦~在Linux下做开发明显要比Win32下面好太多了嘛~~哈哈,强行装B了~
奇了个怪了。 那我们还缺少什么呢~
#include "AppDelegate.h"
//#include "HelloWorldScene.h"
#include "SceneStart.h"
USING_NS_CC;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
pDirector->setOpenGLView(pEGLView);
// turn on display FPS
pDirector->setDisplayStats(false);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
CCScene *pScene = SceneStart::scene();
// run
pDirector->runWithScene(pScene);
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() {
CCDirector::sharedDirector()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
CCDirector::sharedDirector()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}
好吧,如你所见。就是它了。废话不多说,据我猜测,它是整个程序的入口~~(其实我好想只看到它只是加载了CCSceneStart::Scene(),好吧,开场场景都被加载了,那岂有不能开始游戏之理~~)。啧啧~这开源中国怎么没有代码行数呢~都不知道该怎么解释代码~。得~您要是看到什么疑惑的,可以留言咨询哈~当然。其实这里面什么都没有~~^_^。
O啦~附上效果动画。
第一张图中的两个棋子被点击之后呢,会以旋转的方式相聚到中间位置,一旦触碰到。我们的导演就会把第一个场景以及第一个场景中的两个精灵都删去然后堆栈中只会存在第二张场景的内存指针。至于第二张图么~明天再放出细节。实现过程实在蛋疼~~
O啦~~去洗澡咯~