Plynulý posun – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Plynulý posun – Delphi – Fórum – Programujte.comPlynulý posun – Delphi – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
mikeek
~ Anonymní uživatel
32 příspěvků
28. 4. 2010   #1
-
0
-

Zdravím, řešim jeden problem.
Chtěl jsem udělat jednu takovou blbost, prostě kulička (Shape) která by reagovala na zmáčknutí šipek, pohybovala by se, skákala by po takovych plošinkách (pole shapů). Udělal jsem to přes timer (interval 10, vždy zjišťoval GetKeyState(vk_left), vk_right a vk_up ...), vše jsem měl, běhalo to v pohodě, fungovalo jak mělo.
Ale logicky, taková "hra" je o ničem, tak jsem se rozhodl, že přidám na každou plošinku (je jich 11+podlaha) kromě podlahy jednu kuličku(pole shapů) která se bude pohybovat po te plošince od jedné hrany k druhé, při dotyku s mou bude konec hry. Když jsem měl hotov pohyb kuliček (přes další timer, interval 10, pouze posunoval kuličky) a chtěl jsem se pustit do kontroly kolize, otestoval jsem to a co nevidím, hra se při pohybu mou kuličkou dost zpomaluje.
Napadlo mne, že ten prvni timer to asi hodně vytěžuje, chtělo by to pořešit jinak. Chtěl jsem to tedy dát na OnKeyDown formuláře.
Narazil jsem ale na problem, kvuli kteremu jsem to již na začátku dal na timer.

Při zmáčknutí a držení klávesy se sice kulička pohybuje, ale ne ideálně. Vite jak třeba prijíždíte textem a držíte klávesu? Kurzor se posune o jednu pozici, pak má chvíli pauzu a až po té pauze se začne svižně pohybovat dál. Stejně se hýbe i má kulička. Jak se zbavím té pomlky?

Nahlásit jako SPAM
IP: 89.103.39.–
Reklama
Reklama
illioner0
Stálý člen
28. 4. 2010   #2
-
0
-

Nevim zbavovat se kvuli tomu pomlky mi přijde absurdní. Vem to takhle. Asi ti to zpomaluje testování kolizí při tvém
pohybu, nemáš to napsaný nějak neoptimálně tu rutinu pro kolize?
I když to 2 Timery zpomalovat nebudou stačí ti stejnak jeden. Z
jednoho OnEvent Timeru
můžeš řešit pohyb všech objektů. Si tam dej případně počítadlo - proměnnou kolik uběhlo času
(tak můžeš pohyb svý kuličky občas vynechat) a
podprocedury, kterýma vyřešíš pohyb všech objektů ve hře.
Taky proč než shape to nekreslíš do Canvasu? Až přejdeš na něj tak poznáš že je lepší na hry :)

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek
~ Anonymní uživatel
32 příspěvků
29. 4. 2010   #3
-
0
-

yop dam to teda do jednoho timeru, je to fakt, nevim proč sem to tak nedal rovnou.... no do canvasu jsem to nekreslil proto, že to pořadně neumim (jsem začátečník), tak pořádně nevim jak na to, ale projdu nějaky kurzy a přijdu canvasu na kloub ;). diky

Nahlásit jako SPAM
IP: 89.103.39.–
mikeek
~ Anonymní uživatel
32 příspěvků
29. 4. 2010   #4
-
0
-

tak sem to udělal teda tak, že jsem si na vše vytvořil misto shapu image a do nich jsem to přes canvas nakreslil (nevim jak bych přesně dělal ten pohyb, kdybych to canvasem kreslil přimo na form...). Pohybuje se to o něco plynulejc, ale furt to neni ono, ale to už bude problem v procedurach kontrolujicich, jestli je kulička na plošince (pokud neni, má padat dolu).
Dá se ta kontrola udělat nějak jinak? Mám tam poc-1 plošinek (plocinka poc je podlaha), nepritel jsou ty dalsi kulicky, ikdyz necham na timeru jenom tohle, furt se me zda ze to jede celkem pomalu, cca od intervalu 40 dolu se nezrychlují, to uz rychleji nedokaze? max je maximalni hodnota kam muze kazda kulicka jet (plosina[k].left+plosina[k].width) a min=plosina[k].left:

