DirectDraw: Scrolling (Problem: Zeiger auf ein LPDRIECTDRAWSURFACE7-Array)
-
Ich bin gerade dabei mit DirectDraw ein Objekt namens Background zu schreiben, dem ein Array beliebiger Größe mit Öberflächen, die Hintergrundgrafiken enthalten, übergeben werden kann. Die Hintergrundgrafiken und das Fenster haben eine Auflösung von 640x480. Damit werden die Grafiken also einfach nur hintereinander gesetzt. Das Objekt funktioniert mit zwei Öberflächen (dafür aber ohne Arrays) einwandfrei. Nun meckert aber der Compiler, wenn ich das Array übergeben will.
Background.h:
#pragma once #include <ddraw.h> class Background { private: LPDIRECTDRAWSURFACE7 lpDDSBackground; // Soll auf das Array zeigen LPDIRECTDRAWSURFACE7 lpDDSPart1; // Diese beiden Zeiger zeigen immer auf die beiden LPDIRECTDRAWSURFACE7 lpDDSPart2; // Grafiken, die gerade dargestellt werden int number; // Anzahl der Grafiken (wird durch das Array berechnet) int current; // Die Aktuelle Grafik (lpDDSPart1!) entsprechend der Reihenfolge im Array int x; // Wie viel wird von der Aktuelle Grafik auf dem Bild dargestellt int dx; // Scroll-Geschwindigkeit public: Background(); ~Background(); void CreateBackground(LPDIRECTDRAWSURFACE7 lpDDSB, int d); void MoveLeft(); void MoveRight(); void Draw(LPDIRECTDRAWSURFACE7 lpDDSScreen); };Background.cpp (CreateBackground):
void Background::CreateBackground(LPDIRECTDRAWSURFACE7 lpDDSB, int d) { lpDDSBackground = lpDDSB; lpDDSPart1 = lpDDSBackground[0]; lpDDSPart2 = lpDDSBackground[1]; number = sizeof(lpDDSBackground) / 4; current = 1; dx = d; }Für Zeile 4 und 5 und spuckt folgende Fehlermeldungen aus:
1>c:\users\martin\documents\visual studio 2005\projects\scrolling\scrolling\background.cpp(13) : error C2440: '=': 'IDirectDrawSurface7' kann nicht in 'LPDIRECTDRAWSURFACE7' konvertiert werden
1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
1>c:\users\martin\documents\visual studio 2005\projects\scrolling\scrolling\background.cpp(14) : error C2440: '=': 'IDirectDrawSurface7' kann nicht in 'LPDIRECTDRAWSURFACE7' konvertiert werden
1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werdenDie selben Fehler entstehen bei der Funktion MoveLeft() und MoveRight():
Background.cpp (MoveLeft):
void Background::MoveLeft() { LPDIRECTDRAWSURFACE7 lpDDStmp; if (x - dx < 0) { x = SCR_WIDTH + (x - dx); if (current != 1) current--; else current = number; lpDDSPart1 = lpDDSBackground[current]; lpDDSPart2 = lpDDSBackground[current+1]; } else { x -= dx; } }Wie ist es möglich diesen Fehler zu vermeiden?
-
Solche Fehler krieg ich auch andauernd, wenn ich die (eigentlich klar definierte) LP-Struktur verwende (also die long pointer),
Nimm in deinem Falle einfach IDirectDrawSurface7 *varName; <-- Das ist im Endeffekt genau dasselbe wie LPDIRECTDRAWSURFACE7 (Frag mich net wieso der das nicht akzeptiert, macht er ja bei manchen Devices, bei manchen nicht)
Greetings,
Chaos
-
Danke für Deine Hilfe! Das Problem hat sich jetzt aber leider etwas verlagert. Da dem Objekt nun Arrays übergeben werden können habe ich ein Array mit drei Oberflächen erstellt und dann der Funktion CreateBackground übergeben.
IDirectDrawSurface7* backg[] = {ddc.CreateSurfaceFromBitmap("d:\\h1.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h2.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h3.bmp", SCR_WIDTH, SCR_HEIGTH)}; b1.CreateBackground(*backg, 7); // die 7 ist das Scrolltempo - also unwichtigSoweit klappt alles prima. Sobald aber die Funktion Draw aufgerufen wird, schmiert mir alles ab und ich muss das Programm >>gewaltsam<< beenden. Nach einigem rumprobieren habe ich dann die Ursache gefunden. Wenn ich nur lpDDSPart1 auf die Oberfläche zeichne läuft alles problemlos, was bedeutet, dass die Grafiken erfolgreich geladen und das Array (jedenfalls teilweise) erfolgreich übergeben worden ist. Scheinbar kann ich von dem übergebenen Array aber nur [0] zeichnen.
Hier ist nochmal der Code:
void Background::CreateBackground(IDirectDrawSurface7* lpDDSB, int d) { lpDDSBackground = lpDDSB; lpDDSPart1 = &lpDDSBackground[0]; // wird ohne Probleme gezeichnet lpDDSPart2 = &lpDDSBackground[1]; // stürzt beim zeichnen ab :( number = sizeof(lpDDSBackground) / 4; current = 1; dx = d; }... und für die Draw-Funktion ():
void Background::Draw(LPDIRECTDRAWSURFACE7 lpDDSScreen) { RECT Part1R; RECT Part2R; Part1R.left = x; Part1R.right = SCR_WIDTH; Part1R.top = 0; Part1R.bottom = SCR_HEIGTH; Part2R.left = 0; Part2R.right = x; Part2R.top = 0; Part2R.bottom = SCR_HEIGTH; lpDDSScreen->BltFast(0, 0, lpDDSPart1, &Part1R, DDBLTFAST_WAIT); lpDDSScreen->BltFast(SCR_WIDTH - x, 0, lpDDSPart2, &Part2R, DDBLTFAST_WAIT); // wenn ich die Zeile weglasse, // wird das erste Bild auf der // Oberfläche ausgegeben }Wo liegt der Fehler?
-
Das Problem ist halt dass du 0 Ahnung von C++ hast:
IDirectDrawSurface7* backg[] = {ddc.CreateSurfaceFromBitmap("d:\\h1.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h2.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h3.bmp", SCR_WIDTH, SCR_HEIGTH)}; b1.CreateBackground(backg, sizeof(backg)/sizeof(backg[0]), 7); // die 7 ist das Scrolltempo - also unwichtig void Background::CreateBackground(IDirectDrawSurface7** lpDDSB, int numbkg, int d) { lpDDSBackground = lpDDSB; lpDDSPart1 = lpDDSBackground[0]; lpDDSPart2 = lpDDSBackground[1]; number = numbkg; current = 1; dx = d; }Lies dir Tutorials/... zu sizeof, Arrays, Zeigern und abstrakten Klassen durch, dann weisst du wieso es nicht funktioniert wie du es gemacht hast.
-
Gut. Ich habe den Code jetzt verändert und den Doppelzeiger eingebaut, wie Du es oben geschrieben hast:
IDirectDrawSurface7* backg[] = {ddc.CreateSurfaceFromBitmap("d:\\h1.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h2.bmp", SCR_WIDTH, SCR_HEIGTH), ddc.CreateSurfaceFromBitmap("d:\\h3.bmp", SCR_WIDTH, SCR_HEIGTH)}; b1.CreateBackground(backg, sizeof(backg)/sizeof(IDirectDrawSurface7), 7);void Background::CreateBackground(IDirectDrawSurface7** lpDDSB, int numbkg, int d) { lpDDSBackground = *lpDDSB; lpDDSPart1 = lpDDSBackground[0]; lpDDSPart2 = lpDDSBackground[1]; number = numbkg; current = 1; dx = d; }Leider bekomme ich vom Compiler damit folgende Fehlermeldung:
1>c:\users\martin\documents\visual studio 2005\projects\scrolling\scrolling\background.cpp(13) : error C2440: '=': 'IDirectDrawSurface7' kann nicht in 'IDirectDrawSurface7 *' konvertiert werden
1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
1>c:\users\martin\documents\visual studio 2005\projects\scrolling\scrolling\background.cpp(14) : error C2440: '=': 'IDirectDrawSurface7' kann nicht in 'IDirectDrawSurface7 *' konvertiert werden
1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werdenDann habe ich nochmal in meinen Büchern nachgelesen und den Code abgeändert:
void Background::CreateBackground(IDirectDrawSurface7** lpDDSB, int numbkg, int d) { lpDDSBackground = *lpDDSB; *lpDDSPart1 = lpDDSBackground[0]; *lpDDSPart2 = lpDDSBackground[1]; number = numbkg; current = 1; dx = d; }Jetzt wird es erfolgreich compiliert, stürzt aber wieder ab. Diesmal sogar, wenn ich lpDDSPart1 zeichnen will.
-
Alles klar ... hat sich erledigt.