sobota, 13 listopada 2010

Podsumowanie pracy

Z racji tego, iż za dwa dni kończy się konkurs "Daj się poznać" w którym udział bierze ten projekt, chciałem dzisiaj podsumować okres ponad 2 miesięcy pracy nad nim i podzielić się spostrzeżeniami  na jego temat.
Otóż w silniku przez ten okres udało mi się stworzyć mnóstwo klas, które będą stanowić podstawę do dalszej pracy nad silnikiem. W skrócie:
- można wyświetlać obraz(wczytany z pliku lub generowany) i tekst na ekranie;
- można rysować prymitywy;
- można używać klawiatury, myszki;
- dostępny jest wielowyjściowy logger(obecnie wyjscia do pliku i na konsolę dos);
- dostępny timer stałokrokowy;
- animacje z atlasu i manager animacji;
- dodano podstawową obsługę dźwięku(można załadować muzykę z pliku i odtwarzać ją); - i inne drobnostki.
- integracja z Box2D (obecnie mało rozwinięta: można renderować świat, klasa IActor - która łączy się z Body i zarządza nim)
- klasa Aplikacji(CApp) - pozwala zaoszczędzić czas i skrócić pisany kod, bo ma już pętle główną i inne metody których nie musimy pisać sami.
-IGame - interfejs gry klasa główna naszej gry powinna dziedziczyć i wykorzystać metody w nim zawarte.

To na razie tyle, obecnie po zakończeniu konkursu będę się chyba zajmował dokumentacją tego wszystkiego, bo ją strasznie zaniedbałem i skupiłem się tylko na implementacji. Poza tym udział w takim konkursie był super, nauczyłem się paru nowych rzeczy od uczestników. Oby takie konkursy były organizowane częściej.

Teraz jest głosowanie na najlepsze projekty w konkursie jeśli komuś przydały się informacje znajdujące  się na blogu może oddać głos na mój projekt: http://dajsiepoznac.devmedia.pl/ 

IActor

IActor to klasa reprezentująca jak sama nazwa wskazuje aktora. Jest abstrakcyjną klasą bazową po której dziedziczy nasza klasa aktora, w której dodajemy np. zdrowie postaci. Poza tym reprezentuje graficzną formę, zawiera CSprite. Klasa jest zintegrowana z Boxem i została stworzona właśnie do Renderowania ciał(b2Body) na ekranie. Poza tym zawiera kilka flag do zarządzania tym ciałem(czy ma zostać zniszczone, czy ma być rysowane, czy "żyje").




#pragma once
#include
#include
#include
#include "CSprite.h"
namespace DarkStorm2D
{
class DLLDARKSTORM2D IActor
{
protected:
b2Body* m_Body;
GraphicsCore::CSprite* m_Sprite;
unsigned int ID;

enum ActorFlags
{
Alive,
Destroy,
Visible,
ActorFlagsCount
};
std::bitset m_Flags;
public:
IActor()
{
m_Body = 0;
m_Sprite = 0;
m_Flags.reset();
}

~IActor()
{
m_Body = 0;
m_Sprite = 0;
m_Flags.reset();
}
void Render(float ScaleFactory)
{
if ( m_Flags[Alive]&& !m_Flags[Destroy])
{
float rot = m_Body->GetAngle();
b2Vec2 pos = m_Body->GetPosition();
//if (rot)
//m_Sprite->Render(pos.x/ScaleFactory-(float)m_Sprite->GetWidth()/2.0f, pos.y/ScaleFactory-(float)m_Sprite->GetHeight()/2.0f);
//else
m_Sprite->Render(pos.x/ScaleFactory-(float)m_Sprite->GetWidth()/2.0f, pos.y/ScaleFactory-(float)m_Sprite->GetHeight()/2.0f);
}
}

GraphicsCore::CSprite* GetSprite()
{
return m_Sprite;
}
bool IsAlive()
{
return m_Flags[Alive];
}

bool IsDestroy()
{
return m_Flags[Destroy];
}

bool IsVisible()
{
return m_Flags[Visible];
}
};
};


Na razie nie jest aż tak funkcjonalna ale to się zmieni. Dzięki niej można wyrenderować świat Boxa za pomocą jednej komend(klasy CWorld - Render() // iteruje ona przez wszystkie body i renderuje ich aktorów). To na razie tyle o aktorach.

sobota, 6 listopada 2010

CApp - Podstawa Frameworka

O klasie CApp wspomniałem w jednym z wcześniejszych postów, ale nie przedstawiałem jej jeszcze dokładnie. Otóż, będzie ona stanowić podstawę frameworka, jest to jedna z głównych klas w silniku. W założeniu, tworzymy jej instancje w głównej funkcji( main ), oto jak by to wyglądało:




#include "MyGame.h"

#include "CApp"




using namespace DarkStorm2D::SystemCore;

int main()

{

MyGame Game;

CApp App(&Game);

if (App.Init())

{

App.Run();

App.Deinit();

}

return 0;

}


Dosyć prosto wygląda :).
MyGame to klasa naszej gry(dziedziczy po IGame.
Do konstruktora aplikacji przekazujemy naszą grę zgodną z interfejsem IGame, drugim parametrem, którego tu nie podaję, bo domyślna wartość(60) w zupełności wystarczy, to żądana liczba klatek na sekundę.
Potem inicjujemy Grę, następnie jeśli się to powiodło Możemy ją uruchomić(W metodzie Run() znajduje się pętla główna). Na koniec Zwalniamy wszelkie zasoby i kończymy. I to by było na tyle o CApp, jeśli ktoś miałby jakieś sugestie, uwagi niech napisze w komentarzach.

Box2D - Wielka bitwa

Od ponad tygodnia rozplanowuje klasy pomocnicze do obsługi fizyki w silniku. Głównie to będą jakieś wrappery(nakładki) na Boxa, które trochę ułatwią zarządzanie nim. Jeszcze dokładnie nie opanowałem tego pudełka, ale większość już wiem, internet w tej sprawie trochę mi pomógł, ale mogłoby być więcej tutków do tego. Niedługo spróbuję napisać jakieś małe demko z fizyką.

sobota, 30 października 2010

Box2D - Drugie Starcie

Druga próba "dopasowania" Boxa do silnika okazała się sukcesem. Po kilku poprawkach udało mi się wreszcie ruszyć coś na ekranie. Trochę trwało szukanie przyczyn złego dopasowania tego co widzimy na ekranie z tym co
robi box( obraz nie pokrywał się z rzeczywistością, złe pozycje obrazu(różnica 15px)), przyczyną był brak rzutowania na float, wysokości i szerokości podczas definiowania b2Polygona(metoda SetAsBox). Teraz wszystko działa idealnie. Oczywiście były to testy, teraz muszę zrobić kilka klas pomocniczych do tego i może zabiorę się za jakieś demko prezentujące troszeczkę możliwości silnika:)

