środa, 18 sierpnia 2010

Czas zacząć pisać kod !!!

Ostatnio tylko projektowałem klasy i interfejsy mojego silniczka, teraz trzeba to wszystko wcielić w życie i pisać tysiące linii kodu, cóż takie jest już życie programisty:). Zaczynam od najprostszych elementów, czyli klas pomocniczych. Jedną z nich jest CSAllegroController - "S" w nazwie sugeruje, że jest to klasa typu singleton, 
czyli może istnieć tylko jeden taki obiekt w całym silniku. Klasa jest "nakładką"  na wszelki inicjalizacje i instalacje w Allegro(zawiera tablice w której będą znajdowały się informacje o bieżących zainicjowanych elementach Allegro np. czy zainstalowano obsługę klawiatury, myszki itp.). Klasa, będzie pomocna również, gdy   będziemy chcieli dowiedzieć się jaki interfejsem Allegro posługuje się przy obsłudze plików(podstawowym czy PhysicsFS). CSAllegroController nie trzeba używać na zewnątrz, będzie ona używana tylko wewnątrz silnika.

Jeszcze na temat implementacji w postać singletona:
  • Jest to technika programistyczna pozwalająca na to, że w naszym programie będzie istnieć tylko jeden egzemplarz naszej klasy.
  • Jest to możliwe dzięki statycznemu wskaźnikowi na tę klasę, który jest w niej zawarty, a dostęp do niego uzyskujemy przez statyczną metodę która go zwraca.
Singleton.h
#pragma once
#include
class  Singleton
{
private:
         // statyczny wskaźnik na klasę 
static Singleton * m_Singleton;
public:
static Singleton * GetSingleton();
Singleton();
~Singleton();

};




















// składowe statyczne trzeba deklarować w globalnym obszarze nazw





Singleton * Singleton::m_Singleton;



Singleton SingletonOne; // Tworzymy jedyny obiekt 





Singleton.cpp









#include "Singleton.h"

Singleton::Singleton()
{
        // Sprawdzamy czy nie stworzono już obiektu, czy wskaźnik jest pusty
assert(!m_Singleton);
       // Jeśli tak to inicjujemy go obecnym obiektem
m_Singleton = this;
}


Singleton::~Singleton()
{
        // Sprawdzamy czy obiekt istniej, czy nie jest to pusty wskaźnik
assert(m_Singleton);
       // jeśli nie jest pusty to doprowadzamy go do tego stanu
m_Singleton = 0;
}

static Singleton::Singleton * GetSingleton()
{
        assert(m_Singleton);
        // zwracamy wskaźnik na jedyny obiekt tej klasy
        return m_Singleton;
}


Edit: Słusznie ta implementacja nie jest taka dobra, ale znalazłem lepszą:
http://users.v-lo.krakow.pl/~temporal/SCGame/html/v-lo/arts/inf/singleton.html


Implementacja Scotta Bilasa

wtorek, 10 sierpnia 2010

Dylemat konwencji nazweniczej

Myślę czy zastosować w moim projekcie notację węgierską ale trochę zmodyfikowaną:


Prefiks Od czego pochodzi Opis Typ Przykład
i integer całkowitoliczbowe int, short, long iLiczba
ui unsigned integer całkowitoliczbowe bez znaku unsigned int, unsigned short, unsigned long uiLiczba
f float zmiennoprzecinkowe float, double fXPos
p pointer Wskaźniki type * pImage
a array tablica type [ ] pImage
I Interface interfejsy(klasy z wirtualnymi metodami) virtual class IManager
C Class klasy class CImageManager
k kit typy złożone(instancje klas i struktur) type, struct kImage
m_ member of składowe(pola) używane w class, struct m_pImage
E Enumerate enumeraty enum EFlags
f flag flaga bitowa stosowane w enum fVsync
sz string zero napis zakończony zerem char [] szHello

Tabela może być nie kompletna, ale myślę że wymieniłem to co najważniejsze.
Proszę o porady w komentarzach i o oddanie swojego głosu w ankiecie dotyczącej tematu.
Warto przeczytać ten artykuł: http://dezinformacja.org/tarpit/archiwum/1116915727

