本章节实现武器设计:hand枪每次一发,机枪可以连续发射。武器旋转到任何一个方向发射子弹。
首先添加武器类:
//武器基类 class arm :public cocos2d::Sprite { public: //初始化子弹 virtual bool initbullet() = 0; //发射 virtual void fire() = 0; //停止发射 用于自动机枪 virtual void stopfire() = 0; //获取子弹点火位置 Vec2 getBeginfirePos()const; //获取子弹点火离开武器位置 Vec2 getEndfirePos()const; //获取武器旋转点 Vec2 getRotationPos(); //设置点火位置 void setBeginfirePos(Vec2& _firePos); //设置子弹发射位置 void setEndfirePos(Vec2& _gunPoint); ssize_t getbulletCount()const; protected: // _beginfire和_endfire 一起用来计算子弹的平面向量 Sprite* _beginfire; Sprite* _endfire; Sprite* _rotation; //最多携带子弹数 ssize_t _bulletMaxCount; //子弹 std::vector<bullet*> _bullet; };
///handgun的 实现基类的虚函数 class handGun :public arm { public: virtual bool init()override; virtual bool initbullet(); virtual void fire(); virtual void stopfire(); CREATE_FUNC(handGun); }; ///机枪 实现基类的虚函数 class machineGun :public arm{ public: virtual bool init()override; virtual bool initbullet(); virtual void fire(); virtual void stopfire(); //多一个自动发射函数 这里由定时器调用 void autofire(float); CREATE_FUNC(machineGun); private: };
//cpp #include "arm.h" #include "bullet.h" Vec2 arm::getBeginfirePos()const { return _beginfire->getPosition(); } Vec2 arm::getEndfirePos()const { return _endfire->getPosition(); } Vec2 arm::getRotationPos() { //转换世界坐标 在鼠标点击的时候也是转换成世界坐标 return convertToWorldSpace(_rotation->getPosition()); } void arm::setBeginfirePos(Vec2& _firePos) { _beginfire->setPosition(_firePos); } void arm::setEndfirePos(Vec2& _endPos) { _endfire->setPosition(_endPos); } ssize_t arm::getbulletCount()const { return _bullet.size(); } bool handGun::init() { _beginfire = Sprite::create(); _endfire = Sprite::create(); _rotation = Sprite::create(); addChild(_beginfire); addChild(_endfire); addChild(_rotation); _bulletMaxCount = 10; return true; } bool handGun::initbullet() { auto count = _bullet.size(); for (; count != _bulletMaxCount; count++){ auto handbullet = bullet::create(); handbullet->initWithFile("arm1.png"); handbullet->setSpeed(5); handbullet->setVisible(false); _bullet.push_back(handbullet); addChild(handbullet); } //设置旋转中心 _rotation->setPosition(getPosition() + getContentSize() / 2); return !!_bullet.size(); } void handGun::fire() { if (_bullet.size() < 1){ initbullet(); } auto handbullet = _bullet.back(); _bullet.erase(_bullet.end() - 1); //计算方向 auto direction = convertToWorldSpace(getEndfirePos()) - convertToWorldSpace(getBeginfirePos()); handbullet->setDirection(direction); auto pos = convertToWorldSpace(getEndfirePos()); pos += handbullet->getContentSize() / 2; handbullet->setPosition(pos); handbullet->setName("bullet"); auto Parent = getParent(); handbullet->retain(); removeChild(handbullet,false); Parent->addChild(handbullet, true); handbullet->release(); handbullet->setVisible(true); } void handGun::stopfire() { } bool machineGun::init() { _beginfire = Sprite::create(); _endfire = Sprite::create(); _rotation = Sprite::create(); addChild(_beginfire); addChild(_endfire); addChild(_rotation); _bulletMaxCount = 100; return true; } bool machineGun::initbullet() { auto count = _bullet.size(); for (; count != _bulletMaxCount; count++){ auto handbullet = bullet::create(); handbullet->initWithFile("arm1.png"); handbullet->setSpeed(10); handbullet->setVisible(false); _bullet.push_back(handbullet); addChild(handbullet); } _rotation->setPosition(getPosition() + getContentSize() / 2); return !!_bullet.size(); } void machineGun::fire() { //设置定时器 0.1s调用一次 schedule(schedule_selector(machineGun::autofire), 0.1f); } void machineGun::stopfire() { //停止定时器 this->unschedule(schedule_selector(machineGun::autofire)); } void machineGun::autofire(float) { if (_bullet.size() < 1){ initbullet(); } auto handbullet = _bullet.back(); _bullet.erase(_bullet.end() - 1); auto direction = convertToWorldSpace(getEndfirePos()) - convertToWorldSpace(getBeginfirePos()); handbullet->setDirection(direction); auto pos = convertToWorldSpace(getEndfirePos()); pos += handbullet->getContentSize() / 2; handbullet->setPosition(pos); handbullet->setName("bullet"); auto Parent = getParent(); handbullet->retain(); removeChild(handbullet, false); Parent->addChild(handbullet, true); handbullet->release(); handbullet->setVisible(true); }
//子弹类 class bullet:public Sprite { public: int getSpeed()const; Vec2 getDirection()const; void setSpeed(int _speed); void setDirection(Vec2& _direction); //子弹移动 virtual void move(); CREATE_FUNC(bullet); private: int _speed; Vec2 _direction; };
//cpp 自动实现方法 int bullet::getSpeed()const { return _speed; } Vec2 bullet::getDirection()const { return _direction; } void bullet::setSpeed(int _speed) { this->_speed = _speed; } void bullet::setDirection(Vec2& _direction) { this->_direction = _direction; } void bullet::move() { float degree = 0; int dirx = 1; //X 轴方向 int diry = 1; //Y 轴方向 _direction.normalize(); if (_direction.x < 0){ dirx = -1; } if (_direction.y < 0){ diry = -1; } //计算弧度 [0 pi/2) degree = atan(fabs(_direction.y / _direction.x)); Vec2 location = getPosition(); location.x += cos(degree)*_speed*dirx; location.y += sin(degree)*_speed*diry; setPosition(location); }
//Scene fireScene::init() { . . . auto handgun = handGun::create(); handgun->initWithFile("fire/handgun.png"); handgun->setPosition(origin + Vec2(visibleSize) / 2); handgun->setBeginfirePos(Vec2(125, 170)); handgun->setEndfirePos(Vec2(225, 170)); handgun->setName("handgun"); this->addChild(handgun, 1); handgun->initbullet(); auto machinegun = machineGun::create(); machinegun->setBeginfirePos(Vec2(110, 146)); machinegun->setEndfirePos(Vec2(255, 146)); machinegun->initWithFile("fire/machinegun.png"); machinegun->setName("machinegun"); machinegun->setPosition(origin + Vec2(visibleSize) - Vec2(100, 100) - Vec2(label->getContentSize() / 2)); this->addChild(machinegun, 1); machinegun->initbullet(); auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = [](Touch* touch, Event* event){ auto tarter = event->getCurrentTarget(); auto s = tarter->getContentSize(); auto locationNode = tarter->convertToNodeSpace(touch->getLocation()); Rect rect = Rect{ 0, 0, s.width, s.height }; if (rect.containsPoint(locationNode)){ auto gunarm = static_cast<arm*>(tarter); gunarm->fire(); return true; } return false; }; listener->onTouchMoved = [this](Touch* touch, Event* event){ auto pNode = event->getCurrentTarget(); auto gun = static_cast<arm*>(pNode); auto rotationpos = gun->getRotationPos(); Vec2 v = (convertToWorldSpace(touch->getLocation()) - rotationpos) - (convertToWorldSpace(touch->getPreviousLocation()) - rotationpos); v.normalize(); if (v.x >= -0.00001 && v.x <= 0.00001 || v.y >= -0.00001 && v.y <= 0.00001) { return; } auto degree = CC_RADIANS_TO_DEGREES(atan2(v.x, v.y)); pNode->setRotation(degree); }; listener->onTouchEnded = [](Touch* touch, Event* event){ auto pNode = event->getCurrentTarget(); if (strcmp(pNode->getName().c_str(), "machinegun") == 0){ static_cast<machineGun*>(pNode)->stopfire(); } }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, handgun); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), machinegun); return true; }
来一张机枪发射图片 不要在意图片外观。。。
时间: 2024-10-21 17:10:00