Autor Beitrag
mau0r
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 01.04.03 17:23 
hi,

nachdem ich inzwischen ein spielbrett zustande gebracht habe (hab hier deswegen ja schon mal geposted), haben sich einige probleme ergeben.
unsere lösung sieht momentan so aus, dass wir ein tdrawgrid haben, auf das tbitmaps geCanvas't werden.

zur erinnerung: das ganze projekt ist das spiel othello/reversi, meine teilaufgabe besteht aus dem client. ich soll also eine anwendung schreiben, die das spielbrett zur verfügung stellt, darstellt, und mit dem user agiert...
das spielbrett besteht aus 64 feldern, es gibt schwarze und weiße steine.


hier etwas code dazu:
ausblenden volle Höhe 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:
unit canvas_tdrawgrid_bitmap;

interface

uses (...), Grids;

type 
TForm1 = class (TForm)
Button1: TButton;
spielfeld: TDrawGrid;
Label1: TLabel;

procedure Button1.Click (Sender: TObject);
procedure spielfeldMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
procedure set_button (x,y:Integer; btype: string);
procedure paint_all(Sender: TObject);
(...)
type belegung = (empty,black,white);

var
 Form1:TForm1;
 Button:TBitmap;
 board: Array [0..63] of belegung;
 buttons: Array [belegung] of String ='button_blank','button_black','button_white');

implementation

{$R *.DFM}

procedure TForm1.set_button(x,y:integer; btype:string);
begin
    Button:=TBitmap.Create();
    Button.LoadFromFile(concat ('q:\pfad\zum\bild\',btype,'.bmp');
    spielfeld.Canvas.Draw.(x*51+1,y*51+1,Button);
end;

procedure TForm1.paint_all(Sender: TObject);
var i:integer;
begin
    for i:=0 to 63 do
        set_button(i mod 8, i div 8, buttons[board[i]]);
end;

procedure TForm1.spielfeldMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
var a,b: integer;
begin
    a:=X div 50;
    b:= Y div 50;
    board[8*a+b]:=black; {hier mal debugging-mäßig schwarze buttons malen }
    set_button(a,b,'button_black');
end;
end.


soweit :)

meine frage ist nun: ich habe gelesen, dass man, um das "ich lege ein fenster über meine form und alle canvas dinger sind weg"-syndrom ausmerzen will, das onpaint event der form verwenden muss.
dazu habe ich mir hier die paint_all procedure geschrieben, die ausfeführt wird beim onpaint-event. das ganze ding an sich hat aber einige probleme. ich kann debugging mäßig super die button-bitmaps reinladen, nur werden immer nur wenige angezeigt, d.h. sie bleiben nicht wirklich stehen. wenn ich ein anderes fenster drüber lege und wieder wegnehme flashen kurz alle buttons auf (d.h. die paint_all-sub funzt im prinzip schon...)...ich vermute mal das problem liegt in der set_button-sub...ich bin nicht sicher ob es sinnvoll ist immer ein neues objekt zu erzeugen oder ob es komplikationen gibt mit der 'button'-variable, die es nur einmal gibt...

hat jemand ne ahnung, wie ich das hier hinkriegen könnte, so dass alle buttons zunächst einmal stehenbleiben ? ich denke, damit wäre dann auch das onpaint-problem gelöst....

danke schon mal

mfg
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Di 01.04.03 17:27 
Hallo,

das was du suchst heißt ondrawcell such hier im forum mal danach.
in diesem Ereignis mußt du deine Zelle zeichnen.
Mfg Frank

edit: es gibt auch zweidiemsionale Array
ausblenden Quelltext
1:
Var Spielfeld : array[1..8,1..8] of irgendwas;					

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 01.04.03 17:39 
Titel: re:
danke für die schnelle antwort,

ich werds mir mal anschauen, codebeispiele sind trotzdem gerne erwünscht ;)

was das array angeht: jo gibts schon, das hier ist aber leichter durchzurattern in ner schleife, ausserdem lässt sich das ja superleicht konvertieren mit ein bisschen mathe :)

btw. das drawgrid-dingt ist 408 px hoch und breit, cols und rows 50 px,
bitmaps sind 48x48px groß, falls das von interesse sein sollte...
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 01.04.03 17:44 
Titel: re:
btw. meintest du damit, dass mein onclick event grundsätzlich nicht geeignet sei, um bilder dahin zu setzen wohin ich klicke ?

es funktioniert ja im prinzip, nur ist die darstellung der buttons etwas komisch, da sie wieder verschwinden und nicht alle angezeigt werden...

wie war das mit dem onpaint-event- ist das nicht das, was ich brauche ?

mfg
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Di 01.04.03 17:48 
Titel: Re: re:
mau0r hat folgendes geschrieben:
danke für die schnelle antwort,

ich werds mir mal anschauen, codebeispiele sind trotzdem gerne erwünscht ;)

findest du mit sicherheit mit der suche. lies dir die Probleme der anderen mit durch und lern nochwas dabei. 3,4 Codebesipiele sind mit sicherheit zu finden. und in der OH ist bestimmt auch ein drin.

Zitat:

was das array angeht: jo gibts schon, das hier ist aber leichter durchzurattern in ner schleife, ausserdem lässt sich das ja superleicht konvertieren mit ein bisschen mathe :)

wenn du meinst.... :roll:
das mag ja sein, aber durchsehen tut dann keine mehr. das mit der Schleife ist eine fadenscheinige begründung.
ausblenden Quelltext
1:
2:
3:
4:
5:
for x:=1 to 8 do
  for y:=1 to 8 do
   begin
      machwas mit Spielfeld[x,y];
   end;

und wenn du das Ondrawcellereignis richtig nutzt wo mit acol,arow die "Koordinaten" der Zelle schon übergeben werden kommst du mit deinem eindimensionalen Array schnell ins trudeln und fängst dann dort an umständlich wild hin und her zu rechnen, welches Feld acol und arow in deinem array ist.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)


Zuletzt bearbeitet von Keldorn am Di 01.04.03 17:54, insgesamt 1-mal bearbeitet
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Di 01.04.03 17:54 
Zitat:

btw. meintest du damit, dass mein onclick event grundsätzlich nicht geeignet sei, um bilder dahin zu setzen wohin ich klicke

ja, ungeignet.

Zitat:

procedure TForm1.set_button(x,y:integer; btype:string);
begin
Button:=TBitmap.Create();
Button.LoadFromFile(concat ('q:\pfad\zum\bild\',btype,'.bmp');
spielfeld.Canvas.Draw.(x*51+1,y*51+1,Button);
end;

da fehlt auch noch ein bitmap.free oder hast du unbegrenzten Arbeitsspeicher?. Ein try-finally-Block wär auch nicht schlecht.

Such im Forum, ähnliche threads mit Bildern in ein Drawgrid gab es bereits.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 01.04.03 17:58 
Titel: re:
aaah, ich beginne zu verstehen ;)

also ist das ondrawcell-ding direkt in der lage, mir das geklickte feld zu übergeben ? nicht schlecht....

naja, dat mit meiner spezielberechnnung "klappt" zwar, aber wenn das andere besser ist, nehm ich das halt :)

ok, das mit dem free werde ich beherzigen, aber wo könnte denn der grund dafür liegen, dass die bitmaps die gecanvas't werden, nie alle stehenbleiben ? ist das mit ner globalen variable vom typ TBitmap wie ich das da gemacht hab prinzipiell in ordnung oder warum sonst tritt das prob auf...

danke

mfg
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Di 01.04.03 20:17 
Titel: Re: re:
Keldorn hat folgendes geschrieben:
und die Verwendung von globalen Variablen ist auch nicht grad der beste Programmierstil.

Da muß ich aber wiedersprechen...
Natürlich sollte man sie vermeiden sogut es geht, aber in gewissen fällen muß (!) einfach eine Globale Variable her...

z.B. wenn er das Bitmap am anfang lädt und dann immer wieder benutzt, das geht nur per Globaler Variable.. ;)

Au'revoir,
Aya~

PS: Zu dem problem hier generell kann ich leider net sonderlich helfen, hab das TDrawGrid nochnie benutzt :oops:

------------
EDIT: Wargh... sorry... :cry:
Ich hab wohl ausversehen statt Zitat auf Edit gedrückt und es nich gemerkt (siehe unten)... tausendmal sorry, kommt niewieder vor :roll:

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 01.04.03 21:32 
Titel: re
n'abend,

bist du sicher, dass du da mich zitierst hast ?!

kann mich garnicht erinnern das geschrieben zu haben ;)

hm ich bin ja nicht gegen globals, nur war meine frage, obs da evtl. komplikationen gibt von wegen überschreibung der selben variable => wodurch dann nur noch kA 1 bild zur zeit angezeigt wird o.ä.

ausserdem erstelle ich ja, wie am code ersichtlich, bei jedem on paint event bzw. aufruf von paint_all neue objekte, und das obwohl die anderen ja nur "unsichtbar" geworden sind und nicht "weg" sind....wär toll wenn zu diesem problem sich noch jmd. äußern könnte :)

mfg
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 01.04.03 21:37 
AAAAHHHH *schreit*
Sorry Sorry Soooorrryy~~~ *macht isch ganz klein und verkrümelt sich in eine ecke*

Ich äh.. hab da wohl den Button "Zitat" mit "Edit" verwechselt.. (Passiert mir laufend, aber in der regel merk ich das *G*) wääh..

@Keldor: 1000x Sorry~~ war keine absicht... *läuft total rot an und rennt weg*

wäh :oops:

_________________
Aya
I aim for my endless dreams and I know they will come true!
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Di 01.04.03 21:58 
Zitat:

kann mich garnicht erinnern das geschrieben zu haben

ich auch nicht :mrgreen:

ahh, doch nicht Alzheimer in jungen Jahren

Frank, der gerade seine Kontonummer zwecks Überweisung an AYA mailt :wink: :wink:
Aya hat folgendes geschrieben:

*läuft total rot an und rennt weg*

ich find dich trotzdem :mrgreen:

nee, spaß beiseite

Zitat:

also ist das ondrawcell-ding direkt in der lage, mir das geklickte feld zu übergeben ? nicht schlecht....

nicht das Feld sondern die Zelle. aber es hindert dich niemand daran, dein Spielfeld so aufzubauen wie das Grid. In diesem Fall wäre
ausblenden Quelltext
1:
Spielfeld : array[0..7,0..7] of irgendetwas					
besser

Zitat:

ok, das mit dem free werde ich beherzigen, aber wo könnte denn der grund dafür liegen, dass die bitmaps die gecanvas't werden, nie alle stehenbleiben ? ist das mit ner globalen variable vom typ TBitmap wie ich das da gemacht hab prinzipiell in ordnung oder warum sonst tritt das prob auf...

Ich würd dein Problem hier vermuten: das orginale Ondrawcell gibts ja immer noch. Wenn du ins Grid klickst, müssen 2 Zellen neugezeichnet werden, die zelle die den Fokus verliert und die Zelle, die den Fokus erhält. Zeichnen würdest du mit deinem Code immer dur die Zelle, die den Fokus erhält.

Außerdem lädst du bei jedem Zeichnen das Bitmap von der Festplatte. Besser wäre, 3 Bitmaps diese im Formcreate zu erzeugen und einzuladen und im Formclose freizugeben. Oder eine Imagelist verwenden.

Ansonsten: nimm das Ondrawcellereignis, probier es aus und meld dich wieder.

so oder so ähnlich sah mein Post aus.

Aya hat folgendes geschrieben:

Da muß ich aber wiedersprechen...
Natürlich sollte man sie vermeiden sogut es geht, aber in gewissen fällen muß (!) einfach eine Globale Variable her...

z.B. wenn er das Bitmap am anfang lädt und dann immer wieder benutzt, das geht nur per Globaler Variable.. icon_wink.gif

Ansichtssache. du kannst sie auch im private oder published Teil der Form unterbringen. da dann die Zugehörigkeit besser dargestellt ist. Find ich zumindestens.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 21.04.03 00:10 
moin moin,

morgen sind die ferien entgültig um, und ich wollte mal wieder einen gedanken an das ding verschwenden, ihr wisst ja noch worums geht...

ich hab kurz vor beginn der ferien euren rat beherzigt, und die sache mit dem ondrawcell eingebaut, und siehe da, *einige* probleme wurden gelöst
(also es konnten dann auch mehrere spielsteine gesetzt werden).

Es haben sich allerdings andere probs eingestellt, das eine prob, (was auch zu erwarten war, dass es kommt, ich aber nicht weiss, wie ich es lösen kann) war die geschichte mit nem speicher-overload, die anwendung stürzt nach kurzer zeit mit üblen fehlern ab...das mit dem bitmap.free hat anscheinend nicht geklappt. ich vermute mal dass der kleine speicher von dem armen schulrechner das nicht mitgemacht hat, dass er soviele bitmaps erstellen musste... :(

die andere sache, war die anomalie mit dem onpaint-event:
wer den oben stehenden code gelesen hat, weiss das das prog bei jedem überlagern durch andere fenster o.ä. die funktion paint_all aufruft, die wiederum die ganzen bitmaps neu erstellt....also ist es im endeffekt das gleiche problem wie das erste, nur wie erwähnt klappt das angeratene bitmap.free nicht....was ist am sinnvollsten zu tun ?

mfg
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 21.04.03 00:15 
hm, hab grad gesehn, dass diese frage von grundprinzip her beantwortet wurde, nur hat meine umsetzung der idee nicht geklappt:

es wurde vorgeschlagen, die bilder beim formcreate ein einziges mal zu initialisieren, um dann im späteren verlauf wiederum darauf zurückzugreifen, hat leider aus unerfindlichen gründen nicht geklappt....

könnte mir jemand ein funktionierendes beispiel zeigen, wie ich die bilder ein einziges mal initialisiere und dann später immer wieder verwende ?

danke :)
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Mo 21.04.03 15:49 
mau0r hat folgendes geschrieben:

könnte mir jemand ein funktionierendes beispiel zeigen, wie ich die bilder ein einziges mal initialisiere und dann später immer wieder verwende ?

nein, warum? Du hast doch schon fast alles, brauchst deinen Code nur ein wenig umzubauen. und wenns für die Schule ist, erst recht nicht :wink:

mau0r hat folgendes geschrieben:

Es haben sich allerdings andere probs eingestellt, das eine prob, (was auch zu erwarten war, dass es kommt, ich aber nicht weiss, wie ich es lösen kann) war die geschichte mit nem speicher-overload, die anwendung stürzt nach kurzer zeit mit üblen fehlern ab...das mit dem bitmap.free hat anscheinend nicht geklappt. ich vermute mal dass der kleine speicher von dem armen schulrechner das nicht mitgemacht hat, dass er soviele bitmaps erstellen musste... :(

es wären doch nur 3 bilder, die es zu laden gibt. Speicherprobleme bekommst du keine. In deinem ersten Post hast du das free vergessen gehabt, das war ein speicherproblem.

wo hast du denn das free hingesetzt?

poste nochmal deinen code, und wir können mal guggn, wo der fehler liegt.

mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 22.04.03 16:31 
moin moin,

das problem mit dem bitmap hab ich gelöst, jetzt gibts keine speicherprobs mehr :)

eine andere frage hab ich nun:

wenn ich das programm starte, und mal im einzelschritt durchlaufe, passiert folgendes: zunächst wird paint_all aufgerufen (is im onpaint event drin, und tut auch nicht weh, weil da ja nur legitime buttons gepainted werden, d.h. da wird erstma nur alles auf button_blank gesetzt)

ABER es wird auch das spielfeldonDrawCell event ausgelöst, als wäre es in ner schleife drin, und da ich da atm debug mäßig black buttons setzen lasse, ist nun das ganze feld voller schwarzer buttons.
das hat mich insofern verwundert, als das ich dachte, dass das ondrawcellevent nur ausgelöst wird, wenn der USER auf den drawgrid klickt....so aber wird es von selbst ausgelöst.....woran liegt das ? hab ich diese funktion falsch verstanden ? denn so wie das atm ist, kann ich diese fkt nicht zum setzen der steinchen verwenden, da sonst beim startup schon welche gesetzt werden....

hoffe ihr könnt mir darüber was erzählen,
mfg

ps.
bin euch zuliebe auf ein 2-dimensionales array umgestiegen ;)
mau0r Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 22.04.03 19:44 
wargh, kann doch net sein dass mir keiner was zum tdrawgrid erzählen kann ?!

wird's nun nur bei user-mausklick aktiviert oder was sonst bringt das proggie dazu, die funktion bei allen cells auszuführen ?!

mfg
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Mi 23.04.03 08:22 
mau0r hat folgendes geschrieben:
wargh, kann doch net sein dass mir keiner was zum tdrawgrid erzählen kann ?!

wird's nun nur bei user-mausklick aktiviert oder was sonst bringt das proggie dazu, die funktion bei allen cells auszuführen ?!

...
als das ich dachte, dass das ondrawcellevent nur ausgelöst wird, wenn der USER auf den drawgrid klickt....so aber wird es von selbst ausgelöst.....woran liegt das ? hab ich diese funktion falsch verstanden ?

Ich hatte dich gebeten, mal im Forum zu nach OndrawCell zu suchen. Dort hättest du deine Antworten schon längst gefunden. Auch mal in der Onlinehilfe und die Ereignisse durchzulesen, kann hilfreich sein.

Mach dich erst mal dort schlau und wenn du dann immer noch Fragen hast, kannst du dich wieder melden.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)