Może podam kilka złożonych przedrostków:
pk // pointer kit  wskaźnik na typ złożony
m_p // member of pointer członek, wskaźnik
m_pk // member of pointer kit członek, wskaźnik na typ złożony

m_pi // member of pointer integer członek, wskaźnik liczby całkowitej
m_pf // member of pointer float członek, wskaźnik liczby zmiennoprzecinkowej

m_api // member of array pointer integer członek, tablica wskaźników liczb całkowitych
m_apk // member of array pointer kit członek, tablica wskaźników na typ złożony

m_af // member of array flag członek, tablica flag

m_asz // member of array string zero członek, tablica napisów zakończonych zerem

poniedziałek, 9 sierpnia 2010

Kilka pierwszych problemów

Projektuje na razie klasy i rozmyślam o ich implementacji. Natrafiłem na pewne trudności i sposoby ich rozwiązania, oto one:

  1. Rozwiązanie projektowe managera zasobów:
    • Pierwsza, przechowywać zasoby w specjalizowanych managerach dla każdego typu;
    • Druga, Stworzyć pojedynczą "mapę" na na obiekty typu IResource(w tej klasie zarezerwować pole dla typu zasobu), każdy zasób dziedziczy po niej. I wystarczy przy pobieraniu rzutować na wybrany typ;Wybrałem to rozwiązanie!!!
  2. Klasa czcionki i problem z funkcją w stylu printf()



  • Rozwiązanie 1:
    • Wyszedłem od takiego prototypu: 
                      void DrawTextf(int x, int y, int flags, const char * string, ...)
    •  Ale nie można przekazać do funkcji tego "...", więc można by zastosować vsprintf()  do którego można przekazać va_list i dzięki temu można  wszystko połączyć i wykorzystać DrawText();
    • Niestety wadą tego rozwiązania jest to że musimy znać rozmiar bufora do którego zapisujemy.
  • Rozwiązanie 2:
    • skorzystać z Boost Format library i stworzyć funkcję przyjmującą taki obiekt :
                   DrawTextf( int x, int y, int flags ,boost::format));

    Jedenasty Rdzeń

    Jedenastym rdzeniem będzie GUI Core. Pierwotnie byłoby dołączone do Graphics Core, ze względu, że jest to mocno związane z wizualną stroną gry, ale po dłuższym namyśle zawiera również elementy logiczne(akcje: np. kliknięcie, najazd myszy na obiekt itp.) i to zdecydowało o przeniesieniu go do osobnego modułu.

    czwartek, 5 sierpnia 2010

    DarkStorm2D prace ruszyły

    Oficjalnie rozpoczynam pracę nad projektem: DarkStorm2D jest to  silnik i framework do gier 2D tworzony przy pomocy:
    Języka: C++;
    Bibliotek: Allegro5, Boost, OpenSSL, STD, winsock2;
    Fizyki z: Box2D.

    Poszczególne moduły to:
    Graphics Core - odpowiada za to co zobaczymy na ekranie;
    Input Core - odpowiada za sterowanie w grze;
    Sound Core - odpowiada za dźwięk i jego efekty;
    Physic Core - odpowiada za fizykę oraz systemy cząsteczkowe;
    System Core - odpowiada za aplikacje, posiada klasy do obsługi maszyny stanów;
    Utility Core - Posiada klasy pomocnicze, Manager Zasobów oraz klasy obsługujące VFS i Archiwa( Zip, RAR, itp.);
    Network Core - odpowiada za komunikacje sieciową
    Script Core - odpowiada za przetwarzanie skryptów pisanych w specjalnie do tego celu stworzonym języku DarkScript;
    Artificial Intelligence Core - odpowiada za sztuczną inteligencję w grze;
    Game Core - odpowiada za całą grę, posiada klasy wyższego poziomu(czytaj: frameworka) które ułatwiają programowanie gier(zawiera klasy reprezentujące poszczególne elementy różnych typów gier).


    Silnik będzie na licencji open source!!!
    Kod i dokumentacja do pobrania stąd: code.google.com/p/darkstorm2d/
    Projekt bierze udział w konkursie: "Daj się poznać"
    Więcej informacji na temat konkursu na stronie: http://www.maciejaniserowicz.com/page/Konkurs-daj-sie-poznac.aspx