![]() |
Canvas Flackert bei Refresh
Hi.
Ich probiere gerade mein erstes Computerspiel zuprogrammieren =). Und für den Anfang möchte ich erstmal mit dem Canvas Objekt arbeiten. Das Problem ist nur, dass es flackert wenn es schnell hintereinander neu gezeichnet wird. Wie kann man sowas umgehen ?. Ich hab die Hauptfunktionen vom Spiel im "IdleEventHandler" geschrieben, kann man das so machen ?. Den Canvas Lösche ich mit: Form1.Canvas.Brush := Brush; //select brush Form1.Canvas.FillRect(Form1.ClientRect); //redraw form Und zeichne ich mit: Form1.Canvas.Rectangle(x,y,100+x,100+y); Form1.Canvas.Rectangle(x1,y1,x2,y2); wieder neu Hier Mein kompletter Quelltext: Hoffe ihr könnt mir helfen ; /
Delphi-Quellcode:
unit delphigame;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; function ColCheck:Boolean; procedure MovePlayer; procedure SpawnEnemy; procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } procedure IdleEventHandler(Sender: TObject; var Done: Boolean); public { Public declarations } end; var Form1: TForm1; movingUp : boolean; movingDown : boolean; movingRight : boolean; movingLeft : boolean; x,y : Integer; oldx, oldy : Integer; x1,y1,x2,y2 : Integer; the_time : TDateTime; GameStarted : Boolean; Level: Integer; Enemies : Integer; EnemySpawned : Boolean; implementation procedure TForm1.IdleEventHandler(Sender: TObject; var Done: Boolean); begin If GameStarted then begin Oldx := x; Oldy := y; MovePlayer; if (Mouse.CursorPos.x > Left) And (Mouse.CursorPos.x < (Form1.Width + Left)) then x:= Mouse.CursorPos.x - left-50; if (Mouse.CursorPos.y > top) And (Mouse.CursorPos.y < (Form1.height + top)) then y:=Mouse.CursorPos.Y - top-50; SpawnEnemy; Sleep(5); Form1.Canvas.Brush := Brush; //select brush Form1.Canvas.FillRect(Form1.ClientRect); //redraw form If ColCheck then begin Canvas.Brush.Color := clRed end else Canvas.Brush.Color := clBlack; Form1.Canvas.Rectangle(x,y,100+x,100+y); Form1.Canvas.Rectangle(x1,y1,x2,y2); // Label2.Caption := IntTOStr(x); // Label3.Caption := IntTOStr(y); {Do a small bit of work here} Done := false; If Colcheck then begin Button1.Visible := TRUE; Label4.Visible := TRUE; Label5.Caption := 'Score: '+IntToStr(Level); Label5.Visible := True; GameStarted := FALSE; end; end; end; {$R *.dfm} procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of vk_left: begin movingLeft := True; movingRight := False; end; vk_right: begin movingLeft := False; movingRight := True; end; vk_up: begin movingUp := True; movingDown := False; end; vk_down: begin movingUp := False; movingDown := True; end; // vk_space: BulletFired; end; end; procedure TForm1.MovePlayer; begin if movingUp AND (y>=0) then y:=y-2; if movingDown AND (y <= Form1.Height-100) then y:=y+2; if movingLeft AND (x>=0) then x:=x-2; if movingRight AND (x <= Form1.Width-100) then x:=x+2; end; function TForm1.ColCheck:Boolean; begin //Check for collision. result := false; If ((x2 >= x) AND (x2<=x+100) AND (y1 >= y) AND (y1<=y+100)) OR ((x1 >= x) AND (x1<=x+100) AND (y1 >= y) AND (y1<=y+100)) OR ((x1 >= x) AND (x1<=x+100) AND (y2 >= y) AND (y2<=y+100)) OR ((x2 >= x) AND (x2<=x+100) AND (y2 >= y) AND (y2<=y+100)) then begin Label1.Caption := ' BOOOOOOOOOM '; result:=true; end; end; procedure TForm1.SpawnEnemy; begin If not EnemySpawned then begin Randomize; Level := Level+1; x1 := 0+Random(Form1.Width); y1 := Form1.Height; x2 := x1+Random(50)+50; y2 := Form1.Height+Random(50)+50; Form1.Canvas.Rectangle(x1,y1,x2,y2); EnemySpawned := TRUE; end; //Move Enemy Upwards y1 := y1 - Level; y2 := y2 - Level; If y2 < 0 then EnemySpawned := FALSE; end; procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of vk_left : movingLeft := False; vk_right : movingRight := False; vk_up : movingUp := False; vk_down : movingDown := False; end; end; procedure TForm1.FormCreate(Sender: TObject); begin the_time := Time; GameStarted := TRUE; Application.OnIdle := IdleEventHandler; end; procedure TForm1.Button1Click(Sender: TObject); begin GameStarted := TRUE; Button1.Visible := FALSE; Level := 1; end; end. |
Re: Canvas Flackert bei Refresh
Ich würde jegliches Zeichnen ins OnPaint des Formulars verlagern und im OnCreate DoubleBuffered auf true setzen.
|
Re: Canvas Flackert bei Refresh
Hallo,
Funktioniert leider nicht :(.. Wird Onpaint nicht auch erst ausgeführt wenn was gezeichnet wird ?
Delphi-Quellcode:
Was hat es mit dem "Double Buffered" auf sich ?.
procedure TForm1.FormPaint(Sender: TObject);
begin Form1.Canvas.Brush := Brush; //select brush Form1.Canvas.FillRect(Form1.ClientRect); //redraw form Form1.Canvas.Rectangle(x,y,100+x,100+y); Form1.Canvas.Rectangle(x1,y1,x2,y2); end; ~stift |
Re: Canvas Flackert bei Refresh
FormPaint wird ausgeführt, wenn das Formular sich neu zeichnen muss, das ist richtig. Dieses Ereignis kannnst Du aber mit Repaint selbst auslösen. Und das DoubleBuffered soll ein Flackern vermeiden, indem jegliche Zeichenoperationen zunächst in ein Offscreen-Bitmap gezeichnet werden und dies dann mit einem Schlag auf die Zeichenfläche des Formulars gepönt wird.
|
Re: Canvas Flackert bei Refresh
Oh super =).
Klappt alles bestens jetzt. Vielen Dank! :) ~stift |
AW: Canvas Flackert bei Refresh
Bei mir hat dieser Kram mit DoubleBuffered:=true nie wirklich funktioniert. Aber ich habe jetzt einfach ein Bitmap Bmp genommen und auf Bmp.Canvas gezeichnet und dann am Ende PaintBox.Canvas.Draw(Bmp) gemacht. Das geht gut!
|
AW: Canvas Flackert bei Refresh
DoubleBuffered und direktes Zeichnen auf ein Canvas können sich schon in die Quere kommen.
Und das was du mit dem Bitmap gemacht hast, das nennt sich ein OffscreenBitmap, was bei sowas auch sehr häufig zum Einsatz kommt. Vorallem dann, wenn selten auf den Canvas gezeichnet wird und das Zeichnen einen gewissen Aufwand bedeutet (dann kann man es im Notfall, im OnPaint, schnell wiederherstellen, ohne es jedesmal neu zeichnen zu müssen) oder eben wenn die Ausgabe flackert, weil das Zeichnen zu lange dauert, so daß das Auge es mitbekommen könnte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz