Autor Beitrag
mick
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 159



BeitragVerfasst: Mi 29.12.04 00:10 
hi zusammen.


folgendes:
habe ein schachspielbrett - das panel "SpielfeldPanel" ist der container, drin ist ein gr. image als spielbrett und darauf diverse kleine images fuer die figuren (durchnumeriert: imgFeldXY).

nach jedem zug wird intern in einem array der zug berechnet (figuren gesetzt) und danach soll analog zu diesem array das grafische spielbrett neu gezeichnet werden - alle figuren. problem: nach jedem zug flimmert es da einmal fleissig, weil fuer jedes spielfeld (64 stueck) ein image geladen wird. unschoen.

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:
for i := 1 to 64 do begin  
   
 // Pfad zum Image der Figur errechnen, die dargestellt werden soll
 case AktuelleStellung[i] of
   // Auf Spielbrettfeld steht keine Figur
   0: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\0 - Leer_T.bmp';
   1: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\BauerWeiss_T.bmp';
  -1: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\BauerSchwarz_T.bmp';
   2: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\SpringerWeiss_T.bmp';
  -2: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\SpringerSchwarz_T.bmp';
   3: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\LaeuferWeiss_T.bmp';
  -3: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\LaeuferSchwarz_T.bmp';
   4: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\TurmWeiss_T.bmp';
  -4: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\TurmSchwarz_T.bmp';
   5: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\DameWeiss_T.bmp';
  -5: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\DameSchwarz_T.bmp';
   6: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\KoenigWeiss_T.bmp';
  -6: FigurenString_Pfad := ExtractFilePath(Application.ExeName) +
      'Grafik\Spiel-Figuren\Transparent\KoenigSchwarz_T.bmp';
 end;  // Von case-Anweisung
   
 // Entspr. Figurenimage ausfindig machen und Bild laden
  
 // Panel durchlaufen und nach Image-Komponenten suchen
 for j := 0 to SpielfeldPanel.ControlCount - 1 do
  if (SpielfeldPanel.Controls[j] is TImage) then
   // Ist das passende Grafik-Image zur internen Array-Komponente gefunden worden...
   if TImage(SpielfeldPanel.Controls[j]).Name = 'imgFeld' + IntToStr(i) then
    // ... lade das entspr. Bild in dieses Image
    TImage(SpielfeldPanel.Controls[j]).Picture.LoadFromFile(FigurenString_Pfad);

end;  // Von for-Schleife



wie gesagt, das funktioniert. doch um das flimmern zu minimieren dachte ich mir, es waere vorteilhaft, nicht mehr alle 64 images neu zu zeichnen, sondern nur doch diejenigen, die im vgl. zum vorigen zug veraendert wurden (zumeist nur eine figur).


1) wie sollte ich das machen? meine loesungsidee: pfad des geladenen bildes der jeweiligen imagekomponente auslesen und wenn dieser gleich dem neuen entspricht (= auf diesem spielfeld wurde keine figur bewegt), soll nichts neu geladen werden. was ist von dieser idee zu halten?


2) umsetzung: wie bekomme ich diesen pfad? etwa folgendermassen?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
// Entspr. Figurenimage ausfindig machen und Bild laden
   
// Panel durchlaufen und nach Image-Komponenten suchen
for j := 0 to SpielfeldPanel.ControlCount - 1 do
 if (SpielfeldPanel.Controls[j] is TImage) then
  // Ist das passende Grafik-Image zur internen Array-Komponente gefunden worden...
  if (TImage(SpielfeldPanel.Controls[j]).Name = 'imgFeld' + IntToStr(i)) and
     // ... und NEU: Nur wenn der alte Bildpfad NICHT dem neuen geforderten entspricht...
     (TImage(SpielfeldPanel.Controls[j]).Picture.GetNamePath <> FigurenString_Pfad) then
   // ... lade das entspr. Bild in dieses Image
   TImage(SpielfeldPanel.Controls[j]).Picture.LoadFromFile(FigurenString_Pfad);



sofern mit GetNamePath die von mir gewuenschte funktion ueberhaupt moeglich ist, stellt sich die frage, warum es dann trotzdem immer noch flimmert...


danke + ciao,
mijozi.


Zuletzt bearbeitet von mick am Do 30.12.04 18:42, insgesamt 1-mal bearbeitet
sibbe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50

WIN XP Prof
D7 Prof
BeitragVerfasst: Mi 29.12.04 01:07 
Also um das Flimmern abzustellen, gibts diverse Möglichkeiten. Evt. kannste dann trotzdem alles neu zeichnen, ohne dasses flimmert.

Meistens hilft ein einfachesDoublebuffered := True;im OnCreate

Ansonsten kanns an Windows liegen, das dir den Hintergrund andauernd neuzeichnet.
Dagegen kannste die Windowsmessage abfangen und unterbinden, im Klar-/Quell-Text (muhaha was ein Wortspiel :wink: )sieht das so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure <<DeineForm>>.StopFlicker(var Msg: TWMEraseBkgnd);
begin
  Msg.Result := 1;
end;
Die procedure musste dann lediglich noch unter private deklarieren procedure StopFlicker(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;und et vóila, wird der Hintergrund nicht mehr neugezeichnet.

Wenn die zwei Methoden nicht funktionieren, könntest du alle Figuren erst auf ein unsichtbares Bitmap zeichnen und dieses dann auf Form1.Canvas kopieren oder sowas in der Art. Das ist dann aber etwas aufwendiger.

Hoffe geholfen zu haben,
sibbe

_________________
Ideale sind wie Sterne: Man kann sie zwar nicht erreichen, aber man kann sich sehr wohl an ihnen orientieren.
(Blaise Pascal)
mick Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 159



BeitragVerfasst: Do 30.12.04 02:01 
hi sibbe.

danke fuer deine hilfe, werde es morgen mal probieren.

aber:
kann ich denn nicht den dateipfad eines bildes in einem image auslesen?
geht das vielleicht mit ExtractFilePath?


ciao,
mijozi.
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Sa 01.01.05 18:08 
vielleicht wird der irgendwo gespeichert, allerdings kann ich mir das eigentlich nicht vorstellen, denn das bild kann ja z.B. zu Entwicklungszeit in dein programm geladen werden, dass dann später auf einem system läuft, auf dem es diese Datei garnicht gibt.

allerdings könntest du andere eigenschaften der image Komponenten als zwischenspeicher missbrauchen (z.B.: tag: integer)

Jedoch ist das insgesammt eine etwas chaotische methode ein schachbrett darzustellen

andere möglichkeiten wären z.B.:
ein array im hintergrund, dass sich merkt, ob und was darauf steht (-1=nix;0=bauer;1=Turm...)
die Bilder könntest du dann alle zusammenfassen in einem großen, aus dem dann mittels BitBlt oder CopyRect die erforderlichen Bereiche auf das Formular kopiert werden.

MathiasH

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
mick Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 159



BeitragVerfasst: So 02.01.05 16:21 
hi!

ja, mit copyrect sollte vielleicht besser sein, aber ich arbeite jetzt eben mit all den image-komponenten. danke fuer den tipp mit dem tag-wert, so habe ich es jetzt hinbekommen. super!

ciao,
mijozi.