码迷,mamicode.com
首页 > 其他好文 > 详细

三、武器射击和自动射击

时间:2015-10-24 18:41:17      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

  本章节实现武器设计: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;
}

  来一张机枪发射图片  不要在意图片外观。。。

技术分享

 

三、武器射击和自动射击

标签:

原文地址:http://www.cnblogs.com/beat/p/4907225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!