转自:http://blog.csdn.net/zhaixh_89/article/details/24031363

需求

追踪子弹是游戏中的一个相当重要的精灵。子弹追踪的实现本质上是要实时调整子弹的线速度和角速度,使其不断地照着接近目标的方向移动。

分析

子弹速度分为两类,一个线速度,一个是角速度。所谓追踪,就是在子弹更新的每一帧中,动态计算子弹和目标之间的位置关系,然后更新子弹当前的线速度,和把子弹本身绕着自己的中心点旋转一个角度,使子弹朝向和子弹速度方向一致。

这里我们的子弹每帧的旋转角度设定为1度。方向为顺时针或是逆时针根据其与目标之间的位置决定,例如目标在子弹的右上方,则子弹(每帧)顺时针旋转一度,如果在左上方,则逆时针旋转。当然实际计算过程我们可以根据向量运算决定方向。

而子弹的线速度需要通过计算子弹和目标之间的夹角得到,如果子弹和目标之间夹角不为0,那么子弹需要实时调整自己的速度的方向,我们这里也设定为每帧可以旋转1度(这个值和子弹自身的旋转要一样,才能保持子弹看来永远朝着自己的前方运动),在整个运动过程中,子弹的速率(速度的模值)必须是保持不变的。

另外我们需要加一些限制条件(自然的或者人为的限制):

  1. 子弹发射时需要寻找目标,子弹默认会寻找离自己最近的,并且不满足4.1和4.2两个条件的目标。

  2. 子弹如果没有找到目标的情况下发射出去了,则按照初始速度飞行。

  3. 子弹在运动过程中如果失去目标,则按照当前速度飞行。

  4. 子弹一旦锁定目标,就会一直追踪打击目标,直到击中目标或者当目标满足下面条件时放弃并重新寻找目标:

    4.1 目标离开屏幕范围

    4.2子弹与目标之间的夹角大于90度角度

实现

关键部分的实现,包括: 1. 搜索目标 2. 计算速度方向和目标之间的夹角 3. 计算子弹自身要打击到目标需要旋转的方向 4. 子弹运动函数,在这里把东西全串起来

1.搜寻敌人

C++ Code:

/** * 寻找目标,所有的敌人都保存在一个CCArray中,需要从中遍历得到满足条件的一个。 * @author [K.C.](http://i.kimiazhu.info) */ void httrackBullet::seekEnemy() { mTarget = NULL; //目标和子弹之间距离的平方值,之所以用平方值,因为这里只要判断大小,就不开方了。 float mindistanceSQ = mMindistanceSQ; //获取保存所有敌人的数组 CCArray* array = getArrayForEnemy(); for (int i = 0; i < array->count(); i++) //敌人都继承自我自定义的HTCollidablePart可碰撞部件 HTCollidablePart* enemy = (HTCollidablePart*)objectAtIndex(i); if (enemy->isCollidable() && enemy->isInsideWindow() calcAngle(getPosition()) <PI / 2)) /* * 判断满足条件: * 1. 敌人可碰撞(就是可以被打击) * 2. 敌人在当前窗口可视范围内 * 3. 目标和敌人的角度小于90度 */ distanceSQ = ccpdistanceSQ(getPosition(), this->getPosition());distanceSQ < mindistanceSQ) distanceSQ; enemy; } }

2.计算角度

/** * 计算速度方向和目标之间的夹角 * @author [K.C.](http://i.kimiazhu.info) */calcAngle(CCPoint target) r = PI; CCPoint p2 = ccpsub(target,0);border-width:0px;vertical-align:baseline;"> ccpAngle(speed,0);border-width:0px;vertical-align:baseline;"> p2); //计算夹角r是弧度值,不是角度值 return r;3.计算子弹自身旋转方向 
 

/** * 计算子弹自身要打击到目标需要旋转的方向 * @author [K.C.](http://i.kimiazhu.info) */ RotateDirectioncalcDirection(CCPointccpCross( p2) > 0) // 在opengl的右手坐标系中,向量叉乘大于0表示逆时针方向 COUNTERClockwise; else Clockwise; NO_ROTATE;4.子弹每帧移动 
 

