三、武器射击和自动射击

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

三、武器射击和自动射击的相关文章

仿《雷霆战机》飞行射击手游开发--游戏对象

需求分析 既然我们做的是打飞机游戏,那需要有哪些游戏对象呢?观察一下下面这个游戏中的图片.首先,主角当然是飞机,有玩家飞机.两侧的僚机.敌机.飞机上装有各式各样的武器:普通子弹.导弹.激光等.如果只是一成不变的飞机打飞机,子弹没有变化,飞机也没有变化,那也太没意思了.所以我们还增加了道具,当敌机被击落时,会有一定的几率爆出宝石和其他各种奖励道具,比如武器升级.战机暴走.修复护甲.超级必杀.量子护盾. 我们来总结一下: 飞机有哪些基本功能?    飞行.射击.爆炸: 飞机有哪些基本属性呢? 生命.

unity3d游戏开发之第一人称射击游戏

简介 这个教程中,我们详细了解下如何制作一个简单的第一人称射击游戏(FPS).其中将介绍一些基本的3D游戏编程的概念和一些关于怎样如游戏程序员般思考的技巧. 前提 这个教程假定你已经熟悉软件Unity基本操作,掌握了基本的脚本概念. 创建新工程 下载FPS_Tutorial.zip压缩文件,解压,在Unity中打开工程文件. 从Unity安装目录导入Standard Assets资源包. 导入工程后,你会在Unity工程面板中的"Standard Assets"文件夹下看见这些资源内容

POJ - 3041 Asteroids(最小点覆盖数)

1.有一个n*n的矩阵,在矩阵上有k个行星,用武器射击一次可以消灭一行或者一列的行星,求消灭所有的行星的最少射击次数. 2.最小点覆盖数 = 最大匹配数 主要在于转化:看图: 3. /* 顶点编号从0开始的 邻接矩阵(匈牙利算法) 二分图匹配(匈牙利算法的DFS实现)(邻接矩阵形式) 初始化:g[][]两边顶点的划分情况 建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配 g没有边相连则初始化为0 uN是匹配左边的顶点数,vN是匹配右边的顶点数 左边是X集,右边是Y集 调用:re

Bot怪AI

UC中只有一种怪Bot,这是一种很简单的怪,它不会跑,只会旋转并原地射击,所以也没有用什么行为树之类的,所以这里围绕Bot怪如何发现玩家.攻击玩家.被玩家攻击分析Bot怪 1 当游戏开始时 可以看到在编辑器时Bot怪是没有带武器的,是在游戏开始是把武器刷出来,放在手上的 2. 发现玩家 当游戏开始时,Bot怪就启动了一个0.5秒的定时器,执行CheckForPlayer去扫玩家, CheckForPlayer实现是简单的,就是计算Bot怪的头与玩家的Camero的距离,如果小于一个值,就认为是发

我的放浪大学生活

我的放浪大学生活 放浪的童年 我从小就是一个不喜欢学习的,懒惰的人,生活在一个普通的小镇上.爷爷经常激励我学习,若是我能考得年级的前十,他就会给我100元奖金,我可以用这些钱来买好玩的小霸王游戏卡.家里有一个大箱的手柄和游戏卡,魂斗罗,热血等游戏系列数不胜数. 当小镇上出现黑网吧时,我高兴地发现居然有比小霸王更好玩的电脑.因为家里不允许,我总是偷偷地窜去离家只有几百米的黑网吧,我只是静静地站在各个大龄孩子后看他们打游戏,那时流行<侠盗猎车手>,<跑跑卡丁车>和<CS>等

第十九篇:提高SOUI应用程序渲染性能的三种武器

SOUI是一套100%开源的基于DirectUI的客户端开发框架. 基于DirectUI设计的UI虽然UI呈现的效果可以很炫,但是相对于传统的win32应用程序中每个控件一个窗口句柄的形式,渲染效率是一个很重要的问题. 在SOUI系统中提供了三种武器可以用来提高渲染效率: 第一种武器:选择更高效的渲染引擎 渲染引擎提供文字,几何图形,图像的在缓存上的绘制功能.在SOUI系统中,渲染引擎是一个独立的模块,它不依赖于SOUI系统中的其它模块. 在SOUI系统中已经内置了基于skia及GDI两种框架的

一位云架构师用服务打动客户的故事之八「顾问式销售的三把武器」

今天接着上一次文章接着聊,开始之前了也聊聊上一篇文章的反馈情况,自从上一次对话方式的文章发布后,有非常多的正在前线的作战的销售伙伴们加我好友了,并通过邮件联系到我,表达了很多正在遇到的'困境',比如:我不懂技术,怎么能跟客户互动好?.我是个技术,但是我就是跟别人不来电,不知道怎么开场? 文章收益人员:销售.售前.正在转型做销售的技术(售前) 其实有的人看性格,有的人看心情,也有的人看经验,但不得不说售前是一个急各种综合素质能力于一体的岗位,需要不断修炼自己,强行让自己走出舒适区的工种.包括我坚持

unity3d太空射击游戏----------《图形程序设计》课程设计说明书

广西科技大学 <图形程序设计>课程设计说明书             学生姓名:           江玉珍                  .    学    号:           201400404005           .         专    业:         数字媒体技术专业          . 班    级:            数媒141班             .    指导老师:              黄钟源               .    

Unity3D-第一视角射击游戏

一.新建关卡 File,Save Scene,File,New Scene,File,Save Scene as... ,Level02.unity 1.建立场景 从Assets中拖放场景模型到Hierarchy中, 2.为游戏体添加多边形碰撞体 在Hierarchy中选择3个构造游戏空间的游戏体,Component,Physics,Mesh Collider,操作后,游戏空间游戏体可以用于物理碰撞检测. 3.创建灯光 现在游戏空间内光线不好,调整一下, 1)创建电光源 根据需求,创建若干.可使