java雷电怎么连续发射子弹_Cocos2d-x《雷电大战》(3)-子弹无限发射

本文介绍如何在Cocos2d-x 3.4版本中实现《雷电大战》游戏的英雄飞机无限发射子弹功能。通过创建HeroBulletLayer,设置定时器每隔0.2秒发射子弹,利用批次渲染优化性能,当子弹飞出屏幕或碰撞时移除子弹,以节省内存。
摘要由CSDN通过智能技术生成

本文要实现雷电游戏中,游戏一開始,英雄飞机就无限发射子弹的功能。

这里的思想是单独给子弹弄一个层。在这个层不设置一个定时器,每隔一个时间,依据当前英雄飞机传入的位置,生成子弹,并设置子弹的移动事件,和移动后的事件(就是把子弹删除掉,节省内存)。

终于效果:

3a1ccce41636800cb8736677167b61aa.gif

Cocos2d-x版本号:3.4

project环境:VS30213

一、英雄子弹层

1、HeroBulletLayer.h

/**

*功能 创建子弹并初始化子弹的运动

*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)

*时间 2015.3.14

*/

#include "cocos2d.h"

USING_NS_CC;

const float FlYVElOCITY = 500;//执行速度,能够自己控制。每秒所走的像素

class HeroBulletLayer : public cocos2d::Layer

{

public:

HeroBulletLayer(Node* heroPlane);

~HeroBulletLayer();

virtual bool init();

//依据英雄飞机创建子弹

static HeroBulletLayer* create(Node* heroPlane);

//移除超出屏幕可视范围的子弹或者碰撞后的子弹清除

void removeBullet(Node* pNode);

//发射子弹。在当中进行子弹的渲染和子弹的飞行动作,默觉得单子弹

void ShootBullet(float dt);

//返回子弹列表

Vector & GetBullet();

public:

Vector vecBullet;//子弹容器

SpriteBatchNode* bulletBatchNode;//批次渲染节点

Node* heroPlane;//传入的英雄飞机

};

2、HeroBulletLayer.cpp

/**

*功能 创建子弹并初始化子弹的运动

*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)

*时间 2015.3.14

*/

#include "HeroBulletLayer.h"

HeroBulletLayer::HeroBulletLayer(Node* heroPlane) {

this->heroPlane = heroPlane;

}

HeroBulletLayer::~HeroBulletLayer() {

}

/**

*创建子弹的静态方法

*@param heroPlane为英雄飞机

*/

HeroBulletLayer* HeroBulletLayer::create(Node* heroPlane){

HeroBulletLayer* pRet = new HeroBulletLayer(heroPlane);

if (pRet&&pRet->init()){

pRet->autorelease();

return pRet;

}

else{

delete pRet;

pRet = NULL;

return NULL;

}

}

bool HeroBulletLayer::init() {

bool bRet = false;

do {

CC_BREAK_IF(!Layer::init());

//创建BatchNode节点

bulletBatchNode = SpriteBatchNode::create("bullet1.png");

this->addChild(bulletBatchNode);

//每隔0.2S调用一次发射子弹函数

this->schedule(schedule_selector(HeroBulletLayer::ShootBullet), 0.2f);

bRet = true;

} while (0);

return bRet;

}

/**

*用缓存的方法创建子弹,并初始化子弹的运动和运动后的事件

*/

void HeroBulletLayer::ShootBullet(float dt) {

Size winSize = Director::getInstance()->getWinSize();

auto PlanePos = heroPlane->getPosition();

//从缓存中创建子弹

auto spritebullet = Sprite::createWithTexture(bulletBatchNode->getTexture());

//将创建好的子弹加入到BatchNode中进行批次渲染

bulletBatchNode->addChild(spritebullet);

//将创建好的子弹加入到容器

vecBullet.pushBack(spritebullet);

Point bulletPos = (Point(PlanePos.x,

PlanePos.y + heroPlane->getContentSize().height / 2 + 20));

spritebullet->setPosition(bulletPos);

spritebullet->setScale(0.8f);

float flyLen = winSize.height - PlanePos.y;

float realFlyDuration = flyLen / FlYVElOCITY;//实际飞行的时间

//子弹执行的距离和时间,从飞机处開始执行到屏幕顶端

auto actionMove = MoveTo::create(realFlyDuration,

Point(bulletPos.x, winSize.height));

//子弹执行完动作后进行函数回调,调用移除子弹函数

auto actionDone = CallFuncN::create(

CC_CALLBACK_1(HeroBulletLayer::removeBullet, this));

//子弹開始跑动

Sequence* sequence = Sequence::create(actionMove, actionDone, NULL);

spritebullet->runAction(sequence);

}

/**

* 移除子弹,将子弹从容器中移除。同一时候也从SpriteBatchNode中移除

*/

void HeroBulletLayer::removeBullet(Node* pNode) {

if (NULL == pNode) {

return;

}

Sprite* bullet = (Sprite*)pNode;

this->bulletBatchNode->removeChild(bullet, true);

vecBullet.eraseObject(bullet);

}

/**

*返回子弹列表,用来与敌机做碰撞检測

*/

Vector & HeroBulletLayer::GetBullet(){

return vecBullet;

}

注意:

1、

//创建BatchNode节点

bulletBatchNode = SpriteBatchNode::create("bullet1.png");这里用了把子弹的图片加入到缓存中的方法,然后须要创建子弹时候调用

//从缓存中创建子弹

auto spritebullet = Sprite::createWithTexture(bulletBatchNode->getTexture());假设不这样做的话,游戏会非常耗内存。就会非常卡!

2、这里重写了create方法。让它带一个參数,用它来传入英雄飞机

二、用法

//加子弹

HeroBulletLayer *mHeroBulletLayer = HeroBulletLayer::create(mHeroPlane);

this->addChild(mHeroBulletLayer,1);

效果:

8e8afdd9cc8f904357b8dd3e13fae9d8.gif

三、思路说明

1、上面的英雄子弹类非常好用,你仅仅要传入一个英雄飞机的位置。它就会生成英雄子弹层不断调用定时器生成子弹,同一时候加入到当前层中和Vector中(用来保存全部的子弹)

2、 依据当前英雄飞机的位置。计算子弹移动的距离。然后速度是自己设定的,就能够计算子弹要移动的直线距离的时间。

3、 当子弹移动到视野外后,就删除掉这个子弹,vector中也要删除。

4、GetBullet();是用来得到当前的vector子弹集合,然后我们须要一个一个的取出来。推断是否和敌机相撞,假设是,就调用removeBullet(Node* pNode);就是这样了。

比方:

void GameMain::update(float dt){

auto *mEnemyPlane = getChildByTag(200);

Vector mVecHeroBullet = mHeroBulletLayer->GetBullet();

for (int i = 0; i

if (mEnemyPlane->boundingBox().intersectsRect(mVecHeroBullet.at(i)->boundingBox())){

mHeroBulletLayer->removeBullet(mVecHeroBullet.at(i));

}

}

}

效果例如以下:这里要注意下vector的遍历用法,不能[],cocos2dx没有重载这个,要用at.

7b0f7f3c752a4e95a03748e579c92d58.gif

这里仅仅是演示样例了下怎么用,子弹碰到飞机后就把它删除掉,敌机还没有做处理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值