czwartek, 28 października 2010

Box2D - Pierwsze Starcie

Dzisiaj bawiłem się pudełkiem, czyli silnikiem fizycznym 2D o nazwie Box2D, na razie tylko testowo, ale zanim zacząłem cokolwiek z nim robić musiałem je sobie zbudować( CMAKE i te rzeczy), potem napisałem kilka funkcji: do inicjalizacji świata Boxa, tworzenia Body, rysowania go i itp. Potem próbowałem poruszać obiektem ale coś było nie tak i postanowiłem, rozwiązać to jutro, bo dzisiaj kupiłem nową grę i chciałbym ją przetestować.
Ogólnie to ten Box jest fajny, ale mam problem z tutkami(na stronie głównej box2d jest słaba instrukcja, poza tym widziałem tylko tutki związane z wersją flashową boxa, nic pod c++ :( A może słabo szukałem ??

środa, 27 października 2010

Input Core - Klawiatura i mysz

Napisałem niedawno klasy odpowiedzialne za mysz i klawiaturę, są bardzo proste:
Najpierw klawiatura:




class CKeyboard
{
private:
bool m_Key[512]; // true - wciśnięty, false - nie
public:
CKeyboard()
{
Clear();
}

~CKeyboard()
{
Clear();
}

void Update(int Key, bool Action = true)
{
m_Key[Key] = Action;
}

void Clear()
{
memset(m_Key,0,512*sizeof(bool));
}

bool IsKeyDown(int Key)
{
return m_Key[Key];
}
bool IsKeyUp(int Key)
{
return !(m_Key[Key]);
}

bool operator [] (int Key)
{
return m_Key[Key];
}
};



Teraz klasa myszy:


class CMouse
{
private:
struct{
int x;
int y;
int z;

int dx;
int dy;
int dz;

unsigned int button;
} m_MouseState;

GraphicsCore::ImagePtr m_ImageCursor;

bool m_IsCursorVisible;
protected:
public:
enum EButton{NONE,LEFT, RIGHT, MIDDLE};

CMouse()
{
Clear();
m_IsCursorVisible = true;
}

~CMouse()
{
Clear();
m_IsCursorVisible = true;
al_show_mouse_cursor(al_get_current_display());
}

void Clear()
{
memset(&m_MouseState,0,sizeof(m_MouseState));
}

void Update(ALLEGRO_EVENT& Event)
{
switch (Event.type)
{
case ALLEGRO_EVENT_MOUSE_AXES:

m_MouseState.x = Event.mouse.x;
m_MouseState.y = Event.mouse.y;
m_MouseState.z = Event.mouse.z;

m_MouseState.dx = Event.mouse.dx;
m_MouseState.dy = Event.mouse.dy;
m_MouseState.dz = Event.mouse.dz;
break;

case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:

m_MouseState.x = Event.mouse.x;
m_MouseState.y = Event.mouse.y;
m_MouseState.z = Event.mouse.z;
m_MouseState.button = Event.mouse.button;
break;

case ALLEGRO_EVENT_MOUSE_BUTTON_UP:

m_MouseState.x = Event.mouse.x;
m_MouseState.y = Event.mouse.y;
m_MouseState.z = Event.mouse.z;
m_MouseState.button = 0;
}
}

unsigned int GetButton()
{
return m_MouseState.button; 
}

void GetXY(int* x, int* y)
{
*x = m_MouseState.x;
*y = m_MouseState.y;
}

void GetZ(int* z)
{
*z = m_MouseState.z;
}

void GetDXDY(int* dx, int* dy)
{
*dx = m_MouseState.dx;
*dy = m_MouseState.dy;
}

void GetDZ(int* dz)
{
*dz = m_MouseState.dz;
}

void VisibleSystemCursor(bool Visible)
{
if (Visible == true)
al_show_mouse_cursor(al_get_current_display());
else al_hide_mouse_cursor(al_get_current_display());
m_IsCursorVisible = Visible;
}

void DrawCursor()
{
m_ImageCursor->Draw(m_MouseState.x,m_MouseState.y);
}

void SetCursorImage(GraphicsCore::ImagePtr& CursorImage)
{
m_ImageCursor = CursorImage;
}
};


W przyszłości będzie oczywiście gamepad oraz obsługa w stylu PS Move(z zastosowaniem kamerki internetowej)