for k:=0 to (poc-1) do

begin
if nepritel[k].left=min[k] then pos[k]:=1
else if nepritel[k].left=max[k] then pos[k]:=-1;
nepritel[k].Left:=nepritel[k].Left+pos[k];
end;



Nejvic to asi zatežuje to, když kontroluju jestli ma kulička je na nějake plošince. Projiždim všechny plošinky, zjistim jestli plosinka[k].top=(kulicka.top+kulicka.height) a pak ještě jestli kulicka.left>plosinka[k].left and kulicka.left+kulicka.width<plosinka[k].left+plosinka[k].width a podle toho zjistim jestli je na nektere plošince, jestli neni, tak pada dolu. Nedalo by se nějak lip zjistit, jeslti je na nějake plošince?

Nahlásit jako SPAM
IP: 89.103.39.–
illioner0
Stálý člen
30. 4. 2010   #5
-
0
-

Tak třeba zpomaluje práce se standardníma objektama Delphi, používej jak já pole svých vlstních nadefinovaných objektů
nebo Recordů(ještě rychlejší), bude to rychlejší v přístupu, ale u tebe bych řekl spíš variantu že za to můžou Windows - oni taky nejsou s časovačem u malejch hodnot slavný. Můžeš to zkusit dít do procedury Application.OnIdle - ta se vykonává když nemá program do čeho píchnout. Normálně tomu přiřaď svou proceduru.
Na takovejch víc jak 100 plošinek můžeš použít algoritmus stromů, ale tolik jich snad nemáš..

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek
~ Anonymní uživatel
32 příspěvků
2. 5. 2010   #6
-
0
-

přes Application.OnIdle jsem to zkoušel, dal jsem na ni pohyb nepřatelskych kuliček, ale ten byl trhaný v závislosti na pohybu mé kuličky.... jak přesně máš na mysli definování vlastnich objektů?

Nahlásit jako SPAM
IP: 89.103.39.–
mikeek
~ Anonymní uživatel
32 příspěvků
5. 5. 2010   #7
-
0
-

mam dotaz. mam tenhle kod:

 TKula = class

Canvas:TCanvas;

FLeft:integer;
FHeight:integer;
FWidth:integer;
FTop:integer;

function RLeft:integer;
function RHeight:integer;
function RWidth:integer;
function RTop:integer;

procedure WLeft(i:integer);
procedure WHeight(i:integer);
procedure WWidth(i:integer);
procedure WTop(i:integer);

property Left:integer read RLeft write WLeft;
property Height:integer read RHeight write WHeight;
property Width:integer read RWidth write WWidth;
property Top:integer read RTop write WTop;

end;

var
Form1: TForm1;
Kula: Tkula;

implementation
{$R *.dfm}
function TKula.RLeft;
begin
RLeft:=FLeft;
end;

procedure TKula.WLeft(i:integer);
begin
FLeft:=i;
end;

function TKula.RTop;
begin
RTop:=FTop;
end;

procedure TKula.WTop(i:integer);
begin
FTop:=i;
end;

function TKula.RHeight;
begin
RHeight:=FHeight;
end;

procedure TKula.WHeight(i:integer);
begin
FHeight:=i;
end;

function TKula.RWidth;
begin
RWidth:=FWidth;
end;

procedure TKula.WWidth(i:integer);
begin
FWidth:=i;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
kula:=TKula.Create;
kula.Canvas:=Tcanvas.Create;


