(五) 添加子弹

最后更新于:2022-04-01 16:12:16

我方飞机的子弹和敌机子弹都在这个类中产生。将子弹专门设计成一个类,主要是为了方便扩展。之后如果想更换我方飞机子弹或者是敌机子弹,都会很方便。 类的功能很直观,就是添加子弹、移除子弹 ~~~ void bindEnemyManager(EnemyManager* enemyManager); void BeginBulletShoot(float dt = 0.0f); // 开启子弹射击 void StopBulletShoot(); // 停止子弹射击 void addBullet(float dt); // 添加子弹 void removeBullet(Node* pNode); // 移除子弹 void addEnemyBullet(float dt); // 添加敌机子弹 void removeEnemyBullet(Node* pNode); // 移除敌机子弹 ~~~ 添加的子弹像敌机一样,存储在容器中 ~~~ Vector<Sprite*> vecBullet; Vector<Sprite*> vecEnemyBullet; EnemyManager* m_enemyManager; ~~~ 想给敌机添加子弹,要将子弹类和敌机管理类绑定,通过敌机管理类中的容器,来获取敌机对象。 我们通过对比敌机类和我方飞机类,可以发现,我方飞机精灵直接嵌入在飞机层中,并通过setTag()设置标识,可以通过标识来调用,也可以通过调用飞机层的实例instancePlane来间接调用。而敌机虽然也设置了标识,但是可以通过getSprite()函数来获取精灵实体。 接下来实现添加子弹的功能 ~~~ bool Bullet::init() { if (!Layer::init()) { return false; } BeginBulletShoot(); return true; } void Bullet::bindEnemyManager(EnemyManager* enemyManager) { this->m_enemyManager = enemyManager; m_enemyManager->retain(); } void Bullet::BeginBulletShoot(float dt) { this->schedule(schedule_selector(Bullet::addBullet), 0.2f, kRepeatForever, dt); this->schedule(schedule_selector(Bullet::addEnemyBullet), 1.0f, kRepeatForever, dt); } void Bullet::StopBulletShoot() { this->unschedule(schedule_selector(Bullet::addBullet)); this->unschedule(schedule_selector(Bullet::addEnemyBullet)); } void Bullet::addBullet(float dt) { // 子弹 auto bullet = Sprite::createWithSpriteFrameName("bullet1.png"); if (NULL == bullet) { return; } this->addChild(bullet); // 加到Layer中去 vecBullet.pushBack(bullet); // 加到容器中去,用于以后的碰撞检测等 // 获得飞机的位置 Point planePos = MyPlane::instancePlane->getChildByTag(AIRPLANE)->getPosition(); Point bulletPos = Point(planePos.x, planePos.y + MyPlane::instancePlane->getChildByTag(AIRPLANE)->getContentSize().height / 2); bullet->setPosition(bulletPos); // 飞行长度 飞行就是超出窗体 float flyLen = Director::getInstance()->getWinSize().height + bullet->getContentSize().height / 2 - bulletPos.y; float flyVelocity = 320 / 1; //飞行速度 float realFlyDuration = flyLen / flyVelocity; // 飞行时间 auto actionMove = MoveTo::create(realFlyDuration, Point(bulletPos.x, Director::getInstance()->getWinSize().height + bullet->getContentSize().height / 2)); auto actionDone = CallFuncN::create(CC_CALLBACK_1(Bullet::removeBullet, this)); Sequence* sequence = Sequence::create(actionMove, actionDone, NULL); bullet->runAction(sequence); if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying()) { CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/bullet.wav"); } } void Bullet::removeBullet(Node* pNode) { if (NULL == pNode) { return; } Sprite* bullet = (Sprite*)pNode; this->removeChild(bullet, true); vecBullet.eraseObject(bullet); } // 添加敌机子弹 void Bullet::addEnemyBullet(float dt) { for (auto& eEnemy : m_enemyManager->vecEnemy) { Enemy* pEnemySprite = (Enemy*)eEnemy; // 子弹 auto bullet = Sprite::createWithSpriteFrameName("enemyBullet.png"); if (NULL == bullet) { return; } this->addChild(bullet); // 加到Layer中去 vecEnemyBullet.pushBack(bullet); // 加到容器中去,用于以后的碰撞检测等 // 获得敌方飞机的位置 Point enemyPos = pEnemySprite->getPosition(); Point bulletPos = Point(enemyPos.x, enemyPos.y - pEnemySprite->getContentSize().height / 2); bullet->setPosition(bulletPos); // 飞行长度 飞行就是超出窗体 float flyLen = bulletPos.y - bullet->getContentSize().height / 2; float flyVelocity = 320 / 1; //飞行速度 float realFlyDuration = flyLen / flyVelocity; // 飞行时间 auto actionMove = MoveTo::create(realFlyDuration, Point(bulletPos.x, Director::getInstance()->getVisibleOrigin().y - bullet->getContentSize().height / 2)); auto actionDone = CallFuncN::create(CC_CALLBACK_1(Bullet::removeEnemyBullet, this)); Sequence* sequence = Sequence::create(actionMove, actionDone, NULL); bullet->runAction(sequence); if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying()) { CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/enemyBullet.wav"); } } } // 移除敌机子弹 void Bullet::removeEnemyBullet(Node* pNode) { if (NULL == pNode) { return; } Sprite* bullet = (Sprite*)pNode; this->removeChild(bullet, true); vecEnemyBullet.eraseObject(bullet); } ~~~ 注意不要将添加我方飞机子弹和添加敌机子弹放在一个函数中,那样不仅使代码混乱,而且不利于扩展。
';