Avatar
matesax
Redaktor
Avatar
matesax:

Dobrý den,
zdá se, že se mi podařilo splácat funkční algoritmus, ale jaksi to má menší háček - cesty se budují pohledem na příští políčka. (Jejich náhodným výběrem a kontrolu.) Takže mezi políčky mi nevznikají mezery. (stěny) Když se ale budu dívat jak o jedno kolem, tak i o dva kolem - a pak tam dělat nějaké podmínky - či tak, tak to asi nebude dobré řešení... :) Jak na to? Děkuji.

public List<Vector2> GenerateMaze(Rectangle bounds)
{
    List<Vector2>
        paths = new List<Vector2>(),
        potential = new List<Vector2> { new Vector2(0, 0) };

    Vector2[] neighbors = new Vector2[] { new Vector2(1, 0), new Vector2(-1, 0), new Vector2(0, 1), new Vector2(0, -1) };

    while (paths.Count < (bounds.Width / 32) * (bounds.Height / 32))
    {
        Vector2 doc = potential[r.Next(potential.Count - 1)];

        if (!paths.Contains(doc))
        {
            foreach (Vector2 neighbor in neighbors)
                if (!paths.Contains(doc + neighbor))
                    potential.Insert(r.Next(potential.Count), doc + neighbor);

            paths.Add(doc);
        }

        potential.Remove(doc);
    }

    return paths;
}

Proč je tam "if (!paths.Conta­ins(doc))"? To proto, že to chci maximálně náhodné - takže když si nějaké políčko zabere cestu, ale jiné mu ji překazí, tak by došlo k selhání. Takže jsem to mohl zarazit v jedné podmínce - zde:

if (!paths.Conta­ins(doc + neighbor))

Ale jak píši - chtěl bych to co nejnáhodnější...

Editováno 20.10.2012 21:51
 
Odpovědět 20.10.2012 21:48
Avatar
matesax
Redaktor
Avatar
matesax:

Pro jistotu to ještě nakreslím. :)

Základ:

000000...
000000...
000000...
000000...
.........

Moje dělá:

111111...
111111...
111100...
111111...
.........

Potřebuji:

100100...
110111...
101100...
111000...
.........

 
Nahoru Odpovědět 20.10.2012 22:02
Avatar
matesax
Redaktor
Avatar
matesax:

Tak opět sám. :)

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using System;

public class MazeGenerator
{
    private Random r = new Random();

    public List<Vector2> GenerateMaze(Rectangle bounds)
    {
        List<Vector2> paths = new List<Vector2>() { new Vector2(0, 0) };

        Dictionary<Vector2, int> potential =  new Dictionary<Vector2,int>();

        Vector2[] neighbors = new Vector2[] { new Vector2(1, 0), new Vector2(-1, 0), new Vector2(0, 1), new Vector2(0, -1) };

        for (int index = 0; index < 4; index++)
            potential.Add(neighbors[index], index);

        while (paths.Count < 1000)
        {
            Vector2
                oldItem = new Vector2(),
                newItem = new Vector2();
            int
                index = r.Next(potential.Count),
                direction = 0;

            foreach (Vector2 item in potential.Keys)
                if (index == 1)
                {
                    oldItem = item;
                    direction = potential[item];
                    newItem = oldItem + neighbors[direction];
                    break;
                }
                else
                    index--;

            if (!paths.Contains(newItem))
            {
                paths.Add(oldItem);
                paths.Add(newItem);

                for (int index2 = 0; index2 < 4; index2++)
                    if (!paths.Contains(newItem + neighbors[index2]) && !potential.ContainsKey(newItem + neighbors[index2]))
                        potential.Add(newItem + neighbors[index2], index2);
            }

            potential.Remove(oldItem);
        }

        return paths;
    }
}
 
Nahoru Odpovědět 21.10.2012 13:34
Avatar
Kit
Redaktor
Avatar
Odpovídá na matesax
Kit:

My bychom ti občas rádi poradili, kdybychom ti rozuměli.

Nahoru Odpovědět 21.10.2012 13:38
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Redaktor
Avatar
Odpovídá na Kit
matesax:

Já sám jsem to nechápal - proto jsem se obrátil sem... :)

Nyní mi to je již jasné - bral jsem to tak, že si z každého volného konce vyberu náhodného souseda (nikam nezasahujícího) a toho přidám do proměnné s cestami v bludišti. Ale je to tak že každý volný konec má jen jeden směr - vstoupí-li mu někdo jiný do cesty, tak se jednoduše vymaže. Tím tedy každý konec má svůj pevně daný směr - a v něm stačí kontrolovat každé příští políčko...

