带有武器发射子弹的游戏主界面
来源:互联网 发布:剑三插件数据库 编辑:程序博客网 时间:2024/05/05 05:36
接着上次的界面,这次添加了武器主界面,原文出处 http://subject.9ria.com/cocos2d/index.html
现分析如下:
DefenderGameLayer.h
#ifndef __DEFENDERGAME_LAYER_H__#define __DEFENDERGAME_LAYER_H__#include "BaseLayer.h"#include"math.h"// 这个类是游戏主类class DefenderGameLayer:public BaseLayer{ public:static cocos2d::CCScene* scene(); //创建场景virtual bool init(); //初始化CREATE_FUNC(DefenderGameLayer); //创建层virtual void onEnter(); //加载virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);//开始触摸virtual void ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);//触摸点移动virtual void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);//结束触摸virtual void ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);//取消触摸private:bool setUpdateViews(); //创建纹理void detectd(float tim);// 这个方法用来获取判断子弹是否相撞 是否可以获取子弹// 武器的旋转动画执行完的时候执行这个回调函数void weapCallBack(cocos2d::CCNode* pSend);};#endifDefenderGameLayer.cpp#include "DefenderGameLayer.h"#include "WeaponSprite.h"#include"math.h"USING_NS_CC;CCScene* DefenderGameLayer::scene(){CCScene* scene=CCScene::create(); //创建场景DefenderGameLayer* layer=DefenderGameLayer::create();//创建该层scene->addChild(layer); //将层添加进场景return scene;}bool DefenderGameLayer::init(){bool isRet=false;do { CC_BREAK_IF(!BaseLayer::init()); CC_BREAK_IF(!setUpdateViews()); this->schedule(schedule_selector(DefenderGameLayer::detectd),0.1f); isRet=true;} while (0);return isRet;}bool DefenderGameLayer::setUpdateViews(){bool isRet=false;do {// 设置背景图片CCTexture2D* ptext2dBg=CCTextureCache::sharedTextureCache()->textureForKey("gmbg/gamebg.png");CCSprite* pSpribg=CCSprite::createWithTexture(ptext2dBg);CC_BREAK_IF(!pSpribg);pSpribg->setPosition(getWinCenter());this->addChild(pSpribg,1);//初始化武器系统//初始化武器系统CCTexture2D* texture=CCTextureCache::sharedTextureCache()->textureForKey("game/weapon.png");WeaponSprite* pweapon=WeaponSprite::createWithTexture(texture);pweapon->setAnchorPoint(ccp(0.3,0.5));pweapon->setPosition(ccp(0,getWinSize().height/2));this->addChild(pweapon,3,2);pweapon->setHudu(0);pweapon->initIdleBulletSpool(this);// 初始化 子弹系统isRet=true;} while (0);return isRet;} void DefenderGameLayer::onEnter(){ BaseLayer::onEnter(); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate( this,//在那个类中实现触屏回调函数 0, //优先级 true);//触摸时间是否被该目标截获 } bool DefenderGameLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){ WeaponSprite* pweapon=(WeaponSprite*) this->getChildByTag(2); CCPoint dpoint=pTouch->getLocation(); //触点坐标 CCPoint ypoint=pweapon->getPosition(); //武器坐标 float chy=dpoint.y-ypoint.y; float chx=dpoint.x-ypoint.x; float hud=atan(chy/chx); //计算弧度 float rota=-(hud*(180/PI)); CCActionInterval* paction= CCRotateTo::create(0.2,rota);//转过了rota的角度,是负的 CCCallFuncN *onComplete = CCCallFuncN::create(this, callfuncN_selector(DefenderGameLayer::weapCallBack)); CCSequence* pse=CCSequence::create(paction,onComplete,NULL); pweapon->runAction(pse);//执行武器旋转和子弹旋转动作 pweapon->setHudu(-hud);//设置弧度为-hud,因为表示的是转过的角度,而不是真正的角度,顺时针为正 pweapon->setStop(true); return true; } void DefenderGameLayer::weapCallBack(CCNode* pSend){ WeaponSprite* pweapon=(WeaponSprite*)pSend; pweapon->rotateLoadedBullets(); //将子弹旋转装载 CCLOG("wobiezhixingle"); } void DefenderGameLayer::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){//触摸移动和触摸时的方法效果是一样的 WeaponSprite* pweapon=(WeaponSprite*) this->getChildByTag(2); CCPoint dpoint=pTouch->getLocation(); CCPoint ypoint=pweapon->getPosition(); float chy=dpoint.y-ypoint.y; float chx=dpoint.x-ypoint.x; float hud=atan(chy/chx); float rota=-(hud*(180/PI)); CCActionInterval* paction= CCRotateTo::create(0.2,rota); CCCallFuncN *onComplete = CCCallFuncN::create(this, callfuncN_selector(DefenderGameLayer::weapCallBack)); CCSequence* pse=CCSequence::create(paction,onComplete,NULL); pweapon->runAction(pse); pweapon->setStop(true); pweapon->setHudu(-hud); } void DefenderGameLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){ WeaponSprite* pweapon=(WeaponSprite*) this->getChildByTag(2);//如果触摸结束则武器停止移动 pweapon->setStop(false); } void DefenderGameLayer::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){ } void DefenderGameLayer::detectd(float tim){ //检测子弹是否碰撞,武器重新上弹 WeaponSprite* pweapon=(WeaponSprite*) this->getChildByTag(2);//得到武器精灵对象 if(pweapon->getRunBulletsPool()){ CCArray* tem=CCArray::create(); for(int i=0;i<pweapon->getRunBulletsPool()->count();i++){//子弹池的子弹数量 BulletsSprite* pbu=(BulletsSprite*) pweapon->getRunBulletsPool()->objectAtIndex(i);//取得子弹对象池的当前索引的子弹 if (pbu->boundingBox().getMinX()>=getWinSize().width||pbu->boundingBox().getMinY()<0||pbu->boundingBox().getMinY()>=getWinSize().height){ pweapon->recoverBullet(pbu); //如果子弹出界则子弹调用重新上弹方法 tem->addObject(pbu);//将子弹添加进数组 }else { pbu->mymove();// 调用子弹移动方法 } } for(int j=0;j<tem->count();j++){ // pweapon->getRunBulletsPool()->removeObject(tem->objectAtIndex(j),false); } tem->removeAllObjects(); } }BulletsSprite.h
#ifndef __BULLETS_SPRITE_H__#define __BULLETS_SPRITE_H__#include "cocos2d.h"class BulletsSprite :public cocos2d::CCSprite{public:BulletsSprite(void);~BulletsSprite(void);//virtual bool initWithTexture(cocos2d::CCTexture2D *pTexture);//初始化纹理static BulletsSprite* createWithTexture(cocos2d::CCTexture2D *pTexture);//创建对象inline void setMovespeed(float movespeed){//设置子弹移动速度this->movespeed=movespeed;}inlinefloat getMovespeed(){ //得到子弹移动速度return movespeed;}inline void setHurt(float hurt){//设置伤害this->hurt=hurt;}inlinefloat getHurt(){//得到伤害值return hurt;}cocos2d::CCPoint getMovePoint();// 这个是根据当前速度获取精灵的坐标void mymove();// 移动函数// 第一次被设置为弓箭的角度CC_SYNTHESIZE(float,firstRoto,FirstRoto);//用来设置getter和setter属性// 最后一次被弓箭的角度CC_SYNTHESIZE(float,lastRoto,LastRoto);private:float movespeed;// 移动速度float hurt;// 攻击力伤害值};#endif
BulletsSprite.cpp
#include "BulletsSprite.h"#include "BaseLayer.h"#include <cmath>USING_NS_CC;BulletsSprite* BulletsSprite::createWithTexture(CCTexture2D *pTexture){ BulletsSprite *pobSprite = new BulletsSprite();if (pobSprite && pobSprite->initWithTexture(pTexture)){pobSprite->autorelease();return pobSprite;}CC_SAFE_DELETE(pobSprite);return NULL;}CCPoint BulletsSprite::getMovePoint(){// 这里使用了 三角函数 主要是为了计算当前子弹所移动的位置float temhud= (this->getLastRoto()*PI)/180;//将最后的弧度转换成角度float tex= std::cos(temhud)*this->movespeed;//将速度乘以cos值得到横坐标float tey= std::sin(temhud)*this->movespeed;tex=std::fabs(tex);// x 方向不存在负数return ccp(tex,-tey);//取得移动的坐标}void BulletsSprite::mymove(){CCPoint cp=getMovePoint();float x=cp.x+this->getPositionX();float y=cp.y+this->getPositionY();//起始位置+移动的坐标this->setPosition(ccp(x,y));//设置位置}BulletsSprite::BulletsSprite(void):movespeed(2)//设置速度为2,初始化firstRoto和lastRoto为0{this->firstRoto=0;this->lastRoto=0;}BulletsSprite::~BulletsSprite(void){}WeaponSprite.h
#ifndef __WEAPON_SPRITE_H__#define __WEAPON_SPRITE_H__#include "cocos2d.h"#include "BulletsSprite.h"// 这个是武器系统 用来发射子弹class WeaponSprite:public cocos2d::CCSprite{public:WeaponSprite();~WeaponSprite();CREATE_FUNC(WeaponSprite);//创建WeaponSprite对象virtual bool initWithTexture(cocos2d::CCTexture2D *pTexture);//初始化纹理static WeaponSprite* createWithTexture(cocos2d::CCTexture2D *pTexture);cocos2d::CCArray* getIdleBullet(int cout);// 根据目前武器系 的级别获取当前子弹的数量默认级别是1个空闲的子弹 void recoverBullet(BulletsSprite* pbullet);// 回收掉一个子弹void initIdleBulletSpool(cocos2d::CCLayer* pLayer);// 初始化子弹池 CC_SYNTHESIZE(bool,stop,Stop);// 设置当前的武器旋转的弧度制void setHudu(float hudu);inline cocos2d::CCSpriteBatchNode* getBatchNode(){//得到批量穿件节点return batchNode;}inlinecocos2d::CCArray* getRunBulletsPool(){//得到正在运动的子弹对象池数组return pRunBulletsPool;}inlinecocos2d::CCArray* getLoadedArray(){//得到上膛的子弹return loadedArray;}// 当武器旋转的时候 正在枪膛里面的弹药也是需要旋转的void rotateLoadedBullets();private:cocos2d::CCArray* pIdleBulletsPool;// 空闲子弹池cocos2d::CCArray* pRunBulletsPool;// 正在运行的子弹池cocos2d::CCSpriteBatchNode* batchNode;// 批量穿件子弹 优化方法cocos2d::CCArray* loadedArray;// 这是上膛的子弹 其实就是在弓箭上显示的子弹 这个时候的子弹是待发状态float hudu;// 武器所旋转的弧度值// 给武器装备子弹 cout 表示 一次上的子弹的个数void loadedBullet(int cout=1);void loade(float tim);};#endif
WeaponSprite.cpp
#include "WeaponSprite.h"#include "BaseLayer.h"// 定义 每个弓箭之间的间距是20#define SPA 10USING_NS_CC;bool WeaponSprite::initWithTexture(CCTexture2D *pTexture){bool bRet=false;do {CC_BREAK_IF(!CCSprite::initWithTexture(pTexture));// 初始话跑动的子弹this->pRunBulletsPool=CCArray::create();//初始化子弹池数组this->pRunBulletsPool->retain();//保留子弹池//this->speed=10;this->hudu=0;bRet=true;} while (0);return bRet;}void WeaponSprite::initIdleBulletSpool(CCLayer* player){ //初始化空闲子弹池// 创建50个子弹的纹理图片 这样做的目的是为了加速游戏的运行速度 CCTexture2D* texture=CCTextureCache::sharedTextureCache()->textureForKey("game/wq0.png");batchNode = CCSpriteBatchNode::createWithTexture(texture,50);//创建50个子弹的纹理图片batchNode->setPosition(CCPointZero); player->addChild(batchNode,2); //将batchNode精灵对象加入该层,zOrder为2// 初始化子弹池pIdleBulletsPool=CCArray::create();pIdleBulletsPool->retain();this->loadedArray=CCArray::create();//创建上膛的子弹数组loadedArray->retain();this->setZOrder(1);for(int i=0;i<50;i++){// 创建子弹BulletsSprite* pbullet=BulletsSprite::createWithTexture(batchNode->getTexture());// 把子弹的坐标设置成和当前武器的坐标是一样的pbullet->setPosition(this->getPosition());pbullet->setAnchorPoint(ccp(0,0.5));// 设置子弹的移动速度为50pbullet->setMovespeed(50);// 把子弹放到子弹池中this->pIdleBulletsPool->addObject(pbullet);pbullet->setVisible(false);// 把创建好的子弹放到 CCSpriteBatchNode 让其一次渲染batchNode->addChild(pbullet,-1);}this->schedule(schedule_selector(WeaponSprite::loade),1);}void WeaponSprite::recoverBullet(BulletsSprite* pbullet){//回收掉子弹pbullet->setPosition(this->getPosition());//子弹回到初始位置pbullet->setRotation(0);pbullet->setVisible(false);//设置为不可见pbullet->setFirstRoto(0);pbullet->setLastRoto(0);this->pIdleBulletsPool->addObject(pbullet);//添加到空闲子弹池}WeaponSprite* WeaponSprite::createWithTexture(CCTexture2D *pTexture){WeaponSprite *pobSprite = new WeaponSprite();if (pobSprite && pobSprite->initWithTexture(pTexture)){pobSprite->autorelease();return pobSprite;}CC_SAFE_DELETE(pobSprite);return NULL;}void WeaponSprite::loade(float tim){this->loadedBullet(5); //一次上5个子弹}void WeaponSprite::loadedBullet(int cout){ if (this->loadedArray->count()!=cout){ //如果上膛的子弹数组的数量不等于5CCArray* tem=this->getIdleBullet(cout);//从空闲子弹池中取得子弹for(int i=0;i<tem->count();i++){//循环取得子弹 BulletsSprite* pbul=(BulletsSprite*)tem->objectAtIndex(i);//根据索引取得相应的子弹 this->loadedArray->addObject(pbul);//将子弹加入上膛的子弹数组}}// 表示需要发射 需要把 在枪膛中的子弹添加到 发射子弹中if(this->stop){ //如果stop函数为true则发射if(this->loadedArray->count()>0){this->pRunBulletsPool->addObjectsFromArray(this->loadedArray);//将枪膛中的子弹加入发射子弹数组中for(int i=0;i<this->loadedArray->count();i++){this->loadedArray->removeObjectAtIndex(0,false);//依次将子弹从枪膛中的子弹数组中移除i--;}}}}CCArray* WeaponSprite::getIdleBullet(int cout){CCArray* ptemar=CCArray::create();float zhuwuqi= this->hudu*180/PI; //将弧度转换成角度for(int i=0;i<cout;i++){CCObject* pbul=this->pIdleBulletsPool->objectAtIndex(0);//获取空闲子弹池的子弹if(pbul){ //如果获取到了BulletsSprite* pbullet=(BulletsSprite*)pbul;ptemar->addObject(pbul);//将获取的子弹添加进数组pbullet->setVisible(true);//设置子弹为可见// 这些要特别注意在获取子弹的时候进行初始化pbullet->setFirstRoto(0);pbullet->setLastRoto(zhuwuqi);//设置当前的角度pbullet->setRotation(zhuwuqi);//初始化角度this->pIdleBulletsPool->removeObjectAtIndex(0,false);}else {BulletsSprite* pbullet=(BulletsSprite*)BulletsSprite::createWithTexture(batchNode->getTexture());pbullet->setMovespeed(50);//如果没有子弹了,创建子弹精灵,并将精灵添加进batchNodepbullet->setPosition(this->getPosition());pbullet->setRotation(0);pbullet->setVisible(false);pbullet->setFirstRoto(0);pbullet->setLastRoto(0);batchNode->addChild(pbullet,2);i--;}}if(cout>1){// 如果 在箭堂里面的子弹是 大于 2 的时候需要均匀的分布在 箭堂 里面 规定两个 弓箭之间的角度是20度bool isEven=cout%2==0?true:false;// 判断箭堂里面的弓箭是不是偶数int pair=cout/2;// 能分成几对int temsp=(cout-1)*SPA;// 得到所有弓箭之间的夹角for(int i=0;i<ptemar->count();i++){BulletsSprite* pbul=(BulletsSprite*)ptemar->objectAtIndex(i);// 表示中间哪里没有弓箭 反之刚好中间哪里有弓箭if (isEven){//如果是偶数个箭头if(i<pair){ // 表示上半部分 // 旋转 计算出旋转的角度float temro=i*SPA+SPA/2;pbul->setRotation(-temro+zhuwuqi);pbul->setFirstRoto(-temro);pbul->setLastRoto(-temro+zhuwuqi);}else{ //表示的是下半部分的角度float temro=(i-pair)*SPA+SPA/2;pbul->setRotation(temro+zhuwuqi);pbul->setFirstRoto(temro+zhuwuqi);pbul->setLastRoto(temro+zhuwuqi);}}else{ //如果是奇数的话,则增加一个中间箭头的角度的设置if(i<pair){ // 表示上半部分 // 旋转 计算出旋转的角度float temro=i*SPA+SPA;pbul->setRotation(-temro+zhuwuqi);pbul->setFirstRoto(-temro);pbul->setLastRoto(-temro+zhuwuqi);}else if (i==pair){pbul->setRotation(zhuwuqi);pbul->setFirstRoto(0);pbul->setLastRoto(zhuwuqi);}else{float temro=(i-pair-1)*SPA+SPA;pbul->setRotation(temro+zhuwuqi);pbul->setFirstRoto(temro);pbul->setLastRoto(temro+zhuwuqi);}}}}return ptemar;}void WeaponSprite::setHudu(float hudu){this->hudu=hudu;}void WeaponSprite::rotateLoadedBullets(){// 获取当前武器旋转的角度float zhuwuqi= this->hudu*180/PI;if(this->loadedArray){if(this->loadedArray->count()>0){for(int i=0;i<this->loadedArray->count();i++){BulletsSprite* pbul=(BulletsSprite*)loadedArray->objectAtIndex(i);float temr=pbul->getFirstRoto();pbul->setRotation(temr+zhuwuqi);// 设置最后当前武器最后一次的旋转角度pbul->setLastRoto(temr+zhuwuqi);}}}}WeaponSprite::WeaponSprite(void){this->stop=false;this->hudu=0;}WeaponSprite::~WeaponSprite() //将所有有子弹的对象全都release{if (this->pIdleBulletsPool){this->pIdleBulletsPool->release();}if (this->pRunBulletsPool){this->pRunBulletsPool->release();}if (this->loadedArray){this->loadedArray->release();}}
0 0
- 带有武器发射子弹的游戏主界面
- 飞机游戏移动和发射子弹的小模型
- 跳跃的实现(发射子弹)
- 游戏开发之,发射子弹,中弹后退
- 09-html5游戏坦克大战第五战(自己的坦克可以发射单颗子弹)
- 10-html5游戏坦克大战第六战(自己的坦克可以连续发射子弹)
- Android基于box2d开发弹弓类游戏[五]-------------发射子弹
- HTML5+JS游戏开发模块----发射多颗子弹
- Python游戏系列之四_发射子弹
- 四、子弹类的创建,飞机子弹发射与无用子弹的销毁(雷霆战机)
- 带有武器的角色类
- 带有溅射范围的子弹的实现
- cocos2d-x发射子弹
- unity之子弹发射
- 2.8.2 发射子弹
- UE4蓝图发射子弹
- Unity发射子弹
- Unity3D实现再鼠标单击的方向发射子弹
- Android 开机启动应用
- webservice的用法
- hdu 2255 二分图的完备匹配
- 新的起点
- 阿姆斯特朗数 软件训练营 初级 入职前练习 C/C++
- 带有武器发射子弹的游戏主界面
- shell用户手册
- EXCEL:批量读取EXCEL文件给指定数据库(access,sql server)
- 【并查集专题】
- ubuntu12.10安装myeclipse10.5 以及破解
- 面试经之给刚毕业的大学生和刚入门的程序员的忠告及图书推荐
- pull解析xml
- Xlib: connection to ":0.0" refused by server
- Java中的深拷贝(深复制)和浅拷贝(浅复制)