Autor |
Beitrag |
Sylvus 
      
Beiträge: 195
|
Verfasst: Do 17.04.08 19:44
Argh, naja so ganz hab ich es nicht nicht
Also bei meinem Programm ziehen ja die Wolken von links nach rechts und werden dabei immer kleiner.
Damit dies nicht so ruckartig passiert, bräuchte ich schon so 100 Bilder, oder?
Deine Lösung habe ich wie folgt verstanden:
-Je nach Position der Wolke:
-In eine temporäre Variable das Bild mit strechdraw zeichnen
-Meine richtige Wolke mit der temporären überschreiben
-Richtige Wolke anzeigen und die Variable wieder freigeben
Richtig so? Also ich probiere es gerade mal so, wie oben beschrieben. Über eine Rückmeldung würde ich mich freuen
Viele Grüße Sylvus
//edit
hab grad mal was gefunde, was mich von StrechDraw befreien könnte. StretchBlt!
naja aber ich habs noch nicht ganz verstanden, hier mal der erste Versuch eines Codes (ja sehr falsch).
Bitte mich nicht gleich auslachen
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| SetStretchBltMode(Puffer.Canvas.Handle, HALFTONE); StretchBlt(Puffer.Canvas.Handle, WolkenPos[I].X, WolkenPos[I].Y, WolkenPos[I].X + WolkenPos[I].X div 2 div 4 * 2, WolkenPos[I].Y + WolkenPos[I].X div 5 - 10, Wolken[I].Canvas.Handle, WolkenPos[I].X, WolkenPos[I].Y, WolkenPos[I].X + WolkenPos[I].X div 2 div 4 * 2, WolkenPos[I].Y + WolkenPos[I].X div 5 - 10, SRCINVERT); |
Auf das es helfen möge..  LG Sylvus
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Fr 18.04.08 10:36
Schlechte Nachricht für dich. StrechDraw und StrechBlt ist ziemlich genau das Gleiche. Nur, dass eines innerhalb des TBitmaps gekappselt ist.
Ich muss gestehen, dass ich deine Herangehensweise nicht ganz verstehe. Das du die originale Wolke irgendwie überschreibst verwirrt mich etwas. Mag aber evtl auch daran liegen, dass ich heute noch nicht ganz auf der Höhe bin.
Okay. Ich wusste und dachte nicht, dass die Wolken von links nach recht kleiner werden. Hätte eher erwartet dass die unterschiedlich groß sind und nur von links nach rechts ziehen. Dann fällt natürlich die erste Methode raus. Du kannst nicht für jede Größe ein Wolkenbitmap erstellen. Der Speicherverbrauch wäre doch etwas zu viel des Guten.
Also bleibt wohl eher Methode 2. Und ich denke ein bisschen Code veranschaulicht das etwas besser wie ich denke. Dabei wird eine kleinere Kopie der originalen Wolke erstellt und diese in den Buffer eingerechnet.
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:
| procedure TForm1.FormPaint(Sender: TObject); var Buffer: TBitmap; Background: TBitmap; Cloud: Integer; OriginalCloud: TBitmap; TempCloud: TBitmap; begin Buffer.Canvas.Draw(0, 0, Background); Buffer.Assign(Background); for Cloud := 0 to MaxClouds -1 do begin TempCloud := TBitmap.Create; try TempCloud.PixelFormat := pf24bit; TempCloud.Width := 000; TempCloud.Height := 000;
TempCloud.Canvas.StretchDraw (TempCloud.Canvas.ClipRect, OriginalCloud);
finally TempCloud.Free; end; end;
Form1.Canvas.Draw(0, 0, Buffer); end; |
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Sylvus 
      
