原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处、作者信息和本声明。否则将追究法律责任
http://blog.csdn.net/a1977722280/article/details/42966761
游戏下载地址:
http://www.mumayi.com/android-475978.html
直入正题,开始剖析涉及到的开发技术
作为一个游戏,是由UI和场景构成;开始界面、关卡选择、提示框等等统属于UI,游戏过程中的核心游戏代码在场景中实现:
一、游戏开始界面由背景、菜单、游戏logo、动态飘动的云层、粒子、背景音乐元素构成
1、背景、logo都是Cocos2dx中的图片精灵:
相关代码:
/* 游戏标题图片 */ CCSprite* titleSprite2 = CCSprite::create("pickure/mainUI/886.png"); titleSprite2->setPosition(ccp(visibleSize.width / 2,visibleSize.height /2)); this->addChild(titleSprite2,3);
visibleSize.width / 2 是一个相对屏幕坐标。,我们也可以填写绝对坐标,比如titleSprite2->setPosition(ccp(200,400));
2、菜单是用CCMenuItemImage实现,我采用单个的创作模式,因为这样使菜单的位置摆放比较灵活
相关代码:
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);
菜单和按钮有很多相似之处,按钮功能却又可以通过精灵动作来实现,但使用最多的还是菜单,比较方便
3、Cocos2dx在windows上有专门的粒子制作工具,C#编写,我使用的时候对其代码和界面简单的优化了一下
相关代码:
//小树叶特效 CCParticleSystem * lizi = new CCParticleSystemQuad(); //设置plist动画文件 lizi->initWithFile("treedown.plist"); //设置粒子显示位置 lizi->setPosition(ccp(400,500)); // 把粒子对象添加到场景中 this->addChild(lizi,10); 4、背景音乐这个就不用多少了,播放本地的一个音乐文件
相关代码:
/* 游戏背景音乐 */ CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("music/bgMusic.wav",-1);
当然我们也可以定义一个ID分配给它,用于控制停止播放,这种播放方式运用在音效的使用上,因为在游戏中可能有多种音效同时播放,我们或有需要停止某个正在播放的音效
5、飘动的云层,采用精灵动作和回调事件来实现,设置好目标点,执行动作回调
相关代码:
//设置精灵动作
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);
//回调函数
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); }
void MapThings::GetLeft(CCObject* pSender) { thing1->setFlipX(false); CCMoveTo* ToRight = CCMoveTo::create(8.0f, NULL); thing1->runAction(s); }
二、游戏关卡选择界面涉及到的相关技术与架构
组成元素:游戏得分、金币数量、关卡图标、(任务/仓库、充值等菜单)、动作精灵、返回菜单构成
1、金币和游戏得分采用CCLabelAtlas实现
相关代码:
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");
2、各个页面是如何跳转?在菜单回调函数中切换场景
相关代码:
//进入商城界面 void ChoiceUI::shop(CCObject* pSender) {
CCDirector::sharedDirector()->replaceScene(CCTransitionFlipAngular::create(1.0f,shop::scene()));
}
3、这里是如何记录玩家是否已经有权限进入关卡呢?这里设置顺利完成前一关,即可进入下一关
相关代码:
//给没有权限的关卡添加 锁定图标
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);
if(Maxlock!=1) { lock1 =CCSprite::create("pickure/ChoiceUI/suo.png"); lock1->setPosition(ccp(400,200)); this->addChild(lock1,1); } } }
//玩家点击关卡图标,判断是否有权限进入游戏场景
相关代码:
void ChoiceUI::Unlock2(CCObject* pSender) {
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(); }
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);
if(Maxlock>1) {
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());
CCDirector::sharedDirector()->replaceScene(CCTransitionPageTurn::create(1.0f,Scenea::scene(),false));
} } }
三、游戏场景中涉及到的相关技术与架构
组成元素:游戏得分计算过程、玩家角色动画的播放,运动的控制,怪物的AI,碰撞宝石的检测,游戏地图的制作与加载,道具的使用,以及对角色的影响等
地图滚动实现代码:
void Scenea::update( float delta )
{
int bgposX1 = m_bgSprite1->getPositionX();// 背景地图1的x坐标 int bgposX2 = m_bgSprite2->getPositionX();// 背景地图2的x坐标
int bgiSpeed = 7;// 地图滚动速度
/* 两张地图向左滚动(两张地图是相邻的,所以要一起滚动,否则会出现空隙) */ bgposX1 -= bgiSpeed; bgposX2 -= bgiSpeed;
/* 地图大小 */ CCSize mapSize = m_bgSprite1->getContentSize();
/* 当第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; }
m_bgSprite1->setPositionX(bgposX1); m_bgSprite2->setPositionX(bgposX2);
}
与宝石碰撞检测涉及到的技术
相关代码:
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),
player->getPosition().y - ( player->getContentSize().height/2),
player->getContentSize().width,
player->getContentSize().height); CCRect gunchildRect = CCRectMake( gunchild->getPosition().x - ( gunchild->getContentSize().width/2),
gunchild->getPosition().y - ( gunchild->getContentSize().height/2),
gunchild->getContentSize().width,
gunchild->getContentSize().height); CCRect coard1Rect = CCRectMake(
target->getPosition().x - ( target->getContentSize().width/2),
target->getPosition().y - (target->getContentSize().height/2),
target->getContentSize().width,
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); }
//主角碰撞宝石 if (playerRect.intersectsRect(coard1Rect)) { CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect( "music/eat.mp3"); m_monsterArr->removeObject(target); map->removeChild(target);
} }
其他。。。后续更新。。。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|