美文网首页
实现子弹或敌人跟踪

实现子弹或敌人跟踪

作者: 与时间赛跑_ | 来源:发表于2018-09-24 20:01 被阅读0次

    hello,一些游戏中经常有一些自动跟踪的子弹,一旦发射,就一定可以命中到玩家,同时玩家也是不断运动的,看看效果吧,这里我随便找了一张小图当作子弹或者敌人。

    比如王者荣耀的水晶的攻击玩家。

    解决这个问题,首先先来分析一下怎么去设计。

    首先玩家是不断运动的,子弹在运动的时候需要改变自己的运动轨迹。

    子弹在发射的时候总是跟踪着玩家,而且一定会命中

    小code到了这一篇,差不多讲完了一个飞行射击游戏的一些常用功能。

    这里需要分析4中情况。

    1

    2(原来可以用箭头和形状啊)

    3

    4

    在每一种情况子弹/敌人的步进方向都不一样。

    步进,可以简单理解为各在x , y轴方向上各“走”多少像素。

    这里画一张图,方便理解

    这里我们只要确定好子弹的步进长度(可以理解为速度)因为它直观的表现出速度,哈哈

    然后,剩下的就交给3角函数吧

    但是在此之前,还要获取子弹/敌人与我们玩家的之间的角度

    看一张图

    分别求出A,B,C的坐标

    c点的坐标也很容易算出来。对于第1种情况(1图)计算如下

    然后可以写代码算出角度了

    我们应该在设计这种有跟踪行为的子弹的时候就设计好类

    class Emeny{

    public:

     static Emeny*create(int type);//创建方法,为静态

     virtual bool init(int type);//初始化方法

     void move(Point pos);//移动方法。通过传递进来玩家的坐标对玩家相对于子弹的方向做出判断

     Point getPos(Point pos);//返回x和y轴的步进

     float  getAngle(Point pos1,Point pos2,Point pos3); //得到玩家相对于子弹的角度

    private:

    float speed;//子弹步进

    }

    实现文件

    Emeny*Emeny::create(int type){

    //这是一种防御的写法,一起的文已经有写过了,这里偷懒就不在写了

     auto emeny=new Emeny();

     if(emeny&&emeny->init(type)){ 

            emeny->autorelease();

     return emeny;

        }else{

         delete emeny;

     return NULL;

        }

    }

    bool Emeny::init(int type){

     speed=1;//初始化步进长度

     if(type==1){

    //判断参数实现子弹类型

     this->initWithFile("blueemeny.png");

     setHp(10);

        }

     if(type==2){

     this->initWithFile("abouton.png");

        }

    //把它放在一个位置,这里我直接放在随便一个位置

     this->setPosition(Point(240,160));

     this->setAnchorPoint(Point(0.5,0.5));//设置锚点

     return true;

    }

    void Emeny::move(Point pos){

     this->setPosition(this->getPosition()+getPos(pos));//这里是通过把传递进来的pos即是玩家的坐标,把它交给getPos()函数去获得各坐标轴的步进长度。

        //子弹或者敌人的运动方法

    }

    注意:因为控制篇幅,这里没有考虑子弹和玩家处于同一直线的原因,大家可以翻阅上次的360度子弹发射,这篇文章,其实是一样的。

    Point Emeny::getPos(Point pos){

     Point nextPos;//判断敌人或者子弹相对于玩家处于那个位置

    这里的情况是如下图(其他的也就是上面所说的4种情况之一,这里是通过他们各自所处的x,y轴的位置来判断他们的相对位置)

     if(this->getPositionX()>pos.x&&this->getPositionY()>pos.y){

     float rad=getAngle(pos,this->getPosition(),Point(this->getPositionX(),this->getPositionY()-(this->getPositionY()-pos.y)));// 把A,B,C三个点传递给getAngle()函数

     auto p=CC_DEGREES_TO_RADIANS(rad);

            //把角度转化成幅度

            nextPos=Point(-speed*cos(p),-speed*sin(p));//这种情况的x轴步进为-speed*cos(p),y轴的步进为-speed*sin(p),下面的情况也是差不多的

        }

     if(this->getPositionX()<pos.x&&this->getPositionY()<pos.y){

     float rad=getAngle(pos,this->getPosition(),Point(this->getPositionX(),this->getPositionY()-(this->getPositionY()-pos.y)));

     auto p=CC_DEGREES_TO_RADIANS(rad);

    nextPos=Point(speed*cos(p),speed*sin(p));

        }

     if(this->getPositionX()<pos.x&&this->getPositionY()>pos.y){

     float rad=getAngle(pos,this->getPosition(),Point(this->getPositionX(),this->getPositionY()-(this->getPositionY()-pos.y)));

     auto p=CC_DEGREES_TO_RADIANS(rad);

            nextPos=Point(speed*cos(p),-speed*sin(p));

        }

     if(this->getPositionX()>pos.x&&this->getPositionY()<pos.y){

     float rad=getAngle(pos,this->getPosition(),Point(this->getPositionX(),this->getPositionY()-(this->getPositionY()-pos.y)));

     auto p=CC_DEGREES_TO_RADIANS(rad);

            nextPos=Point(-speed*cos(p),speed*sin(p));

        }

     return nextPos;

    }

    /下面的代码根上次那个《实现360度摇杆。。》是一样的,这里就再重复了

    float Emeny::getAngle(Point pos1,Point pos2,Point pos3){

     float dx1,dx2,dy1,dy2;

     float angle;

        dx1=pos2.x-pos1.x;

        dx2=pos3.x-pos1.x;

        dy1=pos2.y-pos1.y;

        dy2=pos3.y-pos1.y;

     float c= sqrt(dx1*dx1+dy1*dy1)*sqrt(dx2*dx2+dy2*dy2);

     if(c==0){

         return -1;

        }

        angle=acos((dx1*dx2+dy1*dy2)/c)/(3.1415)*180;

     return angle;

    }

    到这里已经实现了所有的方法,现在就调用它吧

     auto  em1=Emeny::create(1);//创建一个子弹

    然后用一个时间调度器。在每一帧都执行它 的move方法

    这里假设玩家为_player

    emeny->move(_player->getPosition());通过这样已经写好了全部。

    其实这个算法不够高效,也存在一些精确问题,下次会有更加完善的方法分享给大家

    想制作属于自己的网页小导游吗?也可以说是萌宠,一定要持续关注哦

    (例子)

    我们会给她加入导航和问好等一系列语言和一些其他帮助功能,假如在参加网页设计赛事的时候用上,说不定会成为加分项哦

    拜拜~

    相关文章

      网友评论

          本文标题:实现子弹或敌人跟踪

          本文链接:https://www.haomeiwen.com/subject/zgshoftx.html