Autor Wątek: Własny silnik w SDL - problemy  (Przeczytany 1592 razy)

Offline Arthes

  • Użytkownik
    • Gromaniak

# Maj 03, 2011, 14:33:22
Witam, ostatnio kodzę sobie taki mały silniczek SDL, który posłużyłby mi do pisania gier 2D.
Podczas pisania natrafiłem na kilka problemów, a mianowicie:
-niemożliwość skonwertowania int'a na char'a. Jak nie błąd podczas kompilacji, to program się nie uruchamia
-problem z wydajnością przy wypisywaniu tekstu. Gdy wypiszę na ekranie tekst, wydajność spada
-brak pomysłu na stworzenie obsługi dźwięków (pewnie jest jakaś biblioteka)

Mógłby ktoś coś doradzić, pomóc rozwiązać problemy?
Co do wypisywania tekstu- wydajność pewnie spada dlatego, że "dziwnie" zrobiłem tą funkcję. Jednakże jeśli wczytywanie czcionki i powierzchni zrobię poza funkcją- wtedy tekst się nie wyświetla.


Silnik składa się z kilku plików, oto one:
Inc.h
//Definicje
 #define White 0xffffff
 #define Black 0x000000
 #define Red 0xff0000
 #define Gray 0x808080
 #define Blue 0x0000ff
 #define Green 0x008000
 #define Yellow 0xffff00
 #define Silver 0xc0c0c0

 //Zmienne i wskaźniki
 bool Running = true;
 SDL_Surface* Screen;
 SDL_Event Event;
 Uint8* Key = SDL_GetKeyState(NULL);
 int FPS = 0;

Functions.h
void DrawText(int x, int y, char* Text) {
 TTF_Font* Font = TTF_OpenFont("arial.ttf",20);
 SDL_Color Color = {0,0,255};
 SDL_Rect Rect = {x,y,0,0};
 SDL_Surface* text = TTF_RenderUTF8_Solid(Font, Text, Color);
 SDL_BlitSurface(text, NULL, Screen, &Rect);
}

Classes.h
class Sprite{
 private:
 SDL_Surface *image;
 SDL_Rect rect;

 public:
 Sprite(char *Src);
 void Draw();
 void SetX(int X);
 void SetY(int Y);
 int GetX();
 int GetY();
 };
 
 Sprite::Sprite(char *Src) {
  image = IMG_Load(Src);
  rect.x = 0;
  rect.y = 0;
 }
 void Sprite::Draw() {
 SDL_BlitSurface(image, NULL, Screen, &rect);
 }
 void Sprite::SetX(int X) {
 rect.x = X;
 }
 void Sprite::SetY(int Y) {
 rect.y = Y;
 }
 int Sprite::GetX() {
 return rect.x;
 }
 int Sprite::GetY() {
 return rect.y;
 }

Game.cpp
#define Title "Tytuł okna hehe"
 #define Width 800
 #define Height 600
 #define Flags SDL_DOUBLEBUF
 //Zmienne
 Sprite *Test = new Sprite("image.bmp");
 Sprite* Hero = new Sprite("test.png");
 void Logic(){ //Logika gry
 }
 void Draw(){ //Rysowanie obiektów
 Test->Draw();
 Hero->Draw();
 DrawText(200,200,"Test test test");
 }
 void Events(){ //Zdarzenia
 if (Key[SDLK_RIGHT]) Hero->SetX(Hero->GetX()+1);
 if (Key[SDLK_LEFT]) Hero->SetX(Hero->GetX()-1);
 if (Key[SDLK_DOWN]) Hero->SetY(Hero->GetY()+1);
 if (Key[SDLK_UP]) Hero->SetY(Hero->GetY()-1);
 }
 void Destroy(){ //Niszczenie obiektów po zakończeniu
 delete Hero;
 }

Z góry dziękuję za pomoc i odpowiedzi, pozdrawiam.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline PP

  • Użytkownik

# Maj 03, 2011, 15:02:10
Czcionkę załaduj raz na początku programu a potem przekazuj aby wskaźnik do funkcji renderującej tekst
,tak poza tym to należało by ją potem zwolnić za pomocą TTF_CloseFont .Przy odpaleniu programu tak jak jest zapcha Ci się całą pamięć :)

Offline Lavi

  • Użytkownik
    • using namspace <Lavi.h>

# Maj 03, 2011, 15:10:24
Wskazałbyś gdzie niby nie możesz skonwertować tego int'a na char'a bo jakoś się doszukać nie mogę :/
Czyżby chodziło Ci o konwersje liczby na tekst?

Co do czcionki to tak jak mój poprzednik napisał: funkcja tworząca czcionkę ma być wywołana tylko raz podczas uruchamiania programu jak nie to wieżysz zostaw program na kilka minut i zobacz sobie jak twój program rośnie :)

Do dźwięku to jest masa bibliotek. Oczywiście jest to uzależnione od twoich umiejętności kodzenia więc na początek polecam: http://www.libsdl.org/projects/SDL_mixer/

Offline Arthes

  • Użytkownik
    • Gromaniak

# Maj 03, 2011, 15:11:36
Tylko że jak wczytywanie czcionki dam na początku programu, to kompiluje się bezbłędnie, ale program się nie uruchamia ;/

Offline Rect Code

  • Użytkownik

# Maj 03, 2011, 15:18:03
Co do dźwięku to polecam Audiere ,jeśli coś bardziej skomplikowane piszesz to spróbuj z FMOD'em.

Offline Arthes

  • Użytkownik
    • Gromaniak

# Maj 03, 2011, 15:24:25
Próbowałem już wcześniej problem z textem rozwiązać przy pomocy klasy:


 Text::Text(int x, int y, char *Content) {
  TTF_Font* Font = TTF_OpenFont("arial.ttf",20);
  SDL_Color Color = {0,0,255};
  SDL_Rect Rect = {x,y,0,0};
  Con = Content;
  text = TTF_RenderUTF8_Solid(Font, Con, Color);
 }
 void Text::Draw() {
 SDL_BlitSurface(text, NULL, Screen, &rect);
 }

Jednakże program uruchamia się, a napisu nie widać.

Offline PP

  • Użytkownik

# Maj 03, 2011, 15:37:13
Pierwsze co się rzuca w oczy to to ,że "rect" jest zapewne nie zainicjowane .
Poza tym dziwną masz tą klasę Text .

Offline hfjh

  • Użytkownik

# Maj 03, 2011, 15:53:02
Zacznijmy od tego, że najwyraźniej nie rozumiesz jak działają obiekty globalne. Jeśli konstruktor takiego obiektu ma jakieś zewnętrzne zależności*, to nie masz mieć pewności, że odwołanie się do nich będzie poprawne (np. inny obiekt nie będzie zainicjalizowany), bo:
1) konstruktor jest wywoływany przed wejściem do funkcji main (to Twój problem - przed użyciem funkcji SDLa trzeba    wywołać funkcję SDL_Init)
2) kolejności inicjalizowania obiektów globalnych nie jest odgórnie narzucona - odwoływanie się w konstruktorze do innych obiektów globalnych to słaby pomysł.


*) chodzi o zależności w kodzie programu

Offline Rect Code

  • Użytkownik

# Maj 03, 2011, 16:13:02
Próbowałem już wcześniej problem z textem rozwiązać przy pomocy klasy:


 Text::Text(int x, int y, char *Content) {
  TTF_Font* Font = TTF_OpenFont("arial.ttf",20);
  SDL_Color Color = {0,0,255};
  SDL_Rect Rect = {x,y,0,0};
  Con = Content;
  text = TTF_RenderUTF8_Solid(Font, Con, Color);
 }
 void Text::Draw() {
 SDL_BlitSurface(text, NULL, Screen, &rect);
 }

Jednakże program uruchamia się, a napisu nie widać.

Daj kod z maina,może SDL_Flip(screen) nie wywołujesz?

Offline Arthes

  • Użytkownik
    • Gromaniak

# Maj 03, 2011, 16:19:23
Przecież na samej górze jest kod. Zrobiłem to tak, że automatycznie ciągle czyści.