Optimization 从嵌套状态转换到嵌套状态的最佳实践(参见图表)
我正在尝试用单线程编程语言(Actionscript)实现嵌套状态转换的最佳方法。假设我有这样一个行为树结构: 现在,假设每个叶节点都是网站上的目标点,就像图库中的图像,或者页面视图中嵌套的帖子视图中嵌套的注释。。。我们的目标是能够通过设置上一棵树的动画(从下到上)和当前树的动画(从上到下),运行从叶节点到叶节点的动画转换 因此,如果我们位于最左下角的叶节点,并且我们想要转到最右下角的叶节点,我们必须:Optimization 从嵌套状态转换到嵌套状态的最佳实践(参见图表),optimization,actionscript,state-machine,hsm,behavior-tree,Optimization,Actionscript,State Machine,Hsm,Behavior Tree,我正在尝试用单线程编程语言(Actionscript)实现嵌套状态转换的最佳方法。假设我有这样一个行为树结构: 现在,假设每个叶节点都是网站上的目标点,就像图库中的图像,或者页面视图中嵌套的帖子视图中嵌套的注释。。。我们的目标是能够通过设置上一棵树的动画(从下到上)和当前树的动画(从上到下),运行从叶节点到叶节点的动画转换 因此,如果我们位于最左下角的叶节点,并且我们想要转到最右下角的叶节点,我们必须: 转出左下角节点 完成后(比如在动画播放一秒钟后),将其转换为其父对象 完成后,将其转换为父
- 转出左下角节点
- 完成后(比如在动画播放一秒钟后),将其转换为其父对象
- 完成后,将其转换为父级
- 完成时,在最右侧的父级中进行转换
- 完成时,在最右边的子对象中进行转换
- 关于叶的完全过渡
- 在对象上,他们从何处调用“transitionOut”?从根目录还是特定的子目录
- 状态存储在哪里?全球,本地?定义调用“transitionIn()”和“transitionOut()”的范围是什么
注意:我不是在尝试构建游戏,只是在尝试构建动画网站。我只是在这里猜测,但您可以将该树存储在代码中的实际树中,然后,当单击要导航时,调用一个名为findPath(fromNode,toNode)的函数,该函数将查找两个节点之间的路径,一种方法是使用以下伪代码:
Define array1;
Define array2;
loop while flag is false {
store fromNode's parent node in array1;
store toNode's parent node in array2;
loop through array1 {
loop through array2 {
if array1[i] == array2[j] {
flag = true;
}
}
}
}
path = array1 + reverse(array2);
function checkChildren(targetNode) {
loop through children {
if children[i] == target {
return path;
}
if children[i].checkChildren == target node {
return path;
}
}
}
这就是你的道路
更新:
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
}
另一个解决方案是让每个页面都有类似于此的伪代码——我开始真正喜欢伪代码了:
Define array1;
Define array2;
loop while flag is false {
store fromNode's parent node in array1;
store toNode's parent node in array2;
loop through array1 {
loop through array2 {
if array1[i] == array2[j] {
flag = true;
}
}
}
}
path = array1 + reverse(array2);
function checkChildren(targetNode) {
loop through children {
if children[i] == target {
return path;
}
if children[i].checkChildren == target node {
return path;
}
}
}
这是非常抽象的,它有很多细节和很多优化,以下是我的想法:
- 将路径向上传递到函数,以便直接找到路径,而不是返回到调用函数
- 将当前正在调用的子项传递给父项checkChildren,这样它就不会麻烦检查该子项,从而加快检查速度
package {
public class Transition {
///Array of animation starting functions
private var funcs:Array;
///Function to call at the end of the transition
private var callback:Function;
public function Transition(from:ITransitionable, to:ITransitionable, callback:Function) {
this.callback = callback;
this.funcs = [];
var pFrom:Array = path(from).reverse();
var pTo:Array = path(to).reverse();
while ((pFrom[0] == pTo[0]) && (pTo[0] != null)) {//eliminate common path to root
pFrom.shift();
pTo.shift();
}
pFrom.reverse();//bring this one back into the right order
//fill the function array:
var t:ITransitionable;
for each (t in pFrom) this.funcs.push(hider(t));
for each (t in pFrom) this.funcs.push(shower(t));
this.next();
}
///cancels the overall transition
public function cancel():void {
this.funcs = [];
}
///creates a function that will start a hiding transition on the given ITransitionable.
private function hider(t:ITransitionable):Function {
return function ():void {
t.hide(this.next());
}
}
///@see hider
private function shower(t:ITransitionable):Function {
return function ():void {
t.show(this.next());
}
}
///this function serves as simple callback to start the next animation function
private function next(...args):void {
if (this.funcs.length > 0) this.funcs.shift()();
else this.callback();
}
///returns the path from a node to the root
private function path(node:ITransitionable):Array {
var ret:Array = [];
while (node != null) {
ret.push(node);
node = node.parent;
}
return ret;
}
}
}