首页 文章

老式游戏如何与墙壁,地板和天花板进行碰撞检测?

提问于
浏览
21

我一直在阅读有关stackoverflow和其他网站上的游戏中的碰撞检测 . 他们中的很多人都谈论BSP,边界线,整合等等 . 然而,在NES上,他们设法在游戏中进行地板和墙壁碰撞检测,我发现很难相信他们做了很多计算来检测墙壁碰撞 .

我想我的问题是,考虑到仅由瓷砖组成的水平,它们是如何检测像Mario和Megaman这样几乎没有处理能力的游戏中与墙壁和地板的碰撞?

  • 他们是否遵循运动路径并确定最近的连接瓦片? (有点搜索)(先验)

  • 他们是否确定了与地板的碰撞,然后找出调整角色的最佳方法? (后验)这对于可变的时间步长是有风险的,如果你足够快,你可以跳过一个瓦片 . 虽然我认为NES游戏的时间步长与电视的刷新率同步 .

  • 重力总是影响你的角色're on the ground? Or do you just '关闭' when you'重新决定走在瓷砖上?当你走出悬崖边缘时呢?你需要某种方法来确定你下面的瓷砖 .

  • 如果你与瓷砖相撞,你会找到该瓷砖的边缘并将你的角色移到它的侧面(取决于行进方向)吗?

  • 超级地铁和马里奥的倾斜瓷砖怎么样?

  • 怎么样'platforms'你可以跳到底部并降落在顶部 . 如果你这样做,你将如何处理与这些瓷砖的碰撞'posteriori'?

我写了一些基本上是'先验'的碰撞代码,因为它会搜索你将在某个方向上击中的第一个图块 . 我只是想知道是否有更好的方法 . (可能只是使用事后碰撞检测)

例如,检查瓷砖碰撞向下移动的代码(我检查垂直然后水平移动):

def tile_search_down(self, char, level):
        y_off = char.vert_speed
        assert y_off > 0

        # t_ are tile coordintes
        # must be int.. since we're adding to it.
        t_upper_edge_y = int( math.ceil((char.y+char.h) / self.tile_height ) ) #lowest edge
        while (t_upper_edge_y*self.tile_height) < (char.y+char.h+y_off): # lowest edge + offset

            t_upper_edge_x = int( math.floor(char.x/self.tile_width) )
            while (t_upper_edge_x*self.tile_width) < (char.x+char.w):

                t_x = t_upper_edge_x
                t_y = t_upper_edge_y 
                if self.is_tile_top_solid(t_x, t_y, plane):
                    char.y = t_y*self.tile_height - char.h
                    char.vert_speed = 0.0
                    char.on_ground = True
                    return

                t_upper_edge_x += 1
            t_upper_edge_y += 1

        char.y += y_off

3 回答

  • 13

    对于你所谈论的NES时代游戏的类型,一切都是2D . 仅这一点就简化了许多事情 .

    那个时代的某些机器(特别是具有硬件精灵的机器,如Commodore 64)具有硬件碰撞检测功能 . 大多数不依赖于硬件冲突检测的游戏都会使用边界框或命中掩码(精灵的1位位图) .

    无论哪种方式,碰撞检测通常都是“后验”,除了像世界边缘这样的特殊情况 . 有些游戏确实存在错误,当你击中某些东西时移动得太快可能会导致你通过它 . (事实上,对80年代早期游戏的评论通常会评论碰撞检测的准确程度 . )

    对于平台游戏,您通常会在应用重力之前检查角色是否“接地” .

    由于您知道精灵的速度向量,所以单向平台事情并不难以处理,因此您可以使用它来确定碰撞是否应该注册 .

  • 14

    这里有一篇文章深入探讨了任天堂娱乐系统(NES)"platform game"的编程 .

    我可能没有正确搜索,因为我之前没有偶然发现这篇文章 .

  • 19

    对于超级马里奥世界(SNES)等游戏,游戏以内存格式存储级别,以便轻松获取Mario的X / Y位置,将其转换为平铺地址,然后立即检查该地址周围的平铺 . 由于水平始终是固定宽度(尽管您可以查看的区域各不相同),因此它使寻址更容易管理,因为它总是与马里奥位置的固定偏移,例如马里奥旁边的瓷砖地址为1,他下面的瓷砖地址为0x300,等等 .

相关问题