Beiträge: 195
|
Verfasst: Sa 19.04.08 01:08
Ich bin wohl zu doof  Vielleicht nen Link zu einem Delphi-Tutorial, welches mir nicht mehr erklärt was ne for-Schleife ist, aber mich mal über Scanline und Klasse... aufklärt? *g*
Also hier mein Code, wie er meiner Logik nach funktionieren müsste:
Delphi-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:
| for I := 0 to 3 do begin WolkenTemp[I] := TBitMap.Create; try WolkenTemp[I].PixelFormat := pf24bit; WolkenTemp[I].Height := WolkenPos[I].X + WolkenPos[I].X div 2 div 4 * 2; WolkenTemp[I].Width := WolkenPos[I].Y + WolkenPos[I].X div 5 - 10; WolkenTemp[I].Canvas.StretchDraw(WolkenTemp[I].Canvas.ClipRect, Wolken[I]); for y := 0 to WolkenTemp[I].height - 1 do begin pPix2 := WolkenTemp[I].ScanLine[y]; pPix1 := Background.ScanLine[Y + WolkenPos[I].Y]; for x := 0 to WolkenTemp[I].width - 1 do begin pPix1^.rgbtRed := pPix2^.rgbtRed; pPix1^.rgbtGreen := pPix2^.rgbtGreen; pPix1^.rgbtBlue := pPix2^.rgbtBlue; Inc(pPix1); Inc(pPix2); end; end; finally WolkenTemp[I].Free; end; end; Image1.Canvas.Draw(0, 0, Puffer); |
Funktioniert aber leider nicht, da jedes mal wenn ich die Funktion aufrufe Delphi abstürzt, mit der Fehlermeldung:
"Im Project Wolkenkatz.exe ist eine Exception der Klasse EInvalidGraphicOperation mit der Meldung "Bereichsüberschreitung bei Zeilenindex" aufgetreten."
Tja und jetzt?
Irgendwie bin ich echt nicht fähig  Also über eine weitere Antwort würde ich mich sehr freuen!
Viele Grüße Sylvus
P.S. Ich hatte es auch schon mal hin bekommen, dass er alles mit einer riesigen Wolke übermalt, aber das kann es ja auch nicht sein^^
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Sa 19.04.08 09:22
Also deine Einrückung ist gruselig.
Und ScanLines. Es gibt ein Tutorial aber den Link hab ich gerade nicht zur Hand. Aber Scanline macht nichts anderes als dir den Pointer auf den Datenbereich einer Bildzeile eines Bitamps zurückliefern. Mit anderen Worten. ScanLine[0] gibt den Pointer auf die erste Zeile zurück. Sobald du etwas dort hin schreibst wohin der Pointer zeigt landet es auch sogleich im Bitmap.
"Bereichsüberschreitung bei Zeilenindex" bedeutet du hast versucht auf eine nicht existierende Zeile zuzugreifen. Also Entweder kleiner "-1" oder größer "Height -1". Ich denke es liegt an dem Hintergrund. Du solltest natürlich vor den Zeichnen einer Zeile überprüfen ob der Hintergrund auch großgenug ist. Denn Hintergrund = 800 pixel hoch und du zeichnest eine 200 Pixel hohe Wolke an die Position 700, dann knallt es irgendwann.
Aber ich frage mich gerade warum du eine Array von TempWolken hast? Du hast nur eine Temporäre Wolke. Versuch es doch einfach mal so zu machen, dass du NUR die erste Wolke zeichnest. Und anschließend kannst du es erweitern, dass mehrere Wolken gehen. Denn wie du selbst festgestellt hast ist das kein leichtes Thema und da musst du dich vorsichtig ran tasten.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Sylvus 
      
Beiträge: 195
|
Verfasst: Sa 19.04.08 22:18
Warum eigentlich nicht so??:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| Wolke; for I := 0 to 3 do begin WolkenTemp := TBitMap.Create; WolkenTemp.Transparent := True; try WolkenTemp.PixelFormat := pf24bit; WolkenTemp.Width := WolkenPos[I].X div 2 div 4 * 2; WolkenTemp.Height := WolkenPos[I].X div 5 - 10; WolkenTemp.Canvas.StretchDraw(WolkenTemp.Canvas.ClipRect, Wolken[I]); Wolken[I].Assign(WolkenTemp); Puffer.Canvas.Draw(WolkenPos[I].X, WolkenPos[I].Y, Wolken[I]); finally WolkenTemp.Free; end; end; Image1.Canvas.Draw(0, 0, Puffer); |
Dabei hab ich nur ein Problem, die Transparents
Also beim ersten mal zeichnem gehts noch super und dann wirds immer schlechter bis die Wolken gar nicht mehr neu auftauchen...also irgendwie geht das nicht so richtig.
Weiß auch nicht genau woran es liegt, könnte auch die Temporäre Wolke ins Puffer zeichnen also:
Delphi-Quelltext 1:
| Puffer.Canvas.Draw(WolkenPos[I].X, WolkenPos[I].Y, WolkenTemp); |
aber dann funktioniert meine transparents nur bei ganz wenig Pixeln....hmmm irgendwie muss ich da was ändern, nur was  Nochmals viele liebe Grüße Sylvus
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: So 20.04.08 13:15
Die "Transparenz" die Delphi da meint ist eher ein Masking. Dabei wird eine transparente Farbe einfach ausgelassen. Der Rest wird voll gezeichnet. Und du brauchst aber richtige Transparenz. Es gibt zwar eine Funktion AlphaBlend in der Windows API aber damit habe ich bisher nichts gemacht. Die zweite Möglichkeit wäre das alles mit ScanLines zu lösen. Also händisch.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Sylvus 
      
