![]() |
Flackern auf einer Map verhindern...
hi leutz!
heute schon der 3. thread zu meinem RPG ;) yo... ganz schnell: wie kann ich es verhindern, dass meine Map/Karte bei jedem Neuzeichnen flackert? bzw... kann wer folgende funktion verbessern?
Delphi-Quellcode:
viel spaß beim lesen ;)
procedure MapRenew;
var aai,i,ii,iii: integer; MyRect,MyRect2: TRect; bitmap: TBitmap; ctype: string; center: TPoint; begin if map[charx,chary].Begehbar = false then begin charx := map[0,0].startx; chary := map[0,0].starty; form1.Popup1.Title := 'ACHTUNG:'; form1.Popup1.Text := 'Der Charakter war auf einem unzulässigen Feld! Er wurde zurückgesetzt!'; end; ctype := ini.ReadString('Char','type',''); MyRect2 := Rect(0,0,32,32); if charx < 1 then charx := 1; if chary < 1 then chary := 1; character.mapx := charx; character.mapy := chary; form5.paintbox1.canvas.brush.style := bsclear; center := Point(form5.Paintbox1.Width div 2-16,form5.Paintbox1.Height div 2-16); for i := -2 to 2 do for ii := -2 to 2 do try MyRect := Rect(i*32+center.x,ii*32+center.y,i*32+center.x+32,ii*32+center.y+32); Bitmap:=TBitmap.Create; if (charx+i > 0) and (chary+ii > 0) then begin if FileExists('IMG/Map/'+map[charx+i,chary+ii].Textur) then begin Bitmap.LoadFromFile('IMG/Map/'+map[charx+i,chary+ii].Textur); end else Bitmap.LoadFromFile('IMG/Map/none.bmp'); end else Bitmap.LoadFromFile('IMG/Map/none.bmp'); form5.PaintBox1.Canvas.BrushCopy(MyRect,Bitmap,MyRect2,clfuchsia); if (charx+i > 0) and (chary+ii > 0) then begin if map[charx+i,chary+ii].Textur2 <> '' then begin Bitmap.LoadFromFile('IMG/Map/'+map[charx+i,chary+ii].Textur2); form5.PaintBox1.Canvas.BrushCopy(MyRect,Bitmap,MyRect2,clfuchsia); end; end; finally end; MyRect := Rect(center.x,center.y,center.x+32,center.y+32); if fileexists('DATA/TEMPLATES/'+ctype+'/char_'+character.gender+'.bmp') then begin Bitmap.LoadFromFile('DATA/TEMPLATES/'+ctype+'/char_'+character.gender+'.bmp'); end else begin Bitmap.LoadFromFile('IMG/Map/nochar.bmp'); end; form5.PaintBox1.Canvas.BrushCopy(MyRect,Bitmap,MyRect2,clfuchsia); {for i := 0 to 1000 do begin if NPCs[i].name <> '' then begin Bitmap.LoadFromFile(NPCs[i].smallpic); //MyRect := Rect((NPCs[i].x+center.x)*32,(NPCs[i].y*+center.y)*32,(NPCs[i].x+center.x)*32+32,(NPCs[i].y+center.y)*32+32); MyRect := Rect(i*32+center.x,ii*32+center.y,i*32+center.x+32,ii*32+center.y+32); form5.PaintBox1.Canvas.BrushCopy(MyRect,Bitmap,MyRect2,clfuchsia); end; end;} for iii := 0 to 1000 do begin if NPCs[iii].name <> '' then begin for i := -2 to 2 do begin for ii := -2 to 2 do begin if NPCs[iii].x = charx + i then begin if NPCs[iii].y = chary + ii then begin Bitmap.LoadFromFile(NPCs[iii].smallpic); MyRect := Rect(i*32+center.x,ii*32+center.y,i*32+center.x+32,ii*32+center.y+32); form5.PaintBox1.Canvas.BrushCopy(MyRect,Bitmap,MyRect2,clfuchsia); end; end; end; end; end; end; |
Re: Flackern auf einer Map verhindern...
Schon
Code:
eingestellt?
doublebuffered:=true;
|
Re: Flackern auf einer Map verhindern...
ja, also meine paintbox1 liegt auf:
Form5 => Groupbox1 (oder 2) => pbox1 ich habs sowohl bei der form, als auch bei der groupbox angemacht => nix :( |
Re: Flackern auf einer Map verhindern...
Also, ich habe es bei mir direkt ins OnCreate-Ereignis der Form geschrieben, bei mir flackert nichts.. Aber ich glaub da war noch was, was ich auch umgestellt habe, mir fällts aber im moment echt nich ein, ist ja auch schon spät :) Ich guck heut abend wenn ich aufwache nochmal, evtl. find ich was.
(Oder war es doch nur DoubleBuffered:=true? Naja, wie gesagt, ich guck dann nochmal) mfg Spessi |
Re: Flackern auf einer Map verhindern...
Zeichne alles auf ein Bitmap im Speicher und kopiere das dann mit BitBlt auf den Canvas der Paintbox.
|
Re: Flackern auf einer Map verhindern...
1. das TBitmap.Create VOR die zwei ineinander verschachtelten FOR Schleifen packen, das Bitmap wird immer wieder neu kreiert für jedes Map Tiles und das alte nicht freigegeben.
2. Ein Bitmap.Free am Ende der Procedure wäre auch nicht schlecht. 3. Du solltest die Bitmaps für jedes Tile Art im Speicher vorrätig lassen, die BMPs immer und immer wieder von der Platte auszulesen ist absoluter Käse, die Festplatte ist nicht ansatzweise so schnell wie der RAM Speicher. 4. Eine Map besteht eigentlich immer aus 3 Ebenen (Layer). Einmal der Map Untergrund der sich so schnell nicht ändern (sprich fast schon einmal zeichnen und gut is), dann der Items Layer der sich durch deine / NPC Interaktion ändern kann und letztendlich der Char Layer. Um bisschen Optimierung reinzukriegen, erstell eine Bitmap wo einmal (wenns gebraucht wird) die Map Tiles drauf gezeichnet werden und gut ist. Dann kannst Du deine Items und Chars über diesen Untergrund laufen lassen.. Ach ja, ich weiß Du wirst mich hassen, aber in deinem Interesse empfehle ich Dir: Lern ein bisschen OOP.
Delphi-Quellcode:
Vielleicht kannst Du so ein Zeug momentan noch machen, nur irgendwann wirste damit so richtig Probleme kriegen. Sieh es als Erfahrungs- und Weiterbildungschance an.
for iii := 0 to 1000 do begin
if NPCs[iii].name <> '' then begin |
Re: Flackern auf einer Map verhindern...
iss mir ja klar, dass es einige kritik gibt -> immerhin hab ich ja nach verbesserungen gesucht :)
also... wie soll ich denn dann die karte aufbauen, wenn es denn nach OOP laufen soll? bis jetzt isses "map: array[0..5000,0.5000] of TFeld" (oder so ähnlich) gut... wegen dem BitBlt: Die Funktion hoffe ich steht in der Delphi-Hilfe :) Und wie zeichne ich dann auf ein Bitmap im SPeicher? einfach bitmap.create und dann per canvas genauso die bilder draufhaun wie bei der paintbox per canvas (hätt ich mir jetzt mal so vorgestellt :gruebel: ) und wie soll ich dann die ganzen bilder zwischenspeichern? :( |
Re: Flackern auf einer Map verhindern...
Zitat:
Anderes Beispiel: Charaktere... Chars haben in den meisten RPGs Attribute wie Stärke, Intelligenz, Lebenspunkte, Mana, was weiß ich.. Diese 4 Beispiele wären innem Record einfach nur Variablen vom Typ Byte z.B. Nu haste ne Code Passage - meinetwegen im Programmcode für den Kampf, ein Char trifft den anderen mit nem Schwert - in der es heißt
Delphi-Quellcode:
Nu musst Du direkt danach darauf eingehen was dem anderen Char passiert. Stirbt er ? Kommt er in einen kritischen Bereich mit der Lebensenergie bei dem seine Stärke vllt halbiert wird ? Wenns Du es mit Records angehst, musst du bei JEDER Zuweisung einer Variablen selbstständig checken was im Anschluß darauf passiert. Mag bei dieser einen Passage schnuppe sein, weil das is dann ein Aufruf von einer Procedure hintendran mehr. Aber glaub mir, es wird nicht bei dieser einen Passage bleiben (Ich bin z.Zt. der Programmierteil von einem Ultima Online Freeshard (MMORPG), ich weiß wie dreckig anstrengend so ein Teil werden kann).
if DerAndereCharWurdeGetroffen then
DerAndereCharRecord.Lebenspunkte := DerAndereCharRecord.Lebenspunkte - 10; Nimm statt dessen lieber Klassen und statt Variablen Properties. Jedesmal wenn der Variable was zugewiesen wird, kannst Du in dem speziellen Fall drauf reagieren und musst das ganze nur einmal programmieren, sprich Ereignisorientiert programmieren, den Rest erledigt Delphi für Dich. Nächstes Beispiel: Wie ich schon sagte, alles was Du an Bitmaps hast EINMAL einladen, dann immer aus diesen Bitmaps zeichnen. Bei ner Klasse kannst schon gleich im Konstruktor die Bitmap einladen, im Destruktur wird sie freigegeben. Zwischendurch kannst immer druff zugreifen und brauchst Dich sonst um nichts kümmern. Nächstes Beispiel: Waffen, Items, Monster, alles Mögliche.. Man programmiert für die eine Grundgattung (meinetwegen Waffen) eine Basisklasse, sei es nun TBaseWeapon. Davon leitest Du die anderen Klassen ab, z.b. TBastardschwert. Wenn Du nun in der basisklasse das Grundverhalten von Waffen programmierst, wirkt sich das auf alle Nachfahren dieser Klasse aus, Du brauchst in deinem TBastardschwert nur vllt die Eigenschaften wie Schaden, Schadenstyp usw. ändern. Das wars. Was aber nun, wenn Du mit deinen Records ein Schwert hättest, was ein komplett anderes Verhalten hat als z.b. so nen Standard Schwert. Lass es ein vergiftetes Schwert sein, oder eins was gelb leuchtet un den Gegner in Flammen steckt. Du musst beim Schadenscode überall abchecken, welches Schwert benutzt wird und darauf reagieren. Dadurch wird dieser Programmcode lang, kompliziert und unübersichtlich. Mit meiner Methode würdest einfach ein TFlammenschwert von TBaseWeapon ableiten und eine Methode überschreiben, die den Schaden zufügt. Nächstes Beispiel: Interfaces Ein Interface in einer Klasse zu implementieren bedeutet, man Klassen ansprechen, die nicht von einander abgeleitet sind, bzw. einen gleichen Vorfahren besitzen. Bei Ultima Online (RunUO Server) gibbets ein Interface namens IEntity. Das beherbergt die Felder X, Y, Z, MapPlane (gibt verschiedene Maps dort). Dieses IEntity ist in der Basisklasse für Items und für Chars drinne. Ich könnte somit also einfach über dieses Interface gleichermaßen Items und Chars ansprechen, ohne mit der Wimper zu zucken was ich da nun eigentlich verschiebe. Mit Records musst Du entweder erstmal überladene Proceduren machen, die entweder Items oder Chars als Parameter annehmen ODER aber Du musst eine allgemeine Procedure machen und dann in dieser Procedure nachchcecken was Du eigentlich verschiebst und dann darauf reagieren. Ich weiß Du siehst momentan nicht wirklich den Sinn dahinter, warum Du auf OOP umsteigen solltest und ich muss auch eingestehen, ich weiß noch nit wie fortgeschritten dein Spiel ist. Aber ich weiß GANZ GENAU, sobald das Ding an Komplexität zunimmt die über hin und her gehen und Chars anschnacken hinausgeht, wirst Du Dich vor lauter IF-Bedingungen nicht mehr retten können, solltest Du auf der Records-Schiene draufbleiben. Drum tu Dir selbst ein Gefallen, wechsel auf Klassen. Wenn erstmal das Spiel komplex ist, kannste das knicken, dann stampfst Du alles ein und fängst von vorne an weil Du kein Land mehr siehst. - Thebe |
Re: Flackern auf einer Map verhindern...
vielen dank!! hat mir sehr geholfen! :top:
nur... ich hab mit klassen sehr wenig erfahrung.. :( was meien map anbelangt sollte sie so bleiebn, wenn ich richtig gelesen hab... und das mit den if-gewurschtel ist schon passiert (noch blick ich noch durch! :D ) das mit den bitmaps würde ich mir dann so vorstellen, dass ich einen array mach und in den dann alle (bekannten) bilde reinlad, bzw. dann eben ausles. richtig so? yo... |
Re: Flackern auf einer Map verhindern...
in etwa
wenn Du mir noch sagst welche "Felder" in dem Record für deine Map und deine Chars drinne is kann ich Dir nen Beispiel schreiben wie man da sehr schön was draus mit ner Klasse machen kann.. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 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