Miesiąc uczestnictwa w konkursie „Daj się poznać”

Sierpień 29th, 2010

O tak, minęły już całe 4 tygodnie odkąd wystartowałem w konkursie programistycznym dla bloggerów pt. „Daj się poznać„. Właśnie poprawiłem troszkę swój projekt (refactoring i poprawka plików w źródłach – mam nadzieję, że Wam też się kompiluje:) oraz umieściłem najnowszą wersję gry do ściągnięcia tutaj:

GameXna_30082010.exe
Żeby działało, to dodatkowo trzeba sobie ściągnąć następujący pakiet:
Microsoft XNA Framework Redistributable 3.1

Na tym etapie pochwalić się mogę paroma osiągnięciami, tj.
- postępami w kontekście uzyskiwania całościowego efektu (świat gry, tj. dodany w tym czasie horyzont, modele i interfejs poruszania się są już coraz bardziej widoczne)
- większego wykorzystania możliwości frameworka XNA, na którym opieram swój projekt, w tym wykorzystania podstawowych funkcji do wykrywania kolizji
- nabycia podstawowych umiejętności korzystania z programu Blender (darmowego i profesjonalnego narzędzia do projektowania/modelowania 3D)
- otrzymania kontaktu od Krzyśka Dąbrowskiego (http://ktdabrowski.pl.tl) – osoby, w postaci młodego pisarza, która zainteresowała się moim projektem…. zastanawiam się czy pewne opowiadania mogłyby posłużyć za fabułę, tudzież tło dla tworzonej przeze mnie gry.
- dotrzymania wymaganego tempa blogowania (regulamin konkursu określa jasno min. 2 posty na tydzień – ten jest moim 9. w tym miesiącu)

Z największych problemów, na które natknąłem się teraz, wymienić można przede wszystkim problemy z mapowaniem kulistych tekstur na bryły utworzone w Blenderze. Ciągle mam jeszcze pewne problemy z uzyskaniem oczekiwanego efektu (narazie jest efekt zastępczy), o czym pisałem już w poście tutaj:
http://www.kamilhawdziejuk.pl/2010/08/22/problemy-z-teksturowaniem-modeli-brak-postepow/
ale całkiem szybko poruszam się już w tym nie bardzo intuicyjnym (o skrótach typu SPACJA, U, CTRL+E+3 na forum gamedev więdzą najwięcej;]), aczkolwiek bardzo sprytnym i szybkim w efekcie programie. W sieci znajduje się sporo tutoriali na ten temat.

Na koniec, wreszcie dopiszę do swojej listy ciekawych linków adres bloga o XNA osoby z Microsoftu, który polecało mi już parę osób:
http://blogs.msdn.com/b/shawnhar
Również polecam!

Detekcja kolizji – podstawy

Sierpień 29th, 2010

Detekcja kolizji jest jedną z fundamentalnych części wielu różnych aplikacji, w tym gier komputerowych. Nachodzenie na siebie obiektów jest często bowiem niepożądanym stanem. System wykrywania i naprawiania kolizji odpowiadać ma w swoim zamierzeniu za zapewnienie poprawnego i stabilnego stanu gry, wymuszając odpowiednie zachowanie obiektów w momencie wzajemnej interakcji. W grach komputerowych uniemożliwia postaciom przechodzenie przez ściany czy też upadanie poniżej poziomu podłogi. Dostarcza także możliwości takie, jak odpowiedź na pytanie czy jeden użytkownik może zobaczyć drugiego, bądź czy jest w zasięgu strzału wroga.

Wśród wszystkich problemów występujących w grach 3D, te odnoszące się do kolizji obarczone są najbardziej krytycznymi ograniczeniami czasowymi. W związku z tym stosuje się specjalne algorytmy do wykrywania kolizji pomiędzy nimi oraz wprowadza się pewne usprawnienia przyspieszające ich wykrywanie, takie jak struktury opisujące podział przestrzeni.

W skrócie: w grach, wykrywać można kolizje na wiele sposobów, w zależności od stopnia jej szczegółowości. Najczęściej opakowuje się obiekty w jakieś prostsze odpowiedniki typu sfera lub prostopadłościan i wykrywa kolizje jedynie dla nich (czas testu jest wtedy stały i nie zależy od stopnia skomplikowania siatki). Dla zobrazowania faktu, wklejam przykład z pewnej gry:

Okazuje się, że XNA wychodzi nam naprzeciw i dostarcza wiele spośród rozwiązań w swoim frameworku! Istnieją struktury i istnieją metody, które upraszczają wykrywania kolizji i to bardzo (wiem to, bo pisałem pracę magisterską z detekcji kolizji i mocno się namęczyłem implementując te algorytmy). W szczególności, w XNA każdy model zbudowany jest z modeli siatek (ModelMesh), które posiadają jako propertę BoundingSphere (sferę otaczającą daną siatkę).