/** * 子弹运动 * @author [K.C.](http://i.kimiazhu.info) */move() domTarget)mTarget->isdamaged() ||getPositionX() <=getPositionY() 0)) break; //step 1:确定角度 _rad =_rad && _rad >= PI / 2) //角度大于90的时候放弃,不追踪 _deg = CC_radians_TO_degrees(_rad); deltaR = _rad < mDeltaradians ? _rad : mDeltaradians; deltaD = _deg < mDeltaDegree ? _deg : mDeltaDegree; //step 2:确定方向 switchcalcDirection(getPosition())) case COUNTERClockwise: speed = ccpRotateByAngle( ccp(0,0),0);border-width:0px;vertical-align:baseline;"> deltaR);setRotation(this->getRotation() - deltaD); Clockwise:deltaR); + default: seekEnemy(); while (0);setPosition(ccpAdd( speed)); }

实现Cocos2d-x追踪子弹的更多相关文章

  1. Pygame游戏开发之太空射击实战子弹与碰撞处理篇

    相信大多数8090后都玩过太空射击游戏,在过去游戏不多的年代太空射击自然属于经典好玩的一款了,今天我们来自己动手实现它,在编写学习中回顾过往展望未来,下面开始讲解子弹与碰撞处理,在本课中,我们将添加玩家与敌人之间的碰撞,以及添加供玩家射击的子弹

  2. html5学习--实现坦克可以连续发射子弹

    总结以上是DEVMAX为你收集整理的html5学习--实现坦克可以连续发射子弹全部内容。如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  3. 实现Cocos2d-x追踪子弹

    子弹追踪的实现本质上是要实时调整子弹的线速度和角速度,使其不断地照着接近目标的方向移动。这里我们的子弹每帧的旋转角度设定为1度。子弹如果没有找到目标的情况下发射出去了,则按照初始速度飞行。子弹在运动过程中如果失去目标,则按照当前速度飞行。

  4. 仿《雷霆战机》飞行射击手游开发--子弹、跟踪导弹和激光

    子弹是直线飞行的;导弹会自动跟踪目标,可曲线飞行;而激光是一道光束,可持续地对照射到的敌机产生伤害。子弹根据一次性发射的数量,可分为单发和多发,根据子弹发射的方向可分为:自动瞄准、平行、散射。程序设计先看一下本游戏中有关武器的类的设计其中,BulletGroup可理解为弹匣,Bullet就是其中一颗一颗的子弹,每颗子弹都有相同的属性,包括外观、伤害值以及飞行属性。继承自ScatterBullet,但是初始发射角度指向距离最近的敌机。

  5. 【cocos2d-x 3.7 飞机大战】 决战南海I (五) 添加子弹

    我方飞机的子弹和敌机子弹都在这个类中产生。将子弹专门设计成一个类,主要是为了方便扩展。之后如果想更换我方飞机子弹或者是敌机子弹,都会很方便。接下来实现添加子弹的功能注意不要将添加我方飞机子弹和添加敌机子弹放在一个函数中,那样不仅使代码混乱,而且不利于扩展。

  6. 飞机大战开发04子弹与敌机的碰撞检测

    先是敌机与玩家子弹的碰撞检测:代码:GameLayer.h这样游戏逻辑的基本功能就写完了,后面主要会研究下弹幕。

  7. 飞机大战03之飞机发射子弹,添加敌人

    这就需要对子弹的运动轨迹进行控制。先做一个最简单的子弹发射,后面再添加各种弹幕说是最简单,其实也是最普通的子弹发射,产生一个颗子弹移动就OK了。

  8. jquery – 需要调整自举转盘并使其子弹起作用

    我有一个文本转盘需要对齐,也不知道如何使其子弹活跃.通过点击下面的演示链接,您会看到项目符号不在页面的中间,并根据名称和文本的大小,名称和项目符号之间的距离得到更改.我需要所有的(文本,名称,项目符号)在页面的中间任何屏幕尺寸.DemoUpdateddemoUPDATE我将子弹的代码更改为以下内容,并使其移动到顶部.(在文字的中间)解决方法只需一些更改,使其全部工作:1)零索引.从0开始data-

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部