kula.Left:=3;
kula.Top:=3;
kula.Height:=3;
kula.Width:=3;
kula.Color:=clblack;
kula.Canvas.Brush.Color:=clblack;
kula.Canvas.Ellipse((0,0,kula.Width,kula.height);


a vypisuje to chybu "canvas does not allow drawing"

Co dělám špatně? Vlastnosti left, top, width a height - jsou potřeba ještě nějak specialně propojovat s aplikací (resp. s formulářem), aby se brali jako klasicke vlastnosti (odsazeni zleva, zvrchu, šířka, výška)?

Nahlásit jako SPAM
IP: 89.103.39.–
illioner0
Stálý člen
6. 5. 2010   #8
-
0
-

Jo nějak takhle jsem to myslel, učíš se rychle, s těma objektama, akorát ti tam chybí třeba Hitpointy, vykonávaná činnost, rychlost a další.

To by sis ale moc nepomohl dávat každé kuličce vlastní canvas(taky pomalý a nepraktický), stačí ti vykreslovat do jednoho Canvasu, nejlépe přes nějaké kompatibilní memory Device Context, Svému jednomu canvasu vně (jako globální proměnná) pak přiřadíš handle (jeho jeden z členů) z týhle funkce (CreateCompatibleDC) tak to dělám já. A vytvoříš si pro něj kompatibilní bitmapu do které se bude vykreslovat o daném rozlišení tvého okna. Nakonec budeš překreslovat každý frame v události OnPaint překopíruješ svůj 1 globální Canvas pomocí CopyRect.

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek
~ Anonymní uživatel
32 příspěvků
6. 5. 2010   #9
-
0
-

Yop ty property byly jenom orientačně, abych věděl zda něco nedělam špatně :).
Dále jsem to mírně nepochytil :).

Takže, vytvořím si jeden globalni canvas.

Vykres:TCanvas


a ve FormCreate

Vykres:=Tcanvas.Create;


A pomocí f-ce CreateCompatibleDC přiřadim handle?

CreateCompatibleDC(Vykres.handle);


Asi ne že? Jelikož u tohoto kroku mi to vždy spadne a vyhodi hlašku "Canvas does not allow drawing"

Nahlásit jako SPAM
IP: 89.103.39.–
illioner0
Stálý člen
6. 5. 2010   #10
-
0
-

nemyslíš si že se svou otevřenou hlavou - že to z tohohle popisu snad zvládneš že ne:
správně sis vytvořil 1 třídu canvasu(resp. inicializoval)
teď vezmi jeden nějakej pomocnej handle, a do něho přiřaď kompatibilní DC
který inicializuješ handlem toho svého globálního canvasu. Chce to jen tenhle jeden
argument.
Pak je důležité vytvořit Kompatibilní Bitmapu zas přes handle svýho canvasu s danym rozlišenim xy.
Pomocí selectobject navol na ten pomocnej handle co máš (pořád ten samej) odkaz na vytvořenou bitmapu
Do královského glob. canvasu jeho člena handle přiřaď opět pomocný handle.
Toť vše u startu. Překopírování v události OnPaint je hračka..
předem odmítám nařčení z masochismu :D

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek0
Duch
6. 5. 2010   #11
-
0
-

To illioner :
fííha, asi sem moc dutej :)...
správně sis vytvořil 1 třídu canvasu(resp. inicializoval) - to teda mam

teď vezmi jeden nějakej pomocnej handle, a do něho přiřaď kompatibilní DC který inicializuješ handlem toho svého globálního canvasu - to jsem pochopil takto (han je pomocný handle):

han:=CreateCompatibleDC(vykres.Handle);
Ovšem u tohoto to vždy skončí s chybou "Canvas does not allow drawing"

Pak teda jestli jsem to dobře pochopil dál:

Pak je důležité vytvořit Kompatibilní Bitmapu zas přes handle svýho canvasu s danym rozlišenim xy. - žeby tak?

Vykres.Brush.Bitmap:=TBitmap.Create;

Vykres.Brush.Bitmap.Width:=form1.Width;
Vykres.Brush.Bitmap.Height:=form1.Height;
Vykres.Brush.Bitmap.Handle:=CreateCompatibleDC(vykres.Handle);

Pomocí selectobject navol na ten pomocnej handle co máš (pořád ten samej) odkaz na vytvořenou bitmapu -

SelectObject(han,Vykres.Brush.Bitmap.Handle);


