Cocos2d-x 3.4《雷电大战》-让你的子弹无限发射

2015年03月16日 11:59 0 点赞 0 评论 更新于 2025-11-21 17:11

雷电游戏相信很多朋友都玩过,本文将实现雷电游戏中英雄飞机从游戏开始就无限发射子弹的功能,让战斗更加畅快。实现思路是单独创建一个子弹层,在该层设置一个定时器,每隔一定时间,根据当前英雄飞机传入的位置生成子弹,并设置子弹的移动事件以及移动后的处理事件(删除子弹以节省内存)。

最终效果

实现英雄飞机持续不断地发射子弹,营造激烈的战斗氛围。

开发环境

  • Cocos2d-x版本:3.4
  • 工程环境:VS2013

英雄子弹层实现

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<Sprite*>& GetBullet();

public:
// 子弹容器
Vector<Sprite*> 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() {
// 析构函数可根据需要添加资源释放代码
}

// 创建子弹层的静态方法
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.2秒调用一次发射子弹函数
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);
}

// 移除子弹函数
void HeroBulletLayer::removeBullet(Node* pNode) {
// 将子弹从容器中移除
vecBullet.eraseObject((Sprite*)pNode);
// 将子弹从SpriteBatchNode中移除
bulletBatchNode->removeChild(pNode, true);
}

通过以上代码,我们实现了在Cocos2d-x 3.4中让英雄飞机无限发射子弹的功能。在HeroBulletLayer类中,我们通过定时器定期调用ShootBullet函数来发射子弹,同时在子弹飞行结束后调用removeBullet函数来清理子弹,避免内存泄漏。

作者信息

boke

boke

共发布了 3994 篇文章