Autor Beitrag
Popov
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 07.04.03 15:45 
Ich sehe keinen - aber vielleicht sieht einer von euch es. Anbei ein wenig Code. Mein eigentliches Programm hab ich bis auf diese Zeilen reduziert und leicht modifiziert. Es werden also keine Grafiken geladen, sondern erstellt. Das hat aber auf den Fehler keinen Einfluß.

Wenn man das Programm startet und gleich danach die Leertaste drückt (und gedrückt läßt) kommt früher oder später eine Fehlermeldung. Das Programm bricht mit einer EAccessViolation Fehlermeldung ab.

Wie gesagt muß man dazu das Programm starten und die Leertaste gedrückt lassen. Bei mir bricht es in der vierten Zeile mit der Fehlermeldung ab. Es kann aber auch später sein, vor allem dann, wenn man die Taste auch später erst gedrückt hat.

Die einzige Komponente die man für dieses Beispiel braucht ist der Timer:


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:
implementation

{$R *.DFM}

const
  MatrixMaxX = 40;
  MatrixMaxY = 20;

var
  Matrix: array[0..MatrixMaxX, 0..MatrixMaxY] of Byte;
  Bmp: TBitmap;
  BmpA: TBitmap;
  ax, ay: Integer;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Interval := 20;
  
  Bmp := TBitmap.Create;
  Bmp.Width := MatrixMaxX * 16;
  Bmp.Height := MatrixMaxY * 16;

  BmpA := TBitmap.Create;
  BmpA.Canvas.Brush.Color := clBlack;
  BmpA.Width := 16;
  BmpA.Height := 16;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Bmp.Free;
  BmpA.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if ay > MatrixMaxX then Exit;
  if ax > MatrixMaxX then begin
    ax := -1;
    ay := ay + 1;
  end;
  ax := ax + 1;

  Bmp.Canvas.Draw(ax * 16, ay * 16, BmpA);
  Canvas.Draw(0, 0, Bmp);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0;
end;

_________________
Popov
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 07.04.03 16:11 
Also soweit ich das sehe initialisierst du die beiden Variablen ax und ay nicht..!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Mo 07.04.03 16:26 
mal ne frage: wo wird in ax und ay geschrieben ? und was soll da drinen stehen ?

_________________
MFG
Michael Springwald, "kann kein englisch...."
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 07.04.03 17:15 
Hi,

es kann nur an dieser Zeile hier liegen:
ausblenden Quelltext
1:
 if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0;					


und da es in dieser Zeile nur an der Matrix hinten liegen kann, würde ich mal tippen das es an dem ay+1 liegt... schreib da mal nur ay hin ;)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Mo 07.04.03 17:24 
jetzt weiß ich woran es liegt: du schreibst im timer -1 hin nun musst du im onkey ereignis eine abfage machen ob -1 ist.... oder nicht....
und du musst im onkey ereinigs schauen ob ay+1 größer als die höhe ist....

_________________
MFG
Michael Springwald, "kann kein englisch...."
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 07.04.03 17:28 
mimi hat folgendes geschrieben:
jetzt weiß ich woran es liegt: du schreibst im timer -1 hin nun musst du im onkey ereignis eine abfage machen ob -1 ist.... oder nicht....
und du musst im onkey ereinigs schauen ob ay+1 größer als die höhe ist....

Nein, denn direkt nachdem er ax:=-1 macht, erhöht er eswieder um 1, so das es dann 0 ist ;)

Au'revoir,
Aya

_________________
Aya
I aim for my endless dreams and I know they will come true!
Popov Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 07.04.03 17:35 
@Mozi: ax und ay sind globale Variablen. Siehe also da.

@Mimi: Wo wird in ax und ay geschrieben? Siehe Timerprozedur.

Bitte fragt nicht nach Sinn des Codes. Es ist alles entfernt worden was nicht für die Fehlersuche notwendig ist.

@Aya: Es hat mit +1 nichts zu tun. Auch ohne +1 kommt der Fehler. Allerdings siehts du es richtig. Ohne diese Zeile gibt es keine Fehlermeldung.

@Mimi: Die ganzen Rechnungen haben schon ihren Sinn. Auch so:

ausblenden Quelltext
1:
if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay] := 0;					


gibt es eine Fehlermeldung.

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

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 07.04.03 17:38 
Hi,

dann mach mal aus dem > ein >= in dieser Zeile:
ausblenden Quelltext
1:
2:
  if ay > MatrixMaxX then Exit; 
  if ax > MatrixMaxX then begin


und vorallem mach da mal ein:
MatrixMaxY hin (oder is das absicht?)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Mo 07.04.03 17:41 
also ich würde mal an deiner stelle bei on KeyPress ausgeben was in ax und ay steht ich wette da steht irgenwas drin.... was da nicht reinsoll

_________________
MFG
Michael Springwald, "kann kein englisch...."
Popov Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 07.04.03 18:20 
Ich hab den Fehler.

Den hab ich eigentlich schon nach mimi's -1 Hinweis, hab aber par Minuten gebraucht bis ich es gemerkt habe.

Es ist doch so: Delphi ist eine Multidingsbums Sprache. Das heißt, daß Prozeduren Ereignisorientiert aufgerufen werden. Hier haben wir zwei Prozeduren: einen Timer, der alle X Millisekunden aufgerufen wird. Dann haben wir OnKeyPress, das beim Tastenduck aufgerufen wird. Die Frage ist jetzt ob die Prozeduren warten bis die andere fertig ist, oder die andere Prozedur unterbrechen (bzw. parallel aufgerufen werden). In den zweiten Fall kann es vorkommen, daß ax noch -1, während OnKeyPress aufgerufen wird. In diesem Fall wird ax mit einem -1 angesprochen.

Ich hab den Code jetzt so abgeändert und es funktioniert:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if (ax < 0) or (ax > MatrixMaxX) then Exit;
  if (ay < 0) or (ay > MatrixMaxY) then Exit;

  if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay] := 0;
end;


Also danke für das Brainstorming.

_________________
Popov


Zuletzt bearbeitet von Popov am Mo 07.04.03 18:33, insgesamt 1-mal bearbeitet
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 07.04.03 18:32 
Popov hat folgendes geschrieben:
Es ist doch so: Delphi ist eine Multidingsbums Sprache. Das heißt, daß Prozeduren Ereignisorientiert aufgerufen werden. Hier haben wir zwei Prozeduren: einen Timer, der alle X Millisekunden aufgerufen wird. Dann haben wir OnKeyPress, das beim Tastenduck aufgerufen wird. Die Frage ist jetzt ob die Prozeduren warten bis die andere fertig ist, oder die andere Prozedur unterbrechen. In den zweiten Fall kann es vorkommen, daß ax noch -1, während OnKeyPress aufgerufen wird. In diesem Fall wird ax mit einem -1 angesprochen.

Das dürfte aber eigentlich nicht das Problem sein, da die Windows-Messages nacheinander abgerabeitet werden und dein Prog verwendet schließlich keine Threads und ruft auch nirgendwo Application.ProcessMessages auf oder?
Dass ax und ay globale Variablen sind hab ich schon gesehen, aber initialisiert werden sie in dem obigen Code trotzdem nicht.
Aber nachdem jetzt alles funzt hat sich das ja eh erledigt...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Mo 07.04.03 18:39 
doch!
er hat ein Timer der wird immer wieder aufgerufen und wenn er jetzt eine taste drück kann in ax -1 stehen...

_________________
MFG
Michael Springwald, "kann kein englisch...."
Popov Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 07.04.03 18:48 
Motzi hat folgendes geschrieben:
Dass ax und ay globale Variablen sind hab ich schon gesehen, aber initialisiert werden sie in dem obigen Code trotzdem nicht.


Jetzt sag mal genau was du mit initialisieren meinst. Oder meinst du hier das zuweisen der ersten Werte? Nunja, wäre ax und ay <> 0, dann hätte ich das auf der Grafik gesehen. ax und ay waren also 0 beim Start.

Zu der Sache mit dem Abarbeiten der Prozeduren. Eigentlich bin ich deiner Meinung, aber warum tritt das Problem jetzt nicht auf?

_________________
Popov
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 07.04.03 19:43 
Popov hat folgendes geschrieben:
Jetzt sag mal genau was du mit initialisieren meinst. Oder meinst du hier das zuweisen der ersten Werte? Nunja, wäre ax und ay <> 0, dann hätte ich das auf der Grafik gesehen. ax und ay waren also 0 beim Start.

Zu der Sache mit dem Abarbeiten der Prozeduren. Eigentlich bin ich deiner Meinung, aber warum tritt das Problem jetzt nicht auf?

Mit initlialisieren meine ich das Zuweisen der Ausgangswerte. Fehlende Initialisierungen könnten teuflische Fehler verursachen die erst viel später auftreten, weshalb die eigentlich Fehlerursache ziemlich schwer festzustellen ist.
Warum der Code jetzt funktioniert? Ganz einfach, weil du jetzt explizit jeden Fall ausschließt, in dem entweder ax oder ay ein nicht existierendes Array-Feld referenzieren! ;)

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!


Zuletzt bearbeitet von Motzi am Mo 07.04.03 19:58, insgesamt 2-mal bearbeitet
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Mo 07.04.03 19:48 
und du hast da einen fehler beoben bei if ax > ay then exit;

_________________
MFG
Michael Springwald, "kann kein englisch...."
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 07.04.03 19:55 
Ok.. ich glaube der Fehler ist eine Kombination aus 3 Stellen.. aus dem Original-Code:

1) im OnTimer
ausblenden Quelltext
1:
if ay > MatrixMaxX then Exit; // falscher Vergleich					


2)im OnKeyPress
ausblenden Quelltext
1:
if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg					


3) im OnTimer
ausblenden Quelltext
1:
2:
if ay > MatrixMaxX then
if ax > MatrixMaxX then

In beiden Fällen muss der Vergleich auf >= lauten. Denn wenn ax = MatrixMaxX ist wird es nicht auf -1 zurückgesetzt, aber trotzdem nochmal um 1 erhöht.

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Popov Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 07.04.03 21:36 
Ok, das Problem ist weg. Deshalb ist die Lösung sekundär. Aber mal par Worte zu den Punkten:

ausblenden Quelltext
1:
if ay > MatrixMaxX then Exit; // falscher Vergleich					


Ist zwar ein Fehler, aber hat mit dem eigentlichen Problem nichts zu tun, da der Fehler auftrit bevor ay > MatrixMaxY ist. Der Fehler kommt davon, daß es vorher nur ein MatrixMax gab und keine MatrixMaxX / ...Y. Das hat aber mit dem eigentlichen Problem nichts zu tun.

ausblenden Quelltext
1:
if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg					


Das +1 ist schon richtig, da hier die Matrixzeile drunter angesprochen wird. Aber auch ohne das +1 gabs den Fehler.

ausblenden Quelltext
1:
if ax > MatrixMaxX then					


Das ist auf jeden Fall ein schlimmer Fehler. Das könnte auch der gesuchte Fehler sein. Werde es noch prüfen.

_________________
Popov
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 07.04.03 21:47 
Popov hat folgendes geschrieben:
ausblenden Quelltext
1:
if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg					


Das +1 ist schon richtig, da hier die Matrixzeile drunter angesprochen wird. Aber auch ohne das +1 gabs den Fehler.

Das mag schon sein, nur schließt der Vergleich ay > MatrixMaxY den Fall ay = MatrixMaxY nicht aus wodurch dann mit ay + 1 der Index auserhalb der Matrix liegt! Lösung wäre entweder das +1 zu entfernen oder auch hier den Vergleich auf >= umzuändern..

Aber egal.. nachdem der Fehler ja behoben ist braucht man den Code nicht noch weiter zu zerlegen...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!