侧滚动游戏的数据结构

时间:2011-03-27 04:42:57

标签: flash actionscript-3

我只是想知道用于在侧滚动游戏中表示数据对象的最佳数据结构是什么,基本上用户看不到的东西不在舞台上所以我通常会创建一个自定义类来定义它的属性(x,y,weight,type,derp等),然后将其推入数组中,当用户向前移动时,我会检查数组中的信息,同时检查它们的x位置是否合适。

可能出现的问题是用户可以左右移动,那么最好的方法是跟踪索引吗?

由于

2 个答案:

答案 0 :(得分:1)

因此,您拥有大量对象的长级别,并且您不希望线性检查所有对象以查看屏幕上应该显示的内容。您需要将数据拆分为块并列出这些块。它让我想起Quadtrees,如果你的射手是线性的,那么你的树就会变成1D而且实现起来更简单。

您可能会使用的结构:

节点 - 包含范围(xmin,xmax)和子节点或叶子列表。所有节点都插入到层次结构中,其中根节点是整个游戏世界/级别,根节点是区域,然后是子区域等。树中的级别数取决于对象的数量。

Leaf - 也有范围,包含与此区域对应的数据对象。

构建此树时,从给定范围中找到对象应该花费O(log N)时间。

编辑:我会尝试说明它以便更清楚。

如果您的等级为1D,则不需要完整的四叉树,只需要线性树:

                  root node, xmin = 0, xmax = 1000
                   contains list of regions:
                  /   |   \
                 /    |    \
    region 1,         |     \
xmin = 0, xmax = 300  |      \
                      |       \
                region 2,      \
              xmin = 301,       \
              xmax = 650         region 3, xmin = 651, xmax = 1000
                                  |                   |
                   Leaf, xmin = 652, xmax = 850       |
                   list of objects                 Leaf, xmin = 851, xmax = 1000
                   in that range                   list of objects

public class GameObject
{
    public var x:Number;
    //other stuff
}

public class Node {
    public var xmin, xmax:Number;
    public var children:Vector.<Node>;

    public function writeObject(object:GameObject):void
    {
        for each (var node:Node in children)
        {
            //find node with corresponding range
            if (node.xmin > object.x && node.xmax <= object.x)
            {
                node.writeObject(object);
                return;
            }
        }
        throw new Error("Children not found!");
    }

    public function findObjects(xmin:Number, xmax:Number):Vector.<GameObject>
    {
        //there comes the tricky part
        //1. build list of leaves in that range
        //2. filter first and last leaf (they may be only partially in the range)
        //3. copy objects from leaves between first and last as is
        //4. return list of objects
    }
}

public class Leaf extends Node {
    private var objects:Vector.<GameObject>;

    public function writeObject(object:GameObject):void
    {
        objects.push(object);
    }
}

首先,您需要创建树中连接的节点,根据您的级别选择区域数量。然后你将你的对象写入结构并仔细思考如何在以后获得它们:)

答案 1 :(得分:0)

当你说“阵列中的项目信息”时,你的意思是什么?您想将该信息显示给播放器还是只是想让它可供使用?如果你只想要它可用:

如果你必须跟踪数组的索引,你可以做一些元素匹配 - 通过你的数组来查找屏幕上显示的第一个元素,然后在屏幕上添加对象的数量用于查找最后一个元素的数字。这需要跟踪显示的元素,但可能需要通过自定义类中的布尔值。

但是,经过反思,你真的需要跟踪指数吗?如果玩家可以向后或向前移动,并且屏幕上可以有可变数量的对象,则最好在每个帧上迭代整个数组并检查有效的x / y值;如果x / y在阶段范围内,则显示该对象。使用此方法,您可以轻松地在屏幕上显示元素[2]和元素[89],即使中间的值已消失。 (例如,如果那些滚动屏幕外,但元素[2]跟随玩家角色因此保留在屏幕上。)这样,您可以避免担心数组键和左/右移动。基本上...

//psuedocode.
for each in Array {
   if {x/y aren't valid) don't display;
   else display;
}

如果所有对象都属于一种类型(或从一种类型继承),使用Vector来保存对象会使速度更快。

我希望这是有道理的,我希望我理解你的问题,但它已经很晚了,我真的很累,所以如果没有,我很抱歉。让我知道。