Ja system detekcji kolizji zaimplementowałem zatem w swoim GameObjectsManagerze (dla przypomnienia jest to GameComponent) bardzo szybko. Patrząc przyszłościowo … zdefiniowałem najpierw interfejs wykrywający kolizję:

public interface ICollisionDetector
{
     //zwraca true, gdy pomiędzy dwoma obiektami gry istnieje kolizja
     bool DetectCollision(GameObject obj1, GameObject obj2, double tolerance);
}

i zaimplementowałem póki co detektor wykrywający kolizje na sferach:

public bool DetectCollision(GameObject obj1, GameObject obj2, double tolerance)
{
    //porównuje tutaj każdą z siatek każdego z dwóch obiektów
    foreach (ModelMesh mesh1 in obj1.Model.Meshes)
    {
        foreach (ModelMesh mesh2 in obj2.Model.Meshes)
        {
            //pobieram sferę z siatki
            BoundingSphere bs1 = mesh1.BoundingSphere;
            //...i muszę jeszcze przesunąć i przeskalować ją
            // zgodnie z reprezentacją (dla sfery wystarczy pozycja i skala)
            bs1.Center = obj1.Position;
            bs1.Radius *= obj1.Scale;
           
            BoundingSphere bs2 = mesh2.BoundingSphere;
            bs2.Center = obj2.Position;
            bs2.Radius *= obj2.Scale;
            //wreszcie metoda Intersects z frameworka XNA
            //(która może przyjmować też kilka innych ciekawych argumentów!)
            if (bs1.Intersects(bs2))
            {
                return true;
            }
        }
    }
    return false;
}

Ostatecznie, wystarczy wykorzystać go w GameObjectsManagerze w metodzie Update:

public override void Update(GameTime gameTime)
{
    foreach (GameObject obj in this.gameObjects)
    {
        //narazie, sprawdzam tylko kolizje z aktualnie poruszanym obiektem
        if (obj != this.activeObject)
        {
            if (sphereCollisionDetector.DetectCollision(obj, this.activeObject, 0))
            {
                 //tutaj kod odpowiadający przypadkowi, gdy zachodzi kolizja!
                 //może jakiś dźwięk zderzenia:)?
            }
        }
    }
    base.Update(gameTime);
}

Naprawdę wszystko dostarczone prawie jak na tacy. Jeśli chodzi o sytuację na scenie… mój helikopter już nigdy nie zderzy się niepostrzeżenie z samochodem, choć oczywiście tylko w przybliżeniu, co na daną chwilę graczom w zupełności wystarcza…

Problemy z teksturowaniem modeli – brak postępów?

Sierpień 22nd, 2010

Tak jak pisałem w poprzednim poście, zabrałem się za stworzenie przestrzennego świata 3D. W tym celu wystarczy stworzyć sferę, nałożyć na nią odpowiednią teksturę i powiększyć ją multum razy, tak, aby gracz znajdował się wewnątrz niej i odnosił wrażenie otaczającego go świata.

Można było podejść do tego tematu na różne sposoby, a ja wybrałem ten teoretycznie najprostszy, a zarazem najwłaściwszy. Chciałem stworzyć sferę w jakimś programie do modelowania (mam Blender w wersji 2.49 – darmowy i profesjonalny), nałożyć na nią teksturę i wyeksportować do „zjadliwego” dla XNA formatu *.FBX, po czym załadować gotowy model do gry (o tym jak to zrobić pisałem wcześniej). Przy okazji musiałem przebrnąć przez jakiś tutorial jak w ogóle poruszać się po Blenderze, bo miałem z nim do czynienia po raz pierwszy. Ech…bardzo potężne narzędzie z mnóstwem skrótów klawiszowych, które są mega nieuintucyjne, ale bardzo przyspieszają pracę! Niestety cały ten proces mi się nie udał. O ile w Blenderze wszystko się ładnie pokazuje, o tyle załadowany model w mojej grze nie wygląda tak jak chcę…

…jak się okazało nie tylko ja mam takie problemy. Na forum forum.gamedev.pl padały już pytania o teksturowanie brył nieraz. Niemniej, u mnie wciąż coś jest nie tak. Konkretnie, to postępuję następująco: tworzę sferę, ustawiam UVFaces mode, nakładam tekturę i sprawdzam, czy ładnie się to wszystko renderuje – działa. Następnie eksportuje to do *.FBX. Cały proces wygląda tak (zamieszam filmik 66sek.):
http://KamilHawdziejuk.pl/testy/texturowanie/blender249.avi,
w rezultacie którego widać, że osiągam efekt:

Niestety po załadowaniu modelu do gry dostaję taki rezultat:

czyli coś jakby było na rzeczy z tymi odcieniami, ale to zupełnie nie wygląda tak jak w blenderze…. hmm. Może macie jakieś pomysły? Mam wrażenie, że natknąłem się na tego rodzaju ścianę nie do przebicia bez pomocy innych. Tymczasem wracam do walki…