本文主要是介绍cocos2d-x “喵星战争”要点剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、喵星战争的游戏规则:
玩家用手指控制主角小猫的移动,当小猫处于被控制状态时,会放出子弹,狗博士不断从屏幕上部出现,玩家要做的就是移动小
猫主角,使小猫的子弹打中狗博士,打中dog可以增加积分。该游戏采用移动游戏中流行的生存方式,集没有关卡的限制,主角有三次失败(撞上狗博士或试管子弹)机会,第三次撞上时game over。
二、喵星战争的游戏框架和界面:略
三、主游戏模块组成元素的实现:
1、主角小猫的实现:
由于小猫主体部分没有动画效果,从节约资源角度出发将resources分为四部分:主体,左手,右手,尾巴。其中主体部分的动画由三张图片构成,三张图的明暗度不同,连续播放就有了闪动的效果;小猫向不同方向移动时手臂会有“上扬”的动作,这个效果通过图片的垂直镜像获得;尾巴部分通过旋转动作让它如同座钟的钟摆一样左右摇动。
主角小猫的类定义文件GameObjHero.h
#ifdef example1_1_GameObjHero_h
#define example1_1_GameObjHero_h
#include "cocos2d.h"
using namespace cocos2d;
class GameObjHero : public CCNode,public CCTargetedTouchDelegate{
public:
CCSprite* lefthand; //左手
CCSprite* righthand; //右手
CCPoint offset; // 触摸偏移位置
bool isControl; // 是否在控制主角
GameObjHero(void);
virtual ~GameObjHero();
void releasebullet(); // 释放子弹
CCRect rect();
virtual void onEnter();
vritual void onExit();
bool contrainsTouchLocation(CCTouch* touch);
virtual bool ccTouchBegan(CCTouch* touch , CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch , CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch , CCEvent* event);
virtual void touchDelegateRetain();
virtual void touchDelegateRelease();
};
主角小猫的初始化函数onEnter:
void GameObjHero::onEnter(){
CCNode::onEnter();
this->setContentSize(CCSizeMake(85,90));
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this,0,true); //触屏代理
CCSprite* mainSprite = CCSprite::create("catBody1.png");
// 主体动画
CCAnimation* animation = CCAnimation::create();
animation->addSpriteFrameWIthFileName("catBoy1.png");
animation->addSpriteFrameWithFileName("catBody2-4.png");
animation->addSpriteFrameWithFileName("catBody3.png");
animation->addSpriteFrameWithFileName("catBody2-4.png");
animation->setDelayPerUnit(0.1f);
animation->setRestoreOriginalFrame(true);
mainSprite->runAction(CCRepeatForever::create(CCAnimate::create(animation)));
addChild(mainSprite);
// 尾巴
CCSprite* tail = CCSprite::create("catTail.png");
tail->setAnchorPoint(ccp(0.5,1));
tail->setScale(0.5);
tail->setRotation(20);
tail->runAction(CCRepreatForever((CCActionInterval*)CCSequence::create(
CCRotateBy::create(0.5,-40),CCRotateBy::create(0.5,40),NULL));
}addChild(tail);
// 手
lefthand = CCSprite::create("catHand1.png");
lefthand->setAnchorPoint(ccp(1,0.5));
addChild(lefthand);
righthand = CCSprite::create("catHand2.png");
righthand = setPosition(ccp(18,-20));
righthand->setAnchorPoint(ccp(0,0.5));
addChild(righthand);
offset = ccp(0,0);
isControl = false;
schedule(schecule_selector(GaneObjHero::releasebullet).1.0f);
开始触摸函数ccTouchBegan:
bool GameObjHero::ccTouchBegan(CCTouch* touch,CCEvent* event){
if((GameMain*)this->getParent())->isover) //判断主角是否死亡
return false;
if(!containsTouchLocation(touch)){ // 判断触摸点是否在主角的矩形框中
return false;
}else{
isControl = true;
CCPoint touchPoint = touch->locationInView();
touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); // CCTouch获得的是屏幕坐标,需转换成GL坐标
// 获得触点坐标与主角锚点坐标之差,通过此偏移量和触点移动过后的坐标点可计算出主角的新位置
offset.x = touchPoint.x - this->getPosition().x;
offset.y = touchPoint.y - this->getPosition().y;
}}
return true;
触摸点移动函数ccTouchMoved:
void GameObjHero::ccTouchMoved(CCTouch* touch,CCEvent* event){
if(isControl){
CCPoint touchPoint = touch->locationInView();
touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);
//设置左右手上下动作
float x = touchPoint.x - offset.x;
float y = touchPoint.y - offset.y;
if(x < this->getPosition().x){
lefthand->setFlipY(true);
righthand->setFlipY(false);
}else{
lefthand->setFlipY(false);
righthand->setFlipY(true);
}
}this->setPosition(x,y);
}
触摸结束函数ccTouchEnded:
// 手指离开屏幕时,需要将主角的两只手放下并将是否控制主角变量置为false
void GameObjHero::ccTouchEnded(CCTouch* touch,CCEvent* event){
if(isControl){
isControl = false;
lefthand->setFlipY(false);
righthand->setFlip(false);
}
}
2、敌人狗博士的实现
狗博士的逻辑与主角小猫类似,只是不需要拆分成很多部分。狗博士有两张图片,DrDog2.png下部有褶皱,两张图片连续播放就会有动态效果;狗博士死亡时会有爆炸效果,也是一个动画(5张图片)。
敌人狗博士(继承自CCNode)的初始化函数onEnter:
void GameObjEnemy::onEnter(){
CCNode::onEnter();
this->setContentSize(CCSizeMake(99,111));
mainBody = CCSprite::create("DrDog1.png");
// 初始化动画
CCAnimation* animation = CCAnimation::create();
animation->addSpriteFrameWithFileName("DrDog.png");
animation->addSpriteFrameWithFileName("DrDog.png");
animation->setDelayPerUnit(0.1f);
animation->setRestoreOriginalFrame(true);
mainBody->runAction(CCRepeatForever::create(CCAnimate::create(animation)); // 敌人闪烁动画
addChild(mainBody);
boom = CCSprite::create("Boom1.png"); // 定义爆炸精灵对象
addChild(boom);
boom->setVisible(false); // 爆炸不可见
islife = true;
}
设置狗博士死亡函数:
void GameObjEnemy::setdie(){
islft = false;
mainBody->setVisible(false); // 敌人不可见
boom->setVisible(true); // 爆炸可见
this->stopAllActions(); // 继承自CCNode,停止所有动作
//爆炸动画
CCAnimation* boomAnimation = CCAnimation::create();
boomAnimation->addSpriteFrameWithFileName("Boom1.png");
boomAnimation->addSpriteFrameWithFileName("Boom2.png");
boomAnimation->addSpriteFrameWithFileName("Boom3.png");
boomAnimation->addSpriteFrameWithFileName("Boom4.png");
boomAnimation->addSpriteFrameWithFileName("Boom5.png");
booAnimation->setDelayPerUnit(0.1f);
boomAnimation->setRestoreOriginalFrame(true);
boom->runAction(CCSequence::create(CCAnimate::create(boomAnimation)),CCCallFuncN::create(this,
callfuncN_selector(GameObjEnemy::restart)),NULL);
}
爆炸动画后,调用restart,重新设置敌人位置,将主干部分设为可见,爆炸不可见,然后调用movestart设置移动方式:
void GameObjEnemy::restart(){
mainBody->setVisible(true);
boom->setVisible(false);
CCSize size = CCDirector::sharedDirector()->getWinSize();
this->setPosition(ccp(size.width/4 * type,size.height + 50));
islife = true;
mainBody->setVisible(true);
boom->setVisible(false);
this->movestart();
}
void GameObjEnemy::movestart(){
islife = true;
int type = CCRANDOM_0_1() * 4;
// 贝塞尔曲线移动
ccBezierConfig bezier2;
bezier2.controlPoint_1 = CCPointMake(this->getPosition().x-400,300);
bezier2.controlPoint_2 = CCPointMake(this->getPosition().x+480,280);
bezier2.endPosition = CCPointMake(this->getPosition().x,-70);
ccBezierConfig bezier1;
bezier1.controlPoint_1 = CCPointMake(this->getPosition().x+400,330);
bezier1.controlPoint_2 = CCPointMake(this->getPosition().x-400,280);
bezier1.endPosition = CCPointMake(this->getPosition().x,-70);
CCBezierTo* bezierBy1 = CCBezierTo::create(6,bezier1);
switch(type){
case 0:
case 1:
this->runAction(CCSequence::create(CCMoveBy::create(6,ccp(0,-600)),
CCCallFuncN::create(this,callfuncN_selector(GameObjEnemy::restart)),NULL));
break;
case 2:
this->runAction(CCSequence::create(bezierBy2,CCCallFuncN::create(this,
callfuncN_selector(GameObjEnemy::restart)),NULL));
break;
case 3:
this->runAction(CCSequence::create(bezierBy2,CCCallFuncN::create(this,
callfuncN_selector(GameObjEnemy::restart)),NULL));
break;
}
}
schedule(schedule_selector(GameObjEnemy::releasebullet),1.2f);
未完待续...
这篇关于cocos2d-x “喵星战争”要点剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!