原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处、作者信息和本声明。否则将追究法律责任
http://blog.csdn.net/a1977722280/article/details/42966761
@H_502_4@直入正题,开始剖析涉及到的开发技术
@H_502_4@作为一个游戏,是由UI和场景构成;开始界面、关卡选择、提示框等等统属于UI,游戏过程中的核心游戏代码在场景中实现:
@H_502_4@一、游戏开始界面由背景、菜单、游戏logo、动态飘动的云层、粒子、背景音乐元素构成
@H_502_4@1、背景、logo都是Cocos2dx中的图片精灵:
@H_502_4@相关代码:
@H_502_4@/* 游戏标题图片 */CCSprite* titleSprite2 = CCSprite::create("pickure/mainUI/886.png");
titleSprite2->setPosition(ccp(visibleSize.width / 2,visibleSize.height /2));
this->addChild(titleSprite2,3); @H_502[email protected] / 2 是一个相对屏幕坐标。,我们也可以填写绝对坐标,比如titleSprite2->setPosition(ccp(200,400)); @H_502_4@2、菜单是用CcmenuItemImage实现,我采用单个的创作模式,因为这样使菜单的位置摆放比较灵活 @H_502_4@相关代码: @H_502_4@CcmenuItemImage *tile = CcmenuItemImage::create(
"pickure/mainUI/image 185_1.png",
"pickure/mainUI/image 187_1.png",
this,
menu_selector(mainUI::enter));
CC_BREAK_IF(! tile);
tile->setPosition(ccp(650,200));
Ccmenu* ptile = Ccmenu::create(tile,NULL);
ptile->setPosition(CCPointZero);
CC_BREAK_IF(! ptile);
this->addChild(ptile,3); @H_502_4@ 菜单和按钮有很多相似之处,按钮功能却又可以通过精灵动作来实现,但使用最多的还是菜单,比较方便 @H_502_4@3、Cocos2dx在windows上有专门的粒子制作工具,C#编写,我使用的时候对其代码和界面简单的优化了一下 @H_502_4@相关代码: @H_502_4@ //小树叶特效
CCParticleSy@R_502_6063@ * lizi = new CCParticleSy@R_502_6063@Quad();
//设置plist动画文件
lizi->initWithFile("treedown.plist");
//设置粒子显示位置
lizi->setPosition(ccp(400,500));
// 把粒子对象添加到场景中
this->addChild(lizi,10);
4、背景音乐这个就不用多少了,播放本地的一个音乐文件 @H_502_4@ 相关代码: @H_502_4@/* 游戏背景音乐 */
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("music/bgMusic.wav",-1); @H_502_4@当然我们也可以定义一个ID分配给它,用于控制停止播放,这种播放方式运用在音效的使用上,因为在游戏中可能有多种音效同时播放,我们或有需要停止某个正在播放的音效 @H_502_4@5、飘动的云层,采用精灵动作和回调事件来实现,设置好目标点,执行动作回调 @H_502_4@ 相关代码: @H_502_4@//设置精灵动作 @H_502_4@ CCMoveto* ToRight = CCMoveto::create(8.0f,ccp(2800,thing1->getPositionY()));
CCSequence*s = CCSequence::create(ToRight,
CCCallFuncN::create(this,
callfuncN_selector(MapThings::GetRight)),
NULL);
thing1->runAction(s); @H_502_4@//回调函数 @H_502_4@ void MapThings::GetRight(CCObject* pSender)
{
thing1->setFlipX(true);
CCMoveto* ToLeft = CCMoveto::create(8.0f,ccp(200,thing1->getPositionY()));
CCSequence*s = CCSequence::create(ToLeft,
callfuncN_selector(MapThings::GetLeft)),
NULL);
thing1->runAction(s);
} @H_502_4@
void MapThings::GetLeft(CCObject* pSender)
{
thing1->setFlipX(false);
CCMoveto* ToRight = CCMoveto::create(8.0f,
NULL);
thing1->runAction(s);
}
@H_502_4@二、游戏关卡选择界面涉及到的相关技术与架构 @H_502_4@ 组成元素:游戏得分、金币数量、关卡图标、(任务/仓库、充值等菜单)、动作精灵、返回菜单构成 @H_502_4@1、金币和游戏得分采用cclabelAtlas实现 @H_502_4@相关代码: @H_502_4@cclabelAtlas*SumscoreLabs = cclabelAtlas::create(CCString::createWithFormat("%d",Sumscore)->getCString(),"pickure/ChoiceUI/labelatlasimg.png",24,32,
'0');
SumscoreLabs->setAnchorPoint(ccp(0,0.5));
SumscoreLabs->setPosition(ccp(260,400));
SumscoreLabs->setScale(0.7f);
this->addChild(SumscoreLabs,3);
SumscoreLabs->setString("360"); @H_502_4@2、各个页面是如何跳转?在菜单回调函数中切换场景 @H_502_4@相关代码: @H_502_4@//进入商城界面
void ChoiceUI::shop(CCObject* pSender)
{ @H_502_4@
CCDirector::sharedDirector()->replaceScene(CCTransitionFlipAngular::create(1.0f,shop::scene())); @H_502_4@
} @H_502_4@3、这里是如何记录玩家是否已经有权限进入关卡呢?这里设置顺利完成前一关,即可进入下一关 @H_502_4@相关代码: @H_502_4@//给没有权限的关卡添加 锁定图标 @H_502_4@ if(Maxlock!=4)
{
lock4 =CCSprite::create("pickure/ChoiceUI/suo.png");
lock4->setPosition(ccp(visibleSize.width / 7+(visibleSize.width / 6.5+visibleSize.width / 12)*3,visibleSize.height /2));
this->addChild(lock4,3);
if(Maxlock!=3)
{
lock3 =CCSprite::create("pickure/ChoiceUI/suo.png");
lock3->setPosition(ccp(visibleSize.width / 7+(visibleSize.width / 6.5+visibleSize.width / 12)*2,visibleSize.height /2));
this->addChild(lock3,3);
if(Maxlock!=2)
{
lock2 =CCSprite::create("pickure/ChoiceUI/suo.png");
lock2->setPosition(ccp(visibleSize.width / 7+visibleSize.width / 6.5+visibleSize.width / 12,visibleSize.height /2));
this->addChild(lock2,3); @H_502_4@ if(Maxlock!=1)
{
lock1 =CCSprite::create("pickure/ChoiceUI/suo.png");
lock1->setPosition(ccp(400,200));
this->addChild(lock1,1);
}
}
} @H_502_4@//玩家点击关卡图标,判断是否有权限进入游戏场景 @H_502_4@相关代码: @H_502_4@void ChoiceUI::Unlock2(CCObject* pSender)
{ @H_502_4@ CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(
"music/button.mp3");
if(golds<36)
{
CCBlink*blink = CCBlink::create(1,2);
CCSequence*s = CCSequence::create( blink,
CCCallFuncN::create(this,
callfuncN_selector(ChoiceUI::yincang)),
NULL);
tishi2->setVisible(true);
tishi2->runAction(s);
return;
}
if(Maxlock<2)
{
CCRotateBy* move = CCRotateBy::create(2,360);
lock2->runAction(move);
//showAd();
} @H_502_4@ CCScaleBy* out = CCScaleBy::create(0.5f,2);
CCCallFunc* callFunc = CCCallFunc::create(this,callfunc_selector(ChoiceUI::in));
CCSequence* actions = CCSequence::create(out,callFunc,NULL);
ts->runAction(actions); @H_502_4@if(Maxlock>1)
{ @H_502_4@ locknAmber=2;
cclOG("tiled x=%d",Maxlock);
if(score2!=0)
{
SUMscore(375,295,score2);
MessBox ();
}
else
{
CCUserDefault::sharedUserDefault()->setIntegerForKey("golds",golds-20);
CCUserDefault::sharedUserDefault()->flush();
golds=CCUserDefault::sharedUserDefault()->getIntegerForKey("golds");
SumgoldLabs->setString(CCString::createWithFormat("%d",golds)->getCString()); @H_502_4@ CCDirector::sharedDirector()->replaceScene(CCTransitionPageTurn::create(1.0f,Scenea::scene(),false)); @H_502_4@ }
}
} @H_502_4@三、游戏场景中涉及到的相关技术与架构 @H_502_4@ 组成元素:游戏得分计算过程、玩家角色动画的播放,运动的控制,怪物的AI,碰撞宝石的检测,游戏地图的制作与加载,道具的使用,以及对角色的影响等 @H_502_4@地图滚动实现代码: @H_502_4@void Scenea::update( float delta ) @H_502_4@{ @H_502_4@int bgposX1 = m_bgSprite1->getPositionX();// 背景地图1的x坐标
int bgposX2 = m_bgSprite2->getPositionX();// 背景地图2的x坐标 @H_502_4@int bgiSpeed = 7;// 地图滚动速度 @H_502_4@/* 两张地图向左滚动(两张地图是相邻的,所以要一起滚动,否则会出现空隙) */
bgposX1 -= bgiSpeed;
bgposX2 -= bgiSpeed; @H_502_4@/* 地图大小 */
CCSize mapSize = m_bgSprite1->getContentSize(); @H_502_4@/* 当第1个地图完全离开屏幕时,让第2个地图完全出现在屏幕上,同时让第1个地图紧贴在第2个地图后面 */
if(bgposX1 < -mapSize.width / 2) {
bgposX2 = mapSize.width / 2;
bgposX1 = mapSize.width + mapSize.width / 2;
}
/* 同理,当第2个地图完全离开屏幕时,让第1个地图完全出现在屏幕上,同时让第2个地图紧贴在第1个地图后面 */
if(bgposX2 < -mapSize.width / 2) {
bgposX1 = mapSize.width / 2;
bgposX2 = mapSize.width + mapSize.width / 2;
} @H_502_4@m_bgSprite1->setPositionX(bgposX1);
m_bgSprite2->setPositionX(bgposX2);
@H_502_4@} @H_502_4@与宝石碰撞检测涉及到的技术 @H_502_4@相关代码: @H_502_4@void Scenea::Monstersnock()
{
for (int i = 0; i < m_monsterarr->count(); i++)
{
CCSprite *target = (CCSprite *)m_monsterarr->objectAtIndex(i);
CCRect playerRect = CCRectMake(
player->getPosition().x - ( player->getContentSize().width/2), @H_502_4@ player->getPosition().y - ( player->getContentSize().height/2), @H_502_4@ player->getContentSize().width, @H_502_4@ player->getContentSize().height);
CCRect gunchildRect = CCRectMake(
gunchild->getPosition().x - ( gunchild->getContentSize().width/2), @H_502_4@ gunchild->getPosition().y - ( gunchild->getContentSize().height/2), @H_502_4@ gunchild->getContentSize().width, @H_502_4@ gunchild->getContentSize().height);
CCRect coard1Rect = CCRectMake( @H_502_4@ target->getPosition().x - ( target->getContentSize().width/2), @H_502_4@ target->getPosition().y - (target->getContentSize().height/2), @H_502_4@ target->getContentSize().width, @H_502_4@ target->getContentSize().height);
//子弹击中宝石
if (gunchildRect.intersectsRect(coard1Rect))
{
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(
"music/eat.mp3");
CCMoveto* robot1movetoright = CCMoveto::create(2.0f,ccp(100,450));
target->runAction(robot1movetoright);
} @H_502_4@ //主角碰撞宝石
if (playerRect.intersectsRect(coard1Rect))
{
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(
"music/eat.mp3");
m_monsterarr->removeObject(target);
map->removeChild(target); @H_502_4@ }
} @H_502_4@其他。。。后续更新。。。