Beiträge: 195
|
Verfasst: So 20.04.08 17:21
Hey, also naja am Anfang funktioniert es, dann aber nicht mehr...irgendwie liegt das noch an meiner Struktur.
Folgender 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:
| Puffer.Assign(Background); Puffer.Canvas.StretchDraw(rect(SchornsteinPos.X, SchornsteinPos.Y, SchornsteinPos.X + 130, Image1.Top + Image1.Height), Schornstein); Puffer.Canvas.StretchDraw(rect(PlayerPos.X, PlayerPos.Y, PlayerPos.X + 130, PlayerPos.Y + 79), Player); if DachPos.X > -100 then Puffer.Canvas.StretchDraw(rect(DachPos.X, DachPos.Y, DachPos.X + 100, Image1.Top + Image1.Height), Dach); Wolke; Image1.Canvas.Draw(0, 0, Puffer); procedure TForm1.Wolke; var I, y, x: integer; pPix1, pPix2: PRGBTriple; begin randomize; for I := 0 to 3 do begin if WolkenPos[I].X div 2 div 4 * 2 < 5 then WolkenPos[I].X := 1200; for y := 0 to Wolken[I].height - 1 do begin pPix1 := Wolken[i].ScanLine[y]; pPix2 := Background.ScanLine[Y + WolkenPos[I].Y]; Inc(pPix2, WolkenPos[I].X); for x := 0 to Wolken[I].width - 1 do begin if (pPix1^.rgbtGreen = 255) and (pPix1^.rgbtblue = 0) and (pPix1^.rgbtred = 0) then pPix1 := pPix1 else begin pPix1^.rgbtRed := (pPix2^.rgbtRed + WolkenColor[I] + 255) div 3; pPix1^.rgbtGreen := (pPix2^.rgbtGreen + WolkenColor[I] + 255) div 3; pPix1^.rgbtBlue := (pPix2^.rgbtBlue + WolkenColor[I] + 255) div 3; end; Inc(pPix1); Inc(pPix2); end; end; WolkenTemp := TBitMap.Create; WolkenTemp.PixelFormat := pf24bit; Wolken[I].PixelFormat := pf24Bit; WolkenTemp.Width := WolkenPos[I].X div 2 div 4 * 2; WolkenTemp.Height := WolkenPos[I].X div 5 - 10; WolkenPos[I].X := WolkenPos[I].X - (Lvl.Tag + 3) - Speedfactor; WolkenTemp.Canvas.StretchDraw(WolkenTemp.Canvas.ClipRect, Wolken[I]); Wolken[I].Assign(WolkenTemp); WolkenTemp.Transparent := true; Puffer.Canvas.Draw(WolkenPos[I].X, WolkenPos[I].Y, WolkenTemp); WolkenTemp.Free; end; end; |
Und das Programm findest du im Anhang
Na vielleicht hast du ja Lust mal rein zu schauen, ich probiere auf jeden Fall mal weiter
Viele Grüße Sylvus
Einloggen, um Attachments anzusehen!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 22.04.08 21:07
Also ich muss gestehen, dass ich mit der Anwendung nichts anfangen kann, da es bei mir sehr schnell läuft. Evtl wäre es ganz praktisch, wenn du mal den den kompletten code inklusive alle benötigten Dateien hochlädst. So das wir uns den evtl mal anschauen. Denn mit dem Code weiß ich auch gerade nicht wo was faul sein könnte.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Sylvus 
      
Beiträge: 195
|
Verfasst: Mi 23.04.08 10:14
Wenns zu schnell ist, resete doch einfach mal das lvl
Ja, ich lad mal das komplette Projekt hoch, ist nicht kompiliert und die temporären Datein sind gelöscht (wegen der Größe). Hoffe du kannst es öffnen, habe es mit Delphi 2005 erstellt
Viele liebe Grüße Sylvus
Einloggen, um Attachments anzusehen!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mi 07.05.08 19:31
Hallo Sylvus tschuldige, dass ich so lange gebraucht habe. Ich habe es ein bisschen verpennt und kaum Zeit gehabt. Und so große fremde Projekt durchsuchen sind nicht sonderlich hoch priorisiert.
Mit deinem Projekt bin ich leider so gar nicht klar gekommen. Deshalb habe ich mich mal hingesetzt und habe das mal eben selber gemacht. Ich hoffe du kannst mit dem Code noch etwas anfangen.
Zum Kompilieren benötigst du die Resource aus dem anderen Projekt.
Einloggen, um Attachments anzusehen!
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
|