V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
admin7785
V2EX  ›  程序员

射击类游戏的算法原理

  •  
  •   admin7785 · 2019-09-10 22:28:19 +08:00 · 4152 次点击
    这是一个创建于 1901 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小白一枚,对射击类游戏比较感兴趣,有以下几个问题想问问宝贝们:

    • 游戏内如何判断子弹打到人?
    • 所谓的子弹下坠是某个函数实现的吗?
    • 如果是三维坐标的话,人物移动和互相射击是要根据此刻的坐标来判断吗?
    • 如果用坐标判断的话,两个人同时互相射击,怎么判断出谁先存活(这里是和信息传输有关吗?)

    你们的小宝贝先谢谢各位宝贝们,摸摸大

    14 条回复    2019-09-11 20:19:46 +08:00
    Chell
        1
    Chell  
       2019-09-10 22:40:42 +08:00
    admin7785
        2
    admin7785  
    OP
       2019-09-10 22:43:00 +08:00
    @Chell 好的谢谢,一直在找相关资料,可惜国内相关网站没找到太多有用的,我先看看您这个。
    across
        3
    across  
       2019-09-10 22:49:54 +08:00
    上面说的是联机状况,要考虑网络同步,比较复杂。

    在单机下
    1. 射线检测。 射线和多边形碰撞检测算法。
    2. 是。和重力叠加一个道理。不过一般数值和现实不一样,看情况调的。
    3. 是。世界坐标内,知道彼此位置,发射方向和距离就可以判断结果。
    4. 看时间顺序。按键触发事件,处理事件时,哪个先接收到就是哪个先处理,但是子弹射出来了····人死了又不会带走开的枪····(网络中会同步时序)

    你需要先修数学···· 3D 空间几何和线性代数。
    zhujinliang
        4
    zhujinliang  
       2019-09-10 22:59:54 +08:00 via iPhone
    1. 数学计算,子弹可视为点,身体可视为圆柱,头可视为球,计算弹道与圆柱、球是否相交,相交就是会命中
    2.调一个近似的曲线差不多就可以了
    3 和 4. FPS 游戏一般是客户端计算,玩家的坐标都是公开的(不论 3D 场景中是否看得见),一个玩家发生了数据改变(移动、发射子弹等),以类似广播的形式告知其它玩家。一般延迟越低的玩家越沾光。

    中间还有一个问题,一般角色移动还有个预测过程:数据同步再快也有延迟和同步周期问题,中间这段的玩家动作靠预测算法填补的,与实际对手操作情况可能有不同,具体如何判定命中还得考虑多种因素,要不玩家会觉得明明我瞄的很准却打不中,或者我已经躲起来了,却还被“抓”回去中枪了,以前玩 CS 有这种不好的体验。
    当然根本原因还是“卡”,延迟低到几毫秒比啥算法补偿都强
    justfortest
        5
    justfortest  
       2019-09-10 23:14:18 +08:00
    《实时碰撞检测算法技术》
    《 game programming gems 》
    欢迎阅读,然后你发现游戏是个大坑( ﹁ ﹁ ) ~→
    xiri
        7
    xiri  
       2019-09-11 09:14:41 +08:00
    对于第四点,现在高级一些的射击游戏还需要考虑不同枪的子弹射速
    whp1473
        8
    whp1473  
       2019-09-11 11:01:42 +08:00
    碰撞检测算法。。。简单图形还好,多边形貌似很复杂
    blindie
        9
    blindie  
       2019-09-11 11:10:36 +08:00
    拿 unity 举例,首先要看游戏的子弹是激光枪那种还是模拟的物理子弹头

    游戏内如何判断子弹打到人?
    - 激光:判断一下 raycast 和 enemy object 的 collider 是否在按下扳机时相交即可( 3D 方法,基本用这个)。或者在 viewport 上判断鼠标点在 object 上( 2D 方法)。都可以做。
    - 实弹:从枪口生成一个子弹 rigidbody 给与其初速、重量、air-drag,然后 FixedUpdate 的时候判断子弹和 enemy object 的 collider 是否相交。这里有一个问题是子弹速度过快的时候会穿过但是没检测到 collide。这个有方法解决,比较细节。
    所谓的子弹下坠是某个函数实现的吗?
    - 激光:没有下坠
    - 实弹:rigidbody 设置了初速、重量、air-drag 后,unity 会自己运算。简单下坠自己写就是初中物理 v 垂直 = 1/2 * g * t * t
    如果是三维坐标的话,人物移动和互相射击是要根据此刻的坐标来判断吗?
    - 如果看懂上面两个回答的话,就不会有这个问题。非要回答就是激光在 trigger 的时候已经计算出了结果,实弹是看每次 FixedUpdate 的时候子弹和 enemy 是否相交,出膛了之后跟射击者位置是没关系的。
    如果用坐标判断的话,两个人同时互相射击,怎么判断出谁先存活(这里是和信息传输有关吗?)
    - 这个就是看游戏制作方的个人喜好了。怎么都行。实弹那个很简单,子弹打到 target,target 就暴毙,跟 shooter 是否还活着没关系。但是像吃鸡如果在子弹打到 target 上 shooter 已经死亡了,target 的视角上有飙血动画但是不会扣血。
    admin7785
        10
    admin7785  
    OP
       2019-09-11 17:43:36 +08:00
    @zhujinliang 谢谢。对于 4:角色移动之后,以广播形式路由的话,那是不是每个终端(每个用户)都要去重新获取其他用户数据,还要实时计算,这样的话服务器能抗住?毕竟百人游戏的话,每个用户收到消息的时候都需要实时重新计算,不知道理解有没有错,谢谢。
    admin7785
        11
    admin7785  
    OP
       2019-09-11 17:44:47 +08:00
    @xiri 对啊,不过感觉这些都是常量,实现的时候用公式就行,只不过逻辑稍微复杂些。
    admin7785
        12
    admin7785  
    OP
       2019-09-11 17:53:00 +08:00
    @blindie 谢谢。不太了解游戏引擎,只是单纯好奇,哈哈。感觉这些游戏逻辑太复杂了......
    blindie
        13
    blindie  
       2019-09-11 18:06:37 +08:00
    服务器的建设和信息传递方式不是我研究的方向,不过你有兴趣可以看看云风写的这一篇 https://blog.codingnow.com/2018/08/lockstep.html
    admin7785
        14
    admin7785  
    OP
       2019-09-11 20:19:46 +08:00
    @blindie 好的,十分感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2734 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:58 · PVG 22:58 · LAX 06:58 · JFK 09:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.