Autor Beitrag
Sylvus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 195



BeitragVerfasst: 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 :D
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 :D
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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.
ausblenden volle Höhe 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:
30:
31:
32:
33:
34:
35:
36:
procedure TForm1.FormPaint(Sender: TObject);
var
  Buffer: TBitmap;
  Background: TBitmap;
  Cloud: Integer;
  OriginalCloud: TBitmap;
  TempCloud: TBitmap;
begin
  // Hintergrund in Buffer zeichnen
  Buffer.Canvas.Draw(00, Background);
  // oder
  Buffer.Assign(Background); // vermutlich besser, da nur kopiert wird

  // Wolken in Buffer zeichnen
  for Cloud := 0 to MaxClouds -1 do begin
    // Wolke erstellen und zeichnen
    TempCloud := TBitmap.Create;
    try
      // Größe festlegen
      TempCloud.PixelFormat := pf24bit;
      TempCloud.Width := 000;
      TempCloud.Height := 000;

      // Original Wolke in Temporäre zeichnen
      TempCloud.Canvas.StretchDraw (TempCloud.Canvas.ClipRect, OriginalCloud);

      // temporäre Wolke mittels Scanline auf Hintergrund aufbringen.
      // Das überlasse ich dir.
    finally
      TempCloud.Free;
    end;
  end;

  // Buffer zeichnen
  Form1.Canvas.Draw(00, 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 195



BeitragVerfasst: Sa 19.04.08 01:08 
Ich bin wohl zu doof :D 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:

ausblenden 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
    // Wolke erstellen und zeichnen
      WolkenTemp[I] := TBitMap.Create;
      try
      // Größe festlegen
        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;
      // Original Wolke in Temporäre zeichnen
        WolkenTemp[I].Canvas.StretchDraw(WolkenTemp[I].Canvas.ClipRect, Wolken[I]);
      // temporäre Wolke mittels Scanline auf Hintergrund aufbringen.
  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(00, Puffer); //Pufferzeichnung


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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 195



BeitragVerfasst: Sa 19.04.08 22:18 
Warum eigentlich nicht so??:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
    Wolke;
    // Wolken in Buffer zeichnen
    for I := 0 to 3 do begin
      // Wolke erstellen und zeichnen
      WolkenTemp := TBitMap.Create;
      WolkenTemp.Transparent := True; //Problem
      try
        // Größe festlegen
        WolkenTemp.PixelFormat := pf24bit;
        WolkenTemp.Width := WolkenPos[I].X div 2 div 4 * 2;
        WolkenTemp.Height := WolkenPos[I].X div 5 - 10;
        // Original Wolke in Temporäre zeichnen
        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(00, Puffer); //Pufferzeichnung


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:
ausblenden 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 :P Nochmals viele liebe Grüße Sylvus
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 195



BeitragVerfasst: 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:
ausblenden volle Höhe 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:
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(00, Puffer); //Pufferzeichnung

//...
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 //Wolkenbewegung
         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 = 255and (pPix1^.rgbtblue = 0and (pPix1^.rgbtred = 0then
               pPix1 := pPix1
            else
            begin
               pPix1^.rgbtRed := (pPix2^.rgbtRed + WolkenColor[I] + 255div 3;
               pPix1^.rgbtGreen := (pPix2^.rgbtGreen + WolkenColor[I] + 255div 3;
               pPix1^.rgbtBlue := (pPix2^.rgbtBlue + WolkenColor[I] + 255div 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// Größe festlegen
      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]); // Original Wolke in Temporäre zeichnen
      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 :D
Viele Grüße Sylvus
Einloggen, um Attachments anzusehen!
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 195



BeitragVerfasst: Mi 23.04.08 10:14 
Wenns zu schnell ist, resete doch einfach mal das lvl :D

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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.