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);

}


未完待续...
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值