Jediné co mi vrtá hlavou - jak mám zařídit, aby se mi vyplnila určitá plocha?

 
Nahoru Odpovědět 21.10.2012 13:49
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 21.10.2012 14:05
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

Vždyť to již mám - a způsobů je snad nekonečně mnoho... :) (A ten můj je pro mě lepší - potřebuji alespoň jednu 100% průchozí cestu...) A snad jsem i vymyslel, jek jím vyplnit předem zadanou plochu...

 
Nahoru Odpovědět 21.10.2012 14:11
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na matesax
David Čápka:

Tuhle věc jsem řešil i tak, že jsem naházel na plochu několik obdélníkových místností a ty poté propojil náhodně generovanou chodbou. Bylo to jako had, který se náhodně pohybuje (ale nemůže dozadu) a kolem něj se staví zdi. Dělalo to docela hezké dungeony, bohužel jsem to nikdy nedodělal.

Nahoru Odpovědět 21.10.2012 14:19
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

Cyklus se mi nechce ukončit - přitom podmínky jsou myslím správně:

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using System;

public class MazeGenerator
{
    private Random r = new Random();

    public List<Vector2> GenerateMaze(Rectangle bounds)
    {
        List<Vector2> paths = new List<Vector2>() { new Vector2(0, 0) };

        Dictionary<Vector2, int> potential = new Dictionary<Vector2, int>() { { new Vector2(1, 0), 0 }, { new Vector2(0, 1), 2 } };

        Vector2[] neighbors = new Vector2[] { new Vector2(1, 0), new Vector2(-1, 0), new Vector2(0, 1), new Vector2(0, -1) };

        while (potential.Count > 0)
        {
            Vector2
                oldItem = new Vector2(),
                newItem = new Vector2();
            int
                index = r.Next(potential.Count),
                direction = 0;

            foreach (Vector2 item in potential.Keys)
                if (index == 1)
                {
                    oldItem = item;
                    direction = potential[item];
                    newItem = oldItem + neighbors[direction];
                    break;
                }
                else
                    index--;

            if (!paths.Contains(newItem))
            {
                paths.Add(oldItem);
                paths.Add(newItem);

                for (int index2 = 0; index2 < 4; index2++)
                {
                    Vector2 total = newItem + neighbors[index2];

                    if (!paths.Contains(total) && !potential.ContainsKey(total) && total.X > 0 && total.Y > 0 && total.X < (bounds.Width / 32) && total.Y < (bounds.Height / 32))
                        potential.Add(total, index2);
                }
            }

            potential.Remove(oldItem);
        }

        return paths;
    }
}

V čem vidíš problém? Děkuji.

Editováno 21.10.2012 14:32
 
Nahoru Odpovědět 21.10.2012 14:31
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

A jak bych to měl naklonit podle X - asi to mám správně:

using System;
using Microsoft.Xna.Framework;

public class Camera2D
{
    public float Zoom { get; set; }

    public float Rotation { get; set; }

    public Vector2 Position { get; set; }

    public Camera2D()
    {
        Zoom = 2;
        Rotation = 0.001F;
        Position = new Vector2(-400, 240);
    }

    public void Move(Vector2 amount)
    {
        Position += amount;
    }

    public Matrix GetTransformation(Microsoft.Xna.Framework.Graphics.GraphicsDevice graphicsDevice)
    {
        return Matrix.CreateTranslation(
            new Vector3(Position.X, -Position.Y, 0))
            *
            Matrix.CreateRotationX(Rotation)
            *
            Matrix.CreateScale(new Vector3(Zoom, Zoom, 1))
            *
            Matrix.CreateTranslation(new Vector3(graphicsDevice.Viewport.Width * 0.5f, graphicsDevice.Viewport.Height * 0.5f, 0));
    }
}

Ale problém vidím ve vykreslení 3D objektu - místo 2D. Tak jako tak bych ty zdi 3D mít chtěl - zatím bez textury. Ovšem Texture3D se vykreslit nedá - co jsem nejčastěji viděl - dělá se to přes postupné vykreslování Meshů. Ovšem dává mi to dost zabrat - dát do dokupy - jak píši - zatím by to bylo jen v nějaké modré barvě. Děkuji za případnou pomoc.

 
Nahoru Odpovědět 21.10.2012 17:53
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.