Do královského glob. canvasu jeho člena handle přiřaď opět pomocný handle. -
Vykres.Handle:=han;


Tak, co dělm špatně? Ještě se omlouvám jestli obtěžuju mou nechápavostí, ale jsem začátečník :)

Nahlásit jako SPAM
IP: 89.103.39.–
O život můžeme přijít různě. Smrt je jen jednou z možností.
illioner0
Stálý člen
6. 5. 2010   #12
-
0
-

tenhle radek tam mas ale navic
Vykres.Brush.Bitmap.Handle:=CreateCompatibleDC(vykres.Handle);

jinak zcela presne, ja s tim delam uz kolikatej program, nemuze ti to zlobit a padat, to uz spis hledejme chybu jinde.

Dej na zacatek sveho timerovaneho kresleni Canvas.Lock a na konec Unlock.

a nezapomen postovat .exe dema :D

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek0
Duch
7. 5. 2010   #13
-
0
-

no já to zkoušim zatim nanečisto do prazdne aplikace, než to vpustim do te hry, ale i tak, nevim v čem bych tam jinak měl chybu.

 TKula = class

FLeft:integer;
FHeight:integer;
FWidth:integer;
FTop:integer;

function RLeft:integer;
function RHeight:integer;
function RWidth:integer;
function RTop:integer;

procedure WLeft(i:integer);
procedure WHeight(i:integer);
procedure WWidth(i:integer);
procedure WTop(i:integer);

property Left:integer read RLeft write WLeft;
property Height:integer read RHeight write WHeight;
property Width:integer read RWidth write WWidth;
property Top:integer read RTop write WTop;

constructor Create;

end;

var
Form1: TForm1;
Kula: Tkula;
Vykres: TCanvas;
BMap:TBitmap;
han:HDC;

implementation
{$R *.dfm}
constructor TKula.Create;
begin
left:=3;
top:=3;
width:=100;
height:=100;
end;

function TKula.RLeft;
begin
RLeft:=FLeft;
end;

procedure TKula.WLeft(i:integer);
begin
FLeft:=i;
end;

function TKula.RTop;
begin
RTop:=FTop;
end;

procedure TKula.WTop(i:integer);
begin
FTop:=i;
end;

function TKula.RHeight;
begin
RHeight:=FHeight;
end;

procedure TKula.WHeight(i:integer);
begin
FHeight:=i;
end;

function TKula.RWidth;
begin
RWidth:=FWidth;
end;

procedure TKula.WWidth(i:integer);
begin
FWidth:=i;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
kula:=TKula.Create;
Vykres:=TCanvas.Create;
han:=CreateCompatibleDC(vykres.Handle);

Vykres.Brush.Bitmap:=TBitmap.Create;
Vykres.Brush.Bitmap.Width:=form1.Width;
Vykres.Brush.Bitmap.Height:=form1.Height;
SelectObject(han,Vykres.Brush.Bitmap.Handle);
Vykres.Handle:=han;
end;


Při tomto kodu to stále háže "canvas does not allow drawing".. zkoušel jsem před to dat vykres.lock i vykres.trylock, ale nic.

Nahlásit jako SPAM
IP: 89.103.39.–
O život můžeme přijít různě. Smrt je jen jednou z možností.
liborb
~ Redaktor
+18
Guru
7. 5. 2010   #14
-
0
-

A je vůbec ten Handle platný? Neměl by sis ho napřed sám získat?:



vykres:=TCanvas.Create;
vykres.Handle := GetDC(0);
han:=CreateCompatibleDC(vykres.Handle);


A ještě poznámku, nevím jak v Delphi, ale jinde je potřeba k CompatibleDC ještě tvořit CompatibleBitmap, takže něco takového:


Vykres.Brush.Bitmap.Handle:=CreateCompatibleBitmap(vykres.Handle, form1.Width, form1.Height);

Nahlásit jako SPAM
IP: 85.207.166.–
illioner0
Stálý člen
7. 5. 2010   #15
-
0
-

