分离转向算法

时间:2016-01-22 01:32:59

标签: c# algorithm generator unity5

好的,所以这个网站在我开个帐户之前帮了我很多,但现在网络没有帮助我,所以我自己发布:)

我正在寻找(我还是另一个人)做这样的事情: tinykeep.com/dungen /

现在第一步(生成房间,顺利),但这是我第一次遇到植绒行为算法,我的数学真的不是那么棒。

所以我尝试并提出了一种非工作算法,我所做的是从下一个标准分离算法开始:gamedevelopment.tutsplus.com/tutorials/the-three-simple-rules-of-flocking-behaviors-alignment- cohesion-and-separation - gamedev-3444(对不起这篇文章,但它不会让我发布超过2个链接而没有10个代表),并且改变了我的喜好。就像我之前所说的那样,如果我发现我将如何发布一些调试结果,它真的没有做任何事情。

这是我的代码:

class Room {

Vector3 position;
Vector3 size;
int area;

public Room(Vector3 position, Vector3 size, int area) : this(position, size){

    this.area = area;

}

public Room(Vector3 position, Vector3 size){

    this.position = position;
    this.size = size;
    if(area != null)
        this.area = (int)(size.x * size.z);

}

public Vector3 GetPosition(){

    return position;

}

public Vector3 GetSize(){

    return size;

}

public void SetPosition(Vector3 position){

    this.position = position;

}

public Boolean TooCloseTo(Room room){

    return position.x + size.x / 2 > room.GetPosition().x - room.GetSize().x / 2 || position.z + size.z / 2 > room.GetPosition().z - room.GetSize().z / 2 ||
        position.x - size.x / 2 < room.GetPosition().x + room.GetSize().x / 2 || position.z - size.z / 2 < room.GetPosition().z + room.GetSize().z / 2;

}

public override string ToString ()
{
    return string.Format ("[Room]\nPosition:{0}\nSize:{1}\nArea:{2}", position, size, area);
}

}

这些是Mapgenerator类的一部分,这个类的其余部分工作正常,对我来说似乎并不重要,但如果你觉得有必要看到它,请告诉我,我会发布它。

void SeparateRooms(){

    foreach (Room room in rooms) {

        //Debug.Log (room);
        Vector3 oldPos = room.GetPosition ();
        Vector3 separation = computeSeparation (room);
        //Debug.Log (separation);
        Vector3 newPos = new Vector3 (oldPos.x += separation.x, oldPos.y, oldPos.z += separation.z);
        room.SetPosition (newPos);
        //Debug.Log (room);

    }

}

Vector3 computeSeparation(Room agent) {

    int neighbours = 0;
    Vector3 v = new Vector3 ();

    foreach (Room room in rooms) {

        if (room != agent) {

            if (agent.TooCloseTo (room)) {

                v.x += Difference(room, agent, "x");
                v.z += Difference(room, agent, "z");
                neighbours++;

            }

        }

    }

    if (neighbours == 0)
        return v;

    v.x /= neighbours;
    v.z /= neighbours;
    v.x *= -1;
    v.z *= -1;
    v.Normalize ();
    return v;

}

float Difference(Room room, Room agent, string type){

    switch (type) {

    case "x":
        float xBottom = (room.GetPosition ().x + room.GetSize ().x / 2) - (agent.GetPosition ().x - agent.GetSize ().x / 2);
        float xTop = (agent.GetPosition ().x + agent.GetSize ().x / 2) - (room.GetPosition ().x - room.GetSize ().x / 2);
        return xBottom > 0 ? xBottom : xTop;
        break;
    case "z":
        float xRight= (room.GetPosition ().z + room.GetSize ().z / 2) - (agent.GetPosition ().z - agent.GetSize ().z / 2);
        float xLeft= (agent.GetPosition ().z + agent.GetSize ().z / 2) - (room.GetPosition ().z - room.GetSize ().z / 2);
        return xRight > 0 ? xRight : xLeft;
    default:
        return 0;
        break;

    }

}

我期待差异是像4.0和8.0这样的数字,依此类推,我得到0.9和0.3等等,我将复制一个输出: Debug log

我希望这是可读的。 说明:每三行是关于房间的信息:     1.原来的房间     2.房间和下一个房间之间的重叠(应该是什么)     3.房间的新位置

编辑:好的,感谢评论我现在得到了非常正常的重叠结果,但是在运行算法后房间仍然重叠,我想这可能只需要在每个房间迭代一次......对此有何评论?

我真的希望你们中的一些人能够指出我正确的方向,或者告诉我在推理中出了什么问题。

谢谢!

编辑:填满房间:

public void Generate(int level) {

    int levelModifier = (int)(Math.Round ((double)Mathf.Log (level, 2.5f),1) * 10);
    int mean = 25;
    int SD = 5;
    for (int i = 0; i < 30 + levelModifier; i++) {

        Vector3 position = getPInCircle (20);

        int area = (int)SimpleRNG.GetNormal (mean, SD);
        if (area < mean - SD)
            continue;

        Vector3 size = calculateSize (area);

        Room room = new Room (position, size);

        rooms.Add (room);

    }

    SeparateRooms ();


}

Vector3 calculateSize(int area) {

    float k = UnityEngine.Random.Range (2.0f, area / 2.0f);
    float l = area / k;
    int shortSide;
    int longSide;
    if (Mathf.Round (k) > Mathf.Round (l)) {

        shortSide = Mathf.RoundToInt (k);
        longSide = Mathf.RoundToInt (l);

    } else {

        shortSide = Mathf.RoundToInt (l);
        longSide = Mathf.RoundToInt (k);

    }

    //Debug.Log (shortSide);
    //Debug.Log (longSide);

    Vector3 size;

    if (SimpleRNG.GetUniform () < 0.5) {

        size = new Vector3 (Actualise(shortSide), 0, Actualise(longSide));

    } else {

        size = new Vector3 (Actualise(longSide), 0, Actualise(shortSide));

    }

    return size;

}

SimpleRNG是John D. Cook的命名空间,可从www.codeproject.com/Articles/25172/Simple-Random-Number-Generation下载

0 个答案:

没有答案