gpt4 book ai didi

optimization - 从嵌套状态过渡到嵌套状态的最佳实践(见图)

转载 作者:行者123 更新时间:2023-12-03 15:54:29 24 4
gpt4 key购买 nike

我正在尝试用一种线程编程语言(Actionscript)来实现嵌套状态转换的最佳方法。说我有一个像这样的行为树的结构:

现在,假设每个叶子节点都是网站上的目标点,例如画廊中的图像或嵌套在页面 View 中的帖 subview 中嵌套的注释……目标是能够从叶子中运行动画过渡动画前一棵树(从下到上),并动画当前树(从上到下),从节点到叶节点。

因此,如果我们位于最左下角的叶节点处,并且想转到最右下角的叶节点,则必须:

  • 过渡到左下节点
  • 完成后(例如动画播放一秒钟后),过渡到其父级
  • 完成后,将其转换为父
  • 完成后,在最右边的父
  • 中过渡
  • 完成后,过渡到最右边的 child
  • 完成后,叶
  • 中的过渡

    我的问题是:

    如果您将这些节点中的每个想象为HTML View (叶子是“partials”,从rails借用术语)或MXML View (您在其中嵌套子组件),则不必从应用程序根目录,如上所述,动画过渡的最佳方法是什么?

    一种方法是全局存储所有可能的路径,然后说“应用程序,过渡到该路径,过渡到该路径”。如果应用程序非常简单,则可以使用。这就是 Gaia的工作方式,一个Actionscript框架。但是,如果您希望它能够在任意嵌套的路径之间进行移入/移出,则不能将其全局存储,原因是:
  • Actionscript无法处理
  • 似乎不是很好的封装

  • 因此,这个问题可以改写为:如何从叶开始为最左边的叶子节点及其父节点设置动画,并从根开始为最右边的叶子节点动画?该信息存储在哪里(要过渡和过渡的内容)?

    另一个可能的解决方案是只说“应用程序,移出先前的子节点,完成后,过渡到当前子节点”,其中“子节点”是应用程序根目录的直接子节点。然后,应用程序根目录的最左侧子节点(具有两个子节点,每个子节点具有两个子节点)将检查其是否处于正确状态(如果“子节点”已“移出”)。如果没有,它将在它们上调用“transitionOut()” ...这样,所有内容将被完全封装。但似乎这将占用大量处理器。

    你怎么看?您还有其他选择吗?或者,您能否指出 AI Behavior Trees或“分层状态机”上的任何好的资源,它们描述了它们如何实际实现异步状态转换:
  • 他们从哪里调用对象的“transitionOut”?是来自根还是特定的 child ?
  • 状态存储在哪里?在全局范围内,在本地?定义什么称为“transitionIn()”和“transitionOut()”的范围是什么?

  • 我已经看过/读过许多关于AI和状态机的文章/书,但是我还没有找到描述它们如何在复杂的MVC面向对象项目中实际实现异步/动画过渡的信息,其中有数百个 View /图形参与了行为树。

    我应该从最父对象还是从子对象调用过渡?

    这是我检查过的一些内容:
  • An Architecture for Game Behavior AI: Behavior Multi-Queues
  • Hierarchical State Machines — a Fundamentally Important Way of Design
  • Programming Game AI by Example
  • Goal-Driven Agent Behavior
  • Advanced State Management by Troy Gardner
  • Troyworks' AS3 COGS Library
  • Popular Approaches to Behavior-Tree Design
  • Building Event-Driven Conditions for an Asynchronous Sensory System

  • 尽管这不一定是一个AI问题,但是没有其他资源描述如何将嵌套状态体系结构应用于网站。这些是最接近的东西。

    提出问题的另一种方式是:如何向应用程序广播状态更改?您将事件监听器放在哪里?在任意嵌套的 View 中,如何找到要为其设置动画的 View ?

    注意:我不是在尝试制作游戏,而只是在尝试制作动画网站。

    最佳答案

    在建议一种可能的方法之前,我将尝试简化问题。过渡似乎与 View 有关,而不与模型有关。如果我跳过转换并直接转到其他叶节点,则该应用程序仍然可以运行,但用户看不到任何视觉提示。因此,我建议您专门使用 View Controller 来保存当前分支和各种 View 的过渡。

    这可能是将两种过渡类型拆分为一种堆栈的更好方法,其中弹出过渡将返回到上一个节点,而推送过渡将在层次结构中前进。苹果公司使用类似的技术使用navigation view controller来管理导航应用程序。它基本上维护了用户遵循的到达特定节点的 View Controller 堆栈。当用户返回时,最上面的项目从堆栈中弹出,并且用户看到了上一个项目。如果用户在层次结构中更深入,则会将新的 View Controller 插入堆栈。

    您仍然需要一种全局方式来以轻量级的方式表示层次结构,而导航堆栈仅将当前可见的分支存储到叶节点。

    如果用户从一个叶节点转到另一个叶节点,则当前堆栈将弹出到公共(public)父节点。然后,将要求全局树结构获取从该父节点到新叶节点的路径。节点的此路径被推送到当前导航堆栈中,并且在推送每一项时,都会显示过渡。

    在一个简单的算法中,将有以下两种数据结构以及一种获取包含叶节点的整个分支的方法:

  • 树的全局表示形式
  • 当前分支
  • 的堆栈

    最初是 :
    stack = []
    tree = create-tree()

    算法:
    // empty current branch upto the common ancestor, root node if nothing else
    until stack.peek() is in leaf-node.ancestors() {
    stack.pop() // animates the transition-out
    }
    parent = stack.peek();
    // get a path from the parent to leaf-node
    path = tree.get-path(parent, leaf-node)
    for each node in path {
    stack.push(node) // animates the transition-in
    }

    更新:

    整个应用程序可以有一个导航 Controller ,也可以有多个这样的 Controller 。导航 Controller 只需要知道有一棵树可以公开某些操作即可。因此,您可以使用这些操作创建一个接口(interface),并让具体的子类实现该接口(interface)。

    我只能想到需要公开的两个操作(伪Java语法):
    interface Tree {
    List<Node> getAncestors(node);
    List<Node> findPath(ancestorNode, descendantNode);
    }

    这应该提供足够的抽象,以使导航 Controller 在全局树结构中戳入。要将其提升到一个新的水平,请使用 dependency injection,以便将树对象注入(inject)到导航 Controller 中,从而提高了可测试性并完全断开了树连接。

    关于optimization - 从嵌套状态过渡到嵌套状态的最佳实践(见图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2083516/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com