takhle je to spravne:

procedure TForm1.FormCreate(Sender: TObject);

begin
kula:=TKula.Create;
Vykres:=TCanvas.Create;
han:=CreateCompatibleDC(canvas.Handle);

Vykres.Brush.Bitmap:=TBitmap.Create;
Vykres.Brush.Bitmap.Width:=form1.Width;
Vykres.Brush.Bitmap.Height:=form1.Height;
SelectObject(han,Vykres.Brush.Bitmap.Handle);
Vykres.Handle:=han;
end;

Nahlásit jako SPAM
IP: 83.208.64.–
Nechápu softwarové firmy, ktere utrácejí za čim dál těžkopádnější DRM ochranu!! Vidět kolem snahu o free2play model je jako příjemné připomenutí časů shareware (jen ten Microsoft stále nic nepochopil)
mikeek0
Duch
10. 5. 2010   #16
-
0
-

po přidání

vykres.Handle := GetDC(0);

již chybu nevypisuje.

Ovšem když zkusim jenom třeba na tlačitko dat

vykres.Brush.color:=clblack;

vykres.Ellipse(0,0,30,30);


tak se nic neděje.

1) proč se nic neděje?

2) Sice je pěkny že sem si to za vaši pomoci dokazal takhle vytvořit, ale jak pak dál? :) To při každem pohybu budu překreslovat cely canvas a vykreslovat kuličky na novych pozicich? Nebude to pomaly?

Nahlásit jako SPAM
IP: 89.103.39.–
O život můžeme přijít různě. Smrt je jen jednou z možností.
liborb
~ Redaktor
+18
Guru
11. 5. 2010   #17
-
0
-

add 1) Ono se děje, ale děje se to v DC, který je v paměti. Při vykreslení (OnPaint) musíš přes funkci BitBlt překopírovat obsah paměťového DC do okénkového DC.

add 2) V podstatě ano. Při každém překreslení musíš překopírovat celou viditelnou výseč DC (BitBlt). Při každém pohybu to celé překreslovat nemusíš, stačí ti změnit oblast (region), kde se něco změní. Pro začátek ovšem můžeš kreslit všechno znovu a i tak to v tomto případě nebude pomalé.

Nahlásit jako SPAM
IP: 85.207.166.–
Mikeek
~ Anonymní uživatel
32 příspěvků
15. 6. 2010   #18
-
0
-

Velice se omlouvám za dlouhou pauzu, ale mě jsem problémy s internetem a taky hodně práce... jestli je ještě někdo ochotný, rád bych pokračoval v projektu :).

na FormCreate tedy mam

kula:=TKula.Create;

Vykres:=TCanvas.Create;
han:=CreateCompatibleDC(canvas.Handle);
Vykres.Brush.Bitmap:=TBitmap.Create;
Vykres.Brush.Bitmap.Width:=form1.Width;
Vykres.Brush.Bitmap.Height:=form1.Height;
SelectObject(han,Vykres.Brush.Bitmap.Handle);
Vykres.Handle:=han;
vykres.Handle := GetDC(0);


dále na OnPaint mam
bitblt(form1.Canvas.Handle,0,0,40,40,vykres.Handle,0,0,0);

(snad jsem to pochopil dobře)

a na stisku tlačítka
Vykres.Brush.Color:=clyellow;

vykres.Ellipse(0,0,40,40);



Spustim program a na formuláři se mi objeví černý čtverec o souřadnicích 0,0,40,40.
Stisknu tlačítko a v levém horním rožku se mi objeví černý čtverec opět 40x40 a v něm žlutá kružnice (r=20).

Mám par otázek.

1) na co je mi tu procedura OnPaint, když už mi to vykresluje i tak?
2) jak to donutim, aby mi to vykreslovalo tu kružnici v oblasti, kde je formulář (resp. jak zjistim souřadnice formuláře na displeji)?
3) když program zminimalizuju a zmaximalizuju, kružnice zmizi. Tohle ošetřím jak?

Předem moc diky za vaši trpělivost se mnou :)

Nahlásit jako SPAM
IP: 89.102.19.–
liborb
~ Redaktor
+18
Guru
15. 6. 2010   #19
-
0
-

Několik poznámek ... v té první části je určitě navíc řádek:



vykres.Handle := GetDC(0);

už sis Handle naplnil vytvořeným CompatibleDC.

Další věc ... předtím jsem tomu něvěnoval pozornost ... Canvas.Brush.Bitmap bude bitmapa pro štětec na vyplňování. Jak máš založenou proměnnou TCanvas, tak si založ i TBitmap a Canvas.Brush.Bitmap vynechej (nahraď).

POslední parametr při BitBlt je typ bltování :smile1: . 0 je určitě špatně resp. musíš použít konstantu SRCCOPY:


bitblt(form1.Canvas.Handle,0,0,40,40,vykres.Handle,0,0,SRCCOPY);



A k tvým otázkám:
add 1) v OnPaint se vykresluje, můžeš vykreslit i na základě jiné události, ale pak ti to např. při min/max (add 3) může zmizet (i když tady ti to mizelo z jiných důvodů)

add 2) GetClientRect, GetWindowRect ...

add 3) když uděláš ty úpravy, jak jsem napsal výše, tak nebude co ošetřovat. Kružnici nakreslíš do paměti a v OnPaint se ti zase vykreslí. Možná bude potřeba na konec stisku tlačítka přidat Repaint.

Nahlásit jako SPAM
IP: 85.207.166.–
Mikeek
~ Anonymní uživatel
32 příspěvků
15. 6. 2010   #20
-
0
-

ok, pak zkusim, ale bez řádku

vykres.Handle := GetDC(0);

mi to při spouštění vyhazuje chybu o které jsem se zmiňoval již výše.

Za ten parametr v BitBlt se omlouvám, neměl jsem tušení co to je :).

A ještě, jak přesně mysliš nahrazení té bitmapy tou vytvořenou?

Nahlásit jako SPAM
IP: 89.102.19.–
Mikeek
~ Anonymní uživatel
32 příspěvků
15. 6. 2010   #21
-
0
-

A ještě mě napadlo (doufám že už jsem se na to neptal), co kdybych to vše vykresloval přímo do canvasu toho formuláře a v něm to překresloval? Ale je to jenom takovej nápad, chápu, pokud je to nějaky špatny. Upřimně bych raději pokračoval v tomhle, abych se toho co nejvice přiučil, pokud se mnou budete mit trpělivost :)

Nahlásit jako SPAM
IP: 89.102.19.–
liborb
~ Redaktor
+18
Guru
16. 6. 2010   #22
-
0
-

Všechno souvisí se vším :smile1: .

Když to uděláš přímo, tak se nevyhneš jedné nepříjemné věci, a to takové, že ti to bude problikávat. Proto se to řeší přes double buffering (to je to, o co se tu snažíš), kdy si všechno nakreslíš do paměti a na obrazovku to jde v jedné várce a bez blikání.

BitBlt je mocná funkce. Ona toho umí spoustu a ten poslední parametr je vlastně ten nejdůležitější. Doporučuji ti udělat si s ní potom pár pokusů, abys viděl, co všechno dokáže. Až budeš řešit nějaké maskování, tak na to třeba bude stačit změnit poslední parametr.

A teď ke kódu. Vůbec bych se nebál udělat to "klasicky". Vykreslovací tentononc se jmenuje Device Context (DC). V Delphi je schovaný v Canvasu, ale pořád tam je :smile1: . Když chceš dělat double buffering, tak si potřebuješ vytvořit takový DC v paměti. To se dělá přes funkci CreateCompatibleDC (kompatibilní DC s DC obrazovky, tiskárny nebo jiného zařízení). Aby se dalo do DC vykreslovat, tak musí mít přidělenou oblast/paměť, do které se kreslí. Taková oblast je bitmapa, která se DC musí přidělit (SelectObject). Nejlepší je vytvořit opět kompatibilní bitmapu s DC přes CreateCompatibleBitmap. Následně jen přidělíš a kreslíš. Takže bych ten tvůj kód vytvořil následovně:

- definuju si 2 proměnné

Vykres : TCanvas;

Bitmapa : HBITMAP;


- vytvořím si v OnCreate kompatibilní DC, bitmapu, "spojím je" a všechno to přidělím Canvasu (hdc : HDC):
Vykres := TCanvas.Create;

hdc := CreateCompatibleDC(Form1.Canvas.Handle);
bitmapa := CreateCompatibleBitmap(Form1.Canvas.Handle, form1.Width, form1.Height);

SelectObject(hdc, bitmapa);

Vykres.Handle := hdc;


- v OnPaint nechám BitBlt:
bitblt(form1.Canvas.Handle,0,0,40,40,vykres.Handle,0,0, SRCCOPY);


- v reakci na stisk tlačítka nechám vykreslení kružnice do paměti, ale pro jistotu přidám Repaint:
Vykres.Brush.Color:=clyellow;


vykres.Ellipse(0,0,40,40);

Repaint();



Co bude ještě nutné změnit? Vytvořená bitmapa je prázdná (černá), takže pokud nechceš černé pozadí, tak budeš muset přes vyplnit jinou barvu (FillRect aktuálním Brush). A ještě bych velikost vytvořené bitmapy neodovzoval od aktuální velikosti formuláře, ale třeba od velikosti pracovní plochy, protože ta bitmapa je tak velká, jak ji vytvoříš a za hranici nenakreslíš ani pixel :smile1: .

Nahlásit jako SPAM
IP: 85.207.166.–
Mikeek
~ Anonymní uživatel
32 příspěvků
16. 6. 2010   #23
-
0
-

liborb, hafo diky, z tvého přispěvku jsem konečně dobře pochopil co vlastně dělám, moc diky :). Teď už mi to funguje. Respektive jsem zatim jenom u tohohle. Velikost te bitmapy je už drobnost.
Takže později až budu chtěl rozhybat kuličku tak vždycky budu muset překreslit jeji puvodni pozici kuličkou barvy jako pozadi a nakreslit ji o ten kousiček vedle? stejně tak i s nepřátelskými kuličkami?
Předpokládám že s plošinkami nebudde nejmenši problem, jen nakresleni do tohoto canvasu...

Nahlásit jako SPAM
IP: 89.102.19.–
liborb
~ Redaktor
+18
Guru
16. 6. 2010   #24
-
0
-

Přesně tak, když chceš nakreslit kuličku (i nepřátelskou) na nové pozici, tak ji na staré musíš smazat a nakreslit na nové. A ano, všechno musíš (stejně jako kuličky) kreslit do toho tebou vytvořeného DC, tj. do Canvasu.

Je hodně způsobů, jak se na to můžeš dívat. Třeba, že všechno co se nehýbá je pozadí. Případně si na to vytvořit bitmapu .... Možností je spousty. Kdybych ti směl poradit, tak v první kroku to dělej nejjedodušeji a všechno znovu, nebo-li:
- smazat komplet celý Canvas (DC)
- vykreslit kuličky
- vykreslit plošinky
- vykreslit ....

zavolat Repaint, aby se provedlo OnPaint.

Sazmořejmě to bude pomalé (ale ne zase tolik) a je to možné optimalizovat až do omrzení (překreslovat pouze regiony atd.). Ovšem pro začátek je to to nejlepší - když všechno vidíš a máš to pod kontrolou.

Nahlásit jako SPAM
IP: 85.207.166.–
Mikeek
~ Anonymní uživatel
32 příspěvků
16. 6. 2010   #25
-
0
-

Ok, diky moc, od vikendu na tom začnu pracovat vic, kdyžtak se ozvu ;)

Nahlásit jako SPAM
IP: 89.102.19.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 9 hostů

Podobná vlákna

Plynuly prechod farieb — založil Tomáš Fedor

Posun znaku — založil pista

Posun jmen — založil David

Posun Jmen — založil Radek

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý