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

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

1

30.07.2009, 12:39

Zeiger aus Klasse einer Funktion übergeben

Hi
Ich wollte mal ein kleines Tetirs für die Konsole programmieren, habe leider schon am Anfang ein Problem. Ich möchte wie der Titel schon sagt einen Zeiger aus einer Klasse einer Funktion übergeben. Weil die Fehler kunterbunt und immer wieder anders und anderswo sind poste ich mal den ganzen Code:

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
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
// FLO Tetris 

#include <Pause.hpp>
#include <conio.h>
#include <windows.h>
#include <iostream>
using namespace std;
#pragma comment (lib, "winmm.lib")

// Prototypen

void Steuerung ();
void LinieLoesen (int *Pos1x, int *Pos1y, int *Pos2x, int *Pos2y, int *Pos3x, int *Pos3y, int *Pos4x, int *Pos4y, bool Besetzt);
void Spielfeld (int *Pos1x, int *Pos1y, int *Pos2x, int *Pos2y, int *Pos3x, int *Pos3y, int *Pos4x, int *Pos4y, int *Art, bool Besetzt);
//


// Klassen

class CObjekt
{
    public:
        int Pos1x;
        int Pos1y;
        int Pos2x;
        int Pos2y;
        int Pos3x;
        int Pos3y;
        int Pos4x;
        int Pos4y;
        int Art;
        bool *ObjektUnten;

    public:
        void Fallen (int *Pos1y, int *Pos2y, int *Pos3y, int *Pos4y, bool Besetzt);
        void Drehen (int *Pos1x, int *Pos1y, int *Pos2x, int *Pos2y, int *Pos3x, int *Pos3y, int *Pos4x, int *Pos4y, int *Art, bool Besetzt);
        void LinksBewegen (int *Pos1x, int *Pos2x, int *Pos3x, int *Pos4x, bool Besetzt);
        void RechtsBewegen (int *Pos1x, int *Pos2x, int *Pos3x, int *Pos4x, bool Besetzt);
        CObjekt ();
};
int main ()
{
    // Variablen

    srand (timeGetTime ());
    bool Besetzt[24][30];
    int x, y;

    for (x=0; x<24; x++)
    {
        for (y=0; y<30; y++)
        {
            Besetzt[x][y] = false;
        }
    }
    CObjekt Objekte[1000];
    bool *bQuit = false;   // BEI BEDARF ENTFERNEN


    int Zaehler = 0;    // Legt die Instanz fest die benutzt werden soll

    while (*bQuit == true)
    {
        Spielfeld (&Objekte[Zaehler].Pos1x, &Objekte[Zaehler].Pos1y, &Objekte[Zaehler].Pos2x, &Objekte[Zaehler].Pos2y, &Objekte[Zaehler].Pos3x, &Objekte[Zaehler].Pos3y, &Objekte[Zaehler].Pos4x, &Objekte[Zaehler].Pos4y, &Objekte[Zaehler].Art, Besetzt);
        Objekte[Zaehler].Fallen (&Objekte[Zaehler].Pos1y, &Objekte[Zaehler].Pos2y, &Objekte[Zaehler].Pos3y, &Objekte[Zaehler].Pos4y, Besetzt);
        Steuerung ();
    }
    
    Pause ();
    return 0;
}

CObjekt::CObjekt ()
{
    
    Pos1x = 15;
    Pos1y = -1;
    Pos2x = 15;
    Pos2y = -1;
    Pos3x = 15;
    Pos3y = -1;
    Pos4x = 15;
    Pos4y = -1;
    Art = (rand()%4)+1;
    ObjektUnten = false;
}


Die Fehlermeldungen die ich momentan bekomme ist:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
1>Tetris.obj : error LNK2028: Nicht aufgelöstes Token (0A000283) ""void __cdecl Spielfeld(int *,int *,int *,int *,int *,int *,int *,int *,int *,bool)" (?Spielfeld@@$$FYAXPAH00000000_N@Z)", auf das in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)" verwiesen wird.

1>Tetris.obj : error LNK2028: Nicht aufgelöstes Token (0A0002AB) ""void __cdecl Steuerung(void)" (?Steuerung@@$$FYAXXZ)", auf das in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)" verwiesen wird.

1>Tetris.obj : error LNK2028: Nicht aufgelöstes Token (0A0002C8) ""public: void __thiscall CObjekt::Fallen(int *,int *,int *,int *,bool)" (?Fallen@CObjekt@@$$FQAEXPAH000_N@Z)", auf das in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)" verwiesen wird.

1>Tetris.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""void __cdecl Steuerung(void)" (?Steuerung@@$$FYAXXZ)" in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)".

1>Tetris.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: void __thiscall CObjekt::Fallen(int *,int *,int *,int *,bool)" (?Fallen@CObjekt@@$$FQAEXPAH000_N@Z)" in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)".

1>Tetris.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""void __cdecl Spielfeld(int *,int *,int *,int *,int *,int *,int *,int *,int *,bool)" (?Spielfeld@@$$FYAXPAH00000000_N@Z)" in Funktion ""int __cdecl main(void)" (?main@@$$HYAHXZ)".

1>C:\Dokumente und Einstellungen\Eigene Dateien\Programmieren\Projekte\Tetris\Debug\Tetris.exe : fatal error LNK1120: 6 nicht aufgelöste externe Verweise.


Ich habe schon mehr als eine Stunde versucht es zu lösen aber nichts gefunden. :?

Danke im Voraus :D
Pi mal Daumen = 18.84955592

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

2

30.07.2009, 12:55

void func(); <--- da fehlt die definition!
also mach ein void func() { /* leerer rumpf */ } draus.
"Don't trust your eyes: They are a hell of a lot smarter than you are"

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

3

30.07.2009, 13:15

ich würde mir eher sorgen um das design machen.
ein spielstein sollte nicht wirklich mit soviel zeigern arbeiten müssen.

was spricht gegen so etwas:

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
27
28
struct Feld
{
    DWORD color;
    bool besetzt;
};
struct Position
{
    int x;
    int y;
};

Feld spielfeld[20][10];

class Stein
{
public:
    enum Direction {Left, Right};

    Stein(int type);
    
    bool CanFall(Feld [][10]);
    bool FallDown();
    bool CanRotate(Direction);
    bool Rotate(Direction);
    Position GetPosition(int index);
private:
    Position pos[4];
};


nur als tipp :)
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

4

30.07.2009, 13:55

@ChrisJ
So jetzt startet das Programm :D , mach dann aber den Laufzeit Fehler:

Quellcode

1
2
3
4
Eine nicht behandelte Ausnahme des Typs
"System.NullReferenceException" ist in Tetris.exe aufgetreten.

Zusätzliche Informationen: Der Objektverweis wurde nich auf eine Objektinstanz festgelegt.


Liegt wohl an der Variable "Zaehler".

@Gotbread
Sieht gut aus, habe aber dazu Fragen.

1.

C-/C++-Quelltext

1
DWORD color;
legt die Farbe fest oder? Wie mach man dann das sie die Farbe ausgibt.

2.

C-/C++-Quelltext

1
enum Direction {Left, Right};

was macht das denn genau. Muss ich dann die Koordinaten nich ändern?

3. Was ist

C-/C++-Quelltext

1
Stein (int type);


4. Warum machst du

C-/C++-Quelltext

1
Position GetPosition(int index);

und was ist Index.

5. Wie soll ich überprüfen ob z.B. eine Reihe voll ist um sie aufzulösen? (etc.)
Dazu brauche ich das bool Array "Besetzt".

Danke im Voraus
Pi mal Daumen = 18.84955592

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

5

30.07.2009, 14:13

Gottis code sollte nicht als lauffähige lösung gedacht sein, sondern als objekt-orientierter ansatz.

und benutz weniger zeiger, das tut ja weh.
"Don't trust your eyes: They are a hell of a lot smarter than you are"

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

6

30.07.2009, 14:19

@ChrisJ

Zitat von »"ChrisJ"«

@ChrisJ
...
...

Das seine nicht vollständig ist, ist mir klar. Irgendwas stimmt bei der von dir nicht :?

Zitat von »"ChrisJ"«

...
und benutz weniger Zeiger, das tut ja weh

Objekte die verändert werden, sollen doch als Zeiger übergeben werden. :?
Pi mal Daumen = 18.84955592

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

7

30.07.2009, 16:22

die frage ist aber, wie sie verändert werden. du übergibst der methode
einen zeiger auf deine daten, die dann geändert werden. besser wäre
es aber wenn die methode das ergebniss zurückgeben würde, damit
die daten per zuweisung zugewiesen werden.

zu deinen fragen.

1.) "DWORD color" steht hier für die farbe. (DWORD ist gleich unsigned long)

ob du dem feld eine farbe gibst, musst du wissen, du könnest die farbe
auch in der "position" speichern. wenn du wirklich eine farbausgabe machen
willst, guck dir diese funktion an, die aber nur unter windows
verfügbar ist.

2.) enum Direction.

damit legst du eine art datentyp an. du kannst die beispiel-funktion
"rotate" dann z.b. so aufrufen: "rotate(Left);" was doch besser ist,
als ein magic-value.

in der funktion "rotate" musst du natürlich die berechnungen für die
rotation ausführen, was die koordinaten ändern wird.

3.) Stein(int type);

das ist der konstruktor (abgk. c'tor) der klasse "stein". meiner meinung
nach macht der name "stein" in einem tetris-spiel mehr sinn als "CObject",
aber das bleibt dir überlassen wie das teil heißen soll.

type ist das c'tor-argument dass den typ (das aussehen) des steins fest-
legt, den normalerweise gibt es bei tetris verschiedene steine.

auch das bedeutet wieder, dass du das auch implementieren musst, aber
dabei können wir dir später noch helfen.

4.) Position:

"Position" ist ein eigener datentyp (struct) um x und y koordinate zusammen-
zufassen. du kannst da nehmen was du willst POINT, Vector2, Dot, Cookiebox... etc.

da ein stein aus mehreren "blöcken" besteht, bzw. bestehen sollte, macht
es sinn ein stein als ein array von blöcken abzuspeichern. da ein block
nur eine position hat (und evtl. farbe) behandeln wir ihn wie eine position.

da die funktion nicht weiß, welchen der blöcke wir haben wollen, hat sie
diesen parameter, z.b. "GetPosition(0)" holt den ersten "block".

damit kannst du später sehr leicht den beweglichen stein in das unbeweg-
liche spielfeld kopieren.

5.) reihe auflösen

dazu musst du einfach nur jede reihe durchgehen und gucken, ob alle
plätze besetzt sind.

beispielcode:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ich gehe davon aus, das du eine "Feld" struktur oder etwas ähnliches nutzt


for (unsinged i = 0; i < height; ++i) // jede reihe durchgehen

{
    bool full = true;
    for (unsigned j = 0; j < width; ++j) // jetzt jeden platz

    {
        if (!feld[i][j].besetzt) // aha, ein leeres feld

        {
            full = false;
            break;
        }
    }
    if (full) // eine volle reihe

    {
        // alle höheren reihen eins tiefer setzen

    }
}


so die exception:

welchen compiler verwendest du? normales C++ oder die .Net version?

(wahrscheinlich ist einer von deinen zeigerchen nicht initialisiert)
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

8

30.07.2009, 16:39

Ich würde vorschlagen, dass du nochmal die Grundlagen studierst, vor allem Enums, einfache Klassen, Arrays und Zeiger.

So leicht ist ein Tetris nämlich gar nicht. Da du die conio.h drin hast, würde ich mal gerne wissen welche Version, oder wo du die her hast, ... für Visual Studio gibt es eigentlich keine conio.h.

Alternativ kannst du dich aber hier umsehen.

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

9

30.07.2009, 20:36

Zitat von »"Gotbread"«

die frage ist aber, wie sie verändert werden. du übergibst der methode
einen zeiger auf deine daten, die dann geändert werden. besser wäre
es aber wenn die methode das ergebniss zurückgeben würde, damit
die daten per zuweisung zugewiesen werden.

Also das heißt z.B

C-/C++-Quelltext

1
Pos1x = BewegeNachLinks ();

so.

1.) An Farbe habe ich auch schon gedacht, wollte mich aber nicht überstürzen und es erstmal gelassen :?

2.) Das heißt Left/Right sind ganz normale Paramter.

3.) Über die Namen habe ich jetzt nicht so viel überlegt, aber Stein klingt auf jedenfall besser als Objekt.

Zitat von »"Gotbread"«

auch das bedeutet wieder, dass du das auch implementieren musst, aber dabei können wir dir später noch helfen.

Das habe ich schon 8)
(Kann ja mal posten)
Edit: Das Meißte

4.)

Zitat von »"Gotbread"«

da die funktion nicht weiß, welchen der blöcke wir haben wollen, hat sie diesen parameter, z.b. "GetPosition(0)" holt den ersten "block".

Hmm, wie diese Funktion genau aussehen soll ist mir noch nicht klar, aber die Funktion(also was sie macht) habe ich verstanden :D

5.)

Zitat von »"Gotbread"«

// ich gehe davon aus, das du eine "Feld" struktur oder etwas ähnliches nutzt
Ich hätte da ein zweidimensionales Array benutzt.


C-/C++-Quelltext

1
            break; 

In der Situation habe ich die Verwendung von break noch nicht gesehen
:?


C-/C++-Quelltext

1
// eine volle reihe 

müsste das nicht heißen eine leere Reihe :?


"bool besetzt" ist in bzw. auserhalb der Struktur "Feld" auf/mit(ka) false defniert.


Ich benutze normales C++ und Visual Studio Express.
Aber das ist doch eig. schon egal, ich fang warscheinlich nochmal neu mit coden an :)

@koschka
In meinem Buch wird das irgw. nicht so drangenommen mit Strukturen und gar nichts von Enums :?
conio.h habe ich einfach eingebunden. Das hat bisher immer funktioniert.
Version ka. Wo steht denn das? In den Includes habe ich die hier(falls das weiter hilft):


Quellcode

1
2
3
4
$(VCInstallDir)include
$(VCInstallDir)atlmfc\include
$(WindowsSdkDir)include
$(FrameworkSDKDir)include

und noch ein Paar von mir...

Zitat von »"koschka"«

hier

*freu*


Ich wollte mal ein Spiel programmieren das auch etwas Spielspaß hat.

Edit: Das Vorbild:
http://www.alexo.org/onlinespiele/tetris.php
Nur vom Prinzip und ohne verschiedene Level.
Pi mal Daumen = 18.84955592

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

10

30.07.2009, 21:49

so in der art.

eine bewegung nach links geht nur das objekt etwas an. vllt braucht sie
noch lesenden zugriff auf das spielfeld, aber sie sollte nichts zurückgeben.
allenfalls ein bool ob das geklappt hat. aber sonst nichts.

sehr gut. mit den extras warten bis es läuft.

joa z.b. Left ist einfach nur ein Name. das ist natürlich intern eine
zahl, aber für den menschen ist das leichter lesbar. (und enum ist sicherer
als #define).

gerne poste es :)

kurzer hinweis:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
Position GetPosition(int index)
{
    if (index >= 0 && index < 4) // feld 0...3, da wir nur 4 felder haben

       return positions[index]; // "positions" ist ein array von Position in der Stein klasse


    return Position(-1, -1); // error. sollte niemals auftreten.

    // du darfst auch eine exception schmeißen, mit "__asm int 3" den

    // debugger zum anhalten zwingen oder einfach crashen:

    ++*(int*)0;
}


natürlich. ich meinte damit ein zweidimensionales array aus "Feld"-strukturen

mit "break" beendet man eine schleife (nur und nur eine) sofort. sollte aber im C++ buch stehen

bisher bin ich immer davon ausgegangen, das tetris volle reihen
entfernt. viel spaß beim entfernen einer leeren reihe.

"besetzt" ist nur ne statusvariable.

und was willst du mit conio.h?
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

Werbeanzeige