wangqiao123原创,欢迎转载,转载请在明显处注明! 谢谢。
原文地址:http://blog.csdn.net/wangqiao123/article/details/19636197
初学cocos2d-x,捕鱼达人也搞了很长时间了,经历过迷惘,最终克服了困难,这是其中关于子弹层的编写,也是我的第一篇博文吧,大家可以作为借鉴,其中注释已经很详细了,这也算是我的学习笔记吧,其他的类以后会陆陆续续的发出来.
#ifndef __BULLET_H__
#define __BULLET_H__
#include "BasicLayer.h"
#include "GameCore.h"
#include "cocos2d.h"
USING_NS_CC;
class BulletLayer:public BasicLayer
{
public:
CCSprite *m_BulletSprite;
public:
BulletLayer(void);
~BulletLayer(void);
virtual bool init();
static CCScene *scene();
void main();
//发射子弹 初始点 角度 炮台类型(特殊处理子弹的大小 运用放缩原理)
void BulletFire(const CCPoint &ptStart,float rotation,GameCore::enCannonType CannonType);
/*不需要,只有在返回类型是指针或者引用类型的时候才有意义,表示不允许通过这个返回的指针或者返回的引用去修改数据。
有时候也用于返回类型是自定义类型的情况,不允许对返回值再直接赋值,但这种用法只在理论上有意义。*/
//子弹回调函数
void BulletEndCallback(CCNode* sender);
CREATE_FUNC(BulletLayer);
};
#endif __BULLET_H__
cpp文件:
#include "BulletLayer.h"
#include "GameScene.h"
#include "GameCore.h"
#include "cocos2d.h";
USING_NS_CC;
BulletLayer::BulletLayer(void)
{
}
BulletLayer::~BulletLayer(void)
{
}
bool BulletLayer::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(!BasicLayer::init());
//加载炮弹的纹理缓存
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache -> CCSpriteFrameCache::addSpriteFramesWithFile("Fish/plist/shot_0_3.plist","Fish/plist/shot_0_3.png");
cache -> CCSpriteFrameCache::addSpriteFramesWithFile("Fish/plist/shot_1_3.plist","Fish/plist/shot_1_3.png");
//加载炮弹的动画纹理缓存
CCAnimationCache *animacache = CCAnimationCache::sharedAnimationCache();
animacache -> CCAnimationCache::addAnimationsWithFile("Fish/plist/shot_0_3_anims.plist");
animacache -> CCAnimationCache::addAnimationsWithFile("Fish/plist/shot_1_3_anims.plist");
bRet = true;
} while (0);
this->main();
return bRet;
}
//类外调用
CCScene *BulletLayer::scene()
{
CCScene *scene = CCScene::create();
BulletLayer *bulletLayer = BulletLayer::create();
scene->addChild(bulletLayer);
return scene;
}
void BulletLayer::main()
{
}
//发射子弹函数
void BulletLayer::BulletFire(const CCPoint &ptStart,float rotation,GameCore::enCannonType CannonType)
{
//实现 发射的炮弹是一个无限循环的动画 实现炮弹的 分级
// 1-4 级炮弹是一组图片 5-7级炮弹是一组图片
CBulletObject *pBulletObject = new CBulletObject;
pBulletObject->m_CannonType = CannonType;//对子弹数据进行赋值
int nFish = 0;//实现炮弹分级
if (CannonType>GameCore::CannonType_4)
{
nFish = 1;
}
CCSize szScale;//缩放大小
switch (CannonType)
{
case GameCore::CannonType_0: { szScale.width=0.5f; szScale.height=0.5f; break; }
case GameCore::CannonType_1: { szScale.width=0.6f; szScale.height=0.6f; break; }
case GameCore::CannonType_2: { szScale.width=0.7f; szScale.height=0.7f; break; }
case GameCore::CannonType_3: { szScale.width=0.8f; szScale.height=0.8f; break; }
case GameCore::CannonType_4: { szScale.width=0.9f; szScale.height=0.9f; break; }
case GameCore::CannonType_5: { szScale.width=0.9f; szScale.height=0.9f; break; }
case GameCore::CannonType_6: { szScale.width=1.0f; szScale.height=1.0f; break; }
}
std::ostringstream ostr;
ostr<<"shot_"<<nFish<<"_3_01.png";//将第一帧赋予精灵, plist 里的文件名
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();//读取缓存
m_BulletSprite = CCSprite::createWithSpriteFrame(cache->spriteFrameByName(ostr.str().c_str()));
m_BulletSprite->setUserObject(pBulletObject);//将子弹数据加入用户数据对象
//m_BulletSprite = CCSprite::create("Fish/plist/1.7.png",CCRectMake(193,0,47,48));//后面可以跟位置属性
//m_BulletSprite->setUserObject(pBulletObject);//将子弹精灵设置为子弹类对象 貌似没找到setUserObject的定义
//计算子弹终点坐标 算法
CCPoint ptEnd (ptStart.x+57*std::sin(rotation*M_PI/180), ptStart.y+57*std::cos(rotation*M_PI/180));//rotation*M_PI/180 角度转化成弧度 弧度转换成角度 rotation*180/M_PI 106是预定半径
m_BulletSprite->setPosition(ptEnd);//指定目标 子弹出发点 距炮口一段距离
m_BulletSprite->setRotation(rotation);//旋转角度
m_BulletSprite->setScaleX(szScale.width);//X放大比例
m_BulletSprite->setScaleY(szScale.height);//Y放大比例
addChild(m_BulletSprite);
ostr.str("");//???
ostr<<"shot_"<<nFish<<"_3_capture";
CCAnimationCache *animacache = CCAnimationCache::sharedAnimationCache();
CCAnimation *bulletMoves = animacache->animationByName(ostr.str().c_str());//CCAnimation
bulletMoves->setRestoreOriginalFrame(true);
//bulletMoves->setLoops(-1);
CCRepeatForever *Actbullet=CCRepeatForever::create(CCAnimate::create(bulletMoves));
/*CCAnimate *Actbullet = CCAnimate::create(bulletMoves);*/
m_BulletSprite->runAction(Actbullet);
//发射
CCMoveBy *actBullet = CCMoveBy::create(1.2f,ccp(320*std::sin(rotation*M_PI/180),320*std::cos(rotation*M_PI/180)));
CCSequence *seq=(CCSequence*)CCSequence::create(actBullet,CCCallFuncN::create(this, callfuncN_selector(BulletLayer::BulletEndCallback)), NULL);
//CCFiniteTimeAction *seq=CCSequence::create(actBullet, NULL);
//CCSequence *seq = (CCSequence*)CCSequence::create(actBullet, NULL);
m_BulletSprite->runAction(seq);
}
//在这里张开网 判断
void BulletLayer::BulletEndCallback(CCNode* sender)
{
CCLOG("BulletLayer::BulletEndCallback");
//getUserObject()返回与此节点关联的 Object 值
CBulletObject *pBulletObject = (CBulletObject *)sender->getUserObject();// 指向子弹节点
//判断是否张开网
CCPoint pt = sender->getPosition();
if (pt.x>=0 && pt.x<=Size.width && pt.y>=0 && pt.y<=Size.height)
{
GameScene *pGameScene = (GameScene*)getParent();//获取父节点
pGameScene->m_NetLayer->NetFire(pt,pBulletObject->m_CannonType);
pBulletObject->release();
removeChild(sender,true);
}
}