Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

1

24.12.2012, 12:01

Text mit SDL_ttf anzeigen

Hallo Leute
ich möchte das SDLSpiel aus dem Buch C++ für Spieleprogrammierer erweitern.
Dazu habe ich nun begonnen ein Menü zu erstellen.
Dass ist einfach ein Hintergrund, auf dem nun Text erscheinen soll. Der Text soll wie folgt aussehen:
(1) Spiel starten
(2) Highscore
(3) Beenden
und eventuell noch mehr.
Jetzt sitze ich schon 3 Tage daran irgendwie einen Text mit der SDL_ttf.h zu rendern, doch komme einfach nicht weiter.
Ich stelle euch hier einmal meine Font.hpp und meine Font.cpp vor, welche ich zusammen gebalstet habe.

Font.hpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef FONT_HPP
#define FONT_HPP

#include "SDL_ttf.h"
#include "Menü.hpp"

class CFont
{      public:
              CFont ();              void Run ();

     private:
                     TTF_Font *font;              SDL_Color textColor;               SDL_Surface *m_pScreen;              SDL_Surface *message;              void load ();
              void Render ();
              void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL );
              void Quit ();

};#endif


und hier ist die Font.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "Font.hpp"

CFont::CFont (){    SDL_Surface *message = NULL;    TTF_Font *font = NULL;    SDL_Color textColor = { 255, 255, 255 };    m_pScreen = g_pFramework->GetScreen ();}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{    SDL_Rect offset;//Get offsets
    offset.x = x;    offset.y = y;//Blit
    SDL_BlitSurface( source, clip, destination, &offset );}void CFont::load ()
{    if( TTF_Init() == -1 )
    {        exit (0);    }    //Open the font
    font = TTF_OpenFont( "lazy.ttf", 28 );

//If there was an error in loading the font
if( font == NULL )
    {        exit (0);    }}void CFont::Render ()
{    //Render the text
    message = TTF_RenderText_Solid( font, "(1) Starten", textColor );

//If there was an error in rendering the text
if( message == NULL )
    {        exit (0);    }//Apply the images to the screen
    apply_surface( 0, 150, message, m_pScreen );//Update the screen
if( SDL_Flip( m_pScreen ) == -1 )
    {        exit (0);    }}void CFont::Run ()
{    load ();    Render ();}void CFont::Quit ()
{    SDL_FreeSurface( message );//Close the font that was used
    TTF_CloseFont( font );//Quit SDL_ttf
    TTF_Quit();}


Die Funktion CFont::Run wird aus dem Menü herraus aufgerufen. Im Menü selber läuft eine Schleife, welche entweder durch den druck der Escape Taste oder der 1 beendet wird. Bei 1 Startet das Spiel und bei Escape wird es sofort beendet. Die Funktion Run soll sogesehen alle Funktionen der Klasse CFont steuern. Sollte irgendwo ein Fehler auftreten habe ich dort exit(0); stehen. Das ist jedoch nur übergangsweise. Dort kommt später noch ein rückgabewert hin, durch welchen dann ein Fehler ausgeschmissen wird und dann das Programm sauber beendet wird.

Da der Code hier im Forum komisch formatiert ist, habe ich hier mal die cpp und hpp datei hochgeladen, damit man mehr übersicht hat.
Font.cpp: http://www.mediafire.com/?8fknl6d85n7e5o1
Font.hpp: http://www.mediafire.com/?np8meyxal2tw911


so nun bekomme ich immer folgenden Fehler:

Fehler 1 error LNK2001: Nicht aufgelöstes externes Symbol ""private: void __thiscall CFont::apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *,struct SDL_Rect *)" (?apply_surface@CFont@@AAEXHHPAUSDL_Surface@@0PAUSDL_Rect@@@Z)".

Irgendetwas stimmt dort mit der Funtkion void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )

Weiß jemand wie ich diesen Fehler umgehe und woher er kommt?
Und kennt jemand eine bessere möglichkeit Text anzuzeigen, da mir das was ich dort erstellt habe, etwas ungeeignet finde und sehr durcheinander.
Ich hoffe mir kann jemand helfen.
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

Cookiezzz

Frischling

Beiträge: 91

Wohnort: Deutschland

Beruf: Schüler

  • Private Nachricht senden

2

24.12.2012, 17:05

Hi,

in deiner Font.cpp fehlt vor "apply_surface" ein "CFont::", deswegen ist CFont::apply_surface momentan nicht definiert und der Linker fängt an zu meckern.
Es muss also statt

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    SDL_Rect offset;

    //Get offsets
    offset.x = x;
    offset.y = y;
    //Blit
    SDL_BlitSurface( source, clip, destination, &offset );
}


so heißen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void CFont::apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    SDL_Rect offset;

    //Get offsets
    offset.x = x;
    offset.y = y;
    //Blit
    SDL_BlitSurface( source, clip, destination, &offset );
}


So viel zu deinem Problem. Eine bessere Möglichkeit der Textanzeige kenne ich aber nicht, da ich mich mit der SDL nicht auskenne.

Frohes Fest,
Cookiezzz

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

3

24.12.2012, 20:32

Willkommen im Forum.

Die Idee, das Spiel aus dem Buch zu erweitern finde ich schrecklich. Versuch lieber was eigenes wenn du etwas in der Konsole geübt hast. Dafür kannst du dir auch mal die SFML anschauen. :search:

Achja, wenn du ganze Quelltextdateien posten willst, dann bitte über www.pastebin.com oder etwas ähnlichem.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

4

25.12.2012, 00:09

Wenn er schon Erfahrung durch das Buch mit der SDL hat dann lass ihn auch dabei wenn er will. Man muss ja nicht auf Zwang gleich immer SFML nutzen.
Ganz im Gegenteil, ich finde ein Spiel aus einem Buch zu erweitern ist viel erfolgsversprechender. Man analysiert es und lernt es verstehen und kann dann _danach_ selber etwas eigenes aufziehen.
Da ich selbst sehr viel mit der SDL zu tun habe (zwecks Portierung) kannst du mich ansonsten auch gerne für weitere Fragen per ICQ konsultieren.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

5

25.12.2012, 01:28

Das Problem ist, dass das Spiel nicht wirklich gut geschrieben ist. Z.B. unterstützt die Spriteklasse keine Trennung von Image und den anderen Daten, was häufiger zu Problemen führt, die dann hier gepostet werden.

Ausserdem ist es viel schwieriger Code von anderen zu verstehen als ihn selbst zu schreiben, die SFML ist objektorientiert und muss nicht mehr gekapselt werden und man benötigt keine anderen Bibliotheken oder Erweiterungen solang man keine GUI oder ein Partikelsystem benötigt. Wie wir hier sehen ist ja schon das Zeichnen eines Textes ein Problem.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

6

25.12.2012, 02:23

Dafür gibt es bei der SFML ganz andere Probleme wie wir hier ja auch beinahe täglich sehen.
Und ob das Spiel gut geschrieben ist und ob eine Trennung vorliegt oder nicht sollte ja zu aller Anfang vollkommen egal sein.
Man fängt nicht an und möchte sofort perfekt struktuierten Code sondern erstmal alles verstehen und vor allem auch ein Resultat sehen.
Also wie ich schon sagte: wenn er bereits Erfahrung im Umgang mit der SDL hat und es nicht wirklich absolut unangenehm findet, sollte er dabei bleiben. Und ebenso den Code weiter analysieren und verstehen. Denn der funktioniert schließlich und somit lernt er nichts absolut falsches.
Und die SDL _muss_ nicht gekapselt werden. Man kann natürlich auch ohne Kapselung damit arbeiten.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

7

25.12.2012, 12:08

...dann würde ich es so machen, dass es ungefähr darauf hinausläuft:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
TTF_Init();
...
CFont font(file, size);//font aus datei laden
...
while(is_game_run)
{
    ...
    font.Render(x,y, text);//Surface erzeugen, blitten, freigeben
    ...
    SDL_Flip(screen); //Puffer umschalten
}
...
TTF_Quit();


Zu deinem Code:
-TTF_Init(), TTF_Quit() sollten nur einmal - ähnlich SDL_Init(), SDL_Quit() - aufgerufen werden und nicht für jede Instanz.
-SDL_Flip() gehört auch nicht in deine Font-Klasse.
-TTF_RenderText_Solid() erzeugt jedesmal eine neue Surface, die du nach jedem Rendern sofort wieder freigeben musst.
-TTF_RenderText_Solid() ist zwar sehr performant, das Ergebnis ist aber unsauber. Nimm lieber TTF_RenderText_Shaded() bzw. TTF_RenderText_Blended().
-TTF_CloseFont() gehört in den Destruktor;

Deine Klasse sollte dann also aus definiertem Konstruktor, definiertem Destruktor, und der Methode Render() bestehen.

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

8

26.12.2012, 21:48

Danke cookiezz
darauf habe ich garnicht geachtet.
mal schauen ob es nun funktioniert :D
EDIT:
nun bekomme ich diese Fehlermeldung
Fehler 1 error C2572: 'CFont::apply_surface': Neudefinition des Standardparameters: Parameter 5
weiß da jemand um rat?
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »xXSlayerXx« (26.12.2012, 21:55)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

9

26.12.2012, 22:09

weiß da jemand um rat?

Die Grundlagen lernen! Ohne SDL, nur in der Konsole.
Wieso? Du musst dich nicht mit den Eigenheiten und Anforderungen von zwei neuen Dingen rum schlagen und kannst dich auf C++ konzentrieren.
Der Fehler ist übrigens sehr aussagekräftig. Lies ihn einfach mal...
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige