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

1

13.03.2014, 15:39

Problem mit erstellen von Menü für Das SDL Spiel

Hallo liebe Community,

Ich habe mir für das SDL-Spiel ein Menü ausgedacht. Ganz einfach, ganz klein. Es hat nur einen Start und einen beende Button. Ich kann den Code aber nicht Kompilieren:
"menue.obj : error LNK2005: "public: __thiscall CMenue::CMenue(void)" (??0CMenue@@QAE@XZ) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "public: __thiscall CMenue::~CMenue(void)" (??1CMenue@@QAE@XZ) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "public: void __thiscall CMenue::Menue(void)" (?Menue@CMenue@@QAEXXZ) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "private: void __thiscall CMenue::SetColored(char * const)" (?SetColored@CMenue@@AAEXQAD@Z) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "private: void __thiscall CMenue::Update(class std::basic_string,class std::allocator >)" (?Update@CMenue@@AAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "private: void __thiscall CMenue::beenden(void)" (?beenden@CMenue@@AAEXXZ) ist bereits in main.obj definiert.
1>menue.obj : error LNK2005: "private: void __thiscall CMenue::start(void)" (?start@CMenue@@AAEXXZ) ist bereits in main.obj definiert.
1>C:\Users\Benni\Documents\Visual Studio 2012\Projects\SDL_Game (bearbeitet)\Debug\SDL_Game (bearbeitet).exe : fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.".

Ich habe nur die "main.cpp" verändert und eine "menue.cpp" reingepackt.

Main.cpp:

Quellcode

1
2
3
4
5
6
7
8
9
#include "menue.cpp"

int main (int argc, char *argv[])
{
    CMenue *Menue;
    Menue = new CMenue;
    Menue->Menue();
    return (0);
}

menue.h:

Quellcode

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
#include 
#include "Sprite.hpp"
#include "game.hpp"
#include "Framework.hpp"
class CMenue
{
public:
    CMenue();
    ~CMenue();
    void Menue();

private:
    CGame Spiel;
    CSprite m_Sprite_A;
    CSprite m_Sprite_BTN_Start;
    CSprite m_Sprite_BTN_Beenden;
    CFramework m_Frame;
    char *m_BTN[1];
    void Update(string Way);
    int num;
    void SetColored (char BTN[]);
    void start();
    void beenden();

};

menue.cpp:

Quellcode

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "Menue.h"

CMenue::CMenue()
{
    m_Sprite_BTN_Start.Load("Button_Start.bmp");
    m_Sprite_BTN_Start.SetPos(300, 400);
    m_Sprite_BTN_Start.SetColorKey(255, 0, 255);
    m_Sprite_BTN_Start.Render();
    m_Sprite_BTN_Beenden.Load("Button_Beenden.bmp");
    m_Sprite_BTN_Beenden.SetPos(230, 400);
    m_Sprite_BTN_Beenden.SetColorKey(255, 0, 255);
    m_Sprite_BTN_Beenden.Render();
    m_Sprite_A.Load("Arrow.bmp");
    m_Sprite_A.SetPos(300, 340);
    m_Sprite_A.SetColorKey(255, 0, 255);
    m_Sprite_A.Render();
    m_Frame.Flip();
    num = 0;
    m_BTN[0] = "Start";
    m_BTN[1] = "Beenden";
}

CMenue::~CMenue()
{
}

void CMenue::Menue(){
    // Framework initialisieren
    g_pFramework->Init (800, 600, 16, true);
    SDL_Event Event;

    // Gab es ein Event?
    if (SDL_PollEvent (&Event))
    {
// Ja, also schauen welches
switch (Event.type)
{
// Wurde eine Taste gedrückt?
case (SDL_KEYDOWN):
{
switch (Event.key.keysym.sym)
{
case (SDLK_DOWN):
{
Update("Down");
} 
case (SDLK_UP):
{
Update("Up");
}
case (SDLK_KP_ENTER):
{
Update("Enter");
}break;
}
} break;
}
    }
}
void CMenue::Update(string way){
    if(num > 2){}
    else{
if(way == string("Up"))
{
num--;
int y = 300 + num * 30 ;
int x = 340;
m_Sprite_A.SetPos(x, y);
}   
if(way == string("Down")){
num++;
int y = 300 - num * 30 ;
int x = 340;
m_Sprite_A.SetPos(x, y);
}
SetColored(m_BTN[num]);
    }
    if(way=="Enter"){
if(m_BTN[num] == "Start")
start();
if(m_BTN[num] == "Beenden")
beenden();
    }
}

void CMenue::start(){
    // Spiel initialisieren
    Spiel.Init ();

    // Spiel laufen lassen. Diese Funktion läuft so lange,
    // bis das Spiel geschlossen oder die Escape-Taste
    // gedrückt wird
    Spiel.Run ();
}

void CMenue::beenden(){
    // Spiel beenden
    Spiel.Quit ();
    // Framework beenden
    g_pFramework->Quit ();
    g_pFramework->Del ();
}

void CMenue::SetColored(char BTN[]){
    if(BTN == "Start"){
m_Sprite_BTN_Start.Load("Button_Start_A");
m_Sprite_BTN_Start.Render();
    }
    if(BTN == "Beenden"){
m_Sprite_BTN_Beenden.Load("Button_Beenden_A");
m_Sprite_BTN_Beenden.Render();
    }
    m_Frame.Flip();
}


Ich brauch Hilfe! :S
Ich hab jetzt schon ziemlich lang überlegt, was den Fehler verursachen könnte, komm aber nicht darauf. Ich habe auch schon die MSDN durchsucht und Google befragt, aber bis jetzt habe ich nichts brauchbares gefuden.
:dash:

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

2

13.03.2014, 15:45

Include Guard

Außerdem hast du teilweise leere includes (also nur #include ohne angabe einer Datei).
Du inkludierst die cpp Datei in deiner Main anstatt der Header Datei.

3

13.03.2014, 16:08

Danke für die schnelle Antwort.
Bei mir sind keine leeren includes mehr und ich habe jetzt auch die header Datei included nicht mehr die .cpp (wie Blöd kann man nur sein :dash: )
ich habe jetzt auch noch

Quellcode

1
2
#ifndef MENUE_H
#define MENUE_H

eingefügt.
Er spuckt jetzt zwar nicht mehr die ganzen fehler aus, ABER dafür kommt jetz das hier:
Unbehandelte Ausnahme bei 0x68125FC9 (SDL.dll) in SDL_Game (bearbeitet).exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000138

Was könnte das schon wieder für eine Ursache haben ?(

Swoerm

Alter Hase

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

4

13.03.2014, 17:16

Wenn ich sowas hier sehe

C-/C++-Quelltext

1
#include                
gibt es eigentlich nur eines zu sagen: Grundlagen wiederholen.

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

5

13.03.2014, 17:30

Ja richtig, aber man vergisst auch mal etwas oder vertippt sich.
Ich habe es übersehen und werde mehr darauf achten.

Lares

1x Contest-Sieger

  • Private Nachricht senden

6

14.03.2014, 14:00

Da hilft nur debuggen und den Fehlerraum eingrenzen.
Allgemein gibt es aber einige Sachen die mich irritieren. Beispielsweise warum du ein CFramework für das Menü erstellst, wenn du dafür das Singleton aus dem Ursprungsspiel verwenden kannst? Du solltest dich entscheiden, ob du das Singleton ( g_pFramework) benutzt oder ein Objekt (m_Frame) des Frameworks erstellst. Jetzt wo ich so darüber nachdenke...initalisierst du eigentlich m_Frame? Weil du dessen .flip()-Befehl nutzt, aber ich nirgendwo eine Initalisierung dessen sehe (und ich bezweifle, dass die Standardinitialiserung ausreicht).

7

14.03.2014, 14:51

Also ich habe jetzt m_Frame durch den Singleton g_pFramework ersetzt. Und der Debugger endet, wenn das Programm das erste mal zum Flip befehl kommt, also muss es irgendetwas damit zu tun haben. Ich habe allerdings nicht die leiseste Ahnung :hmm:

Lares

1x Contest-Sieger

  • Private Nachricht senden

8

14.03.2014, 15:04

Hast du auch den Konstruktor von CMenu geändert? Das könnte auch Probleme verursachen (ich weiß aber nicht, ob das dein Problem löst):
Du hast einmal nen Konstruktor mit normaler Signatur

Quellcode

1
CMenue::CMenue(){}


und einmal ne Methode, die ähnlich aussieht:

Quellcode

1
void CMenue::Menue(){...}



Es ist von der Semantik her nicht sinnvoll eine Methode wie den Konstruktor zu nennen. Entweder gehört das, was die Methode ausführt in den Konstruktor, oder sie erfüllt eine andere Aufgabe, weswegen man die Methode aussagekräftiger benennen kann.

In deinem Fall führt deine Methode die Initialisierung des Frameworks durch, der Konstruktor jedoch nicht. D.h. Solange du die Methode nicht explizit aufrufst, bevor du g_pFramework verwendest, wird es zu einen Crash kommen. Du solltest also noch mal genau überlegen, welche Befehle in den Konstruktor gehören und die Methode dann ensprechend umbenennen.

Werbeanzeige