Entwickler-Ecke

Multimedia / Grafik - Einen kleinen Punkt mit den Pfeiltasten steuern


oneP - Mo 11.05.09 15:31
Titel: Einen kleinen Punkt mit den Pfeiltasten steuern
Tach zusammen!

Ich lern seit ein paar Monaten Delphi und kann schon so ziehmlich die Grundlagen und will jetz auch die Grafischen Sachen lernen.
Was mich da zB interresieren würde, ist, wie man ganz einfach einen kleinen Punkt (oder eine kleine Grafik) mit den Pfeiltasten über das Formular steuert.
Wäre dankbar für ne erklärung (...und für codes) :D


ffgorcky - Mo 11.05.09 15:49

Also ich meine, es müsste mit AktuellesForm.OnKeyPress gehen.
So in etwa mit der Abfrage (vorausgesetzt, Du hast eine solche Komponente drauf):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Procedure TForm1.KeyPress(Key)
if Key=VK_Right then
   GesteuerterButton.Left:=GesteuerterButton.Left+1;
if Key=VK_Left then
   GesteuerterButton.Left:=GesteuerterButton.Left-1;
if Key=VK_Up then      
   GesteuerterButton.Top:=GesteuerterButton.Top-1;
if Key=VK_Down then
   GesteuerterButton.Top:=GesteuerterButton.Top+1;


Wie das jetzt genau mit OnKeyPress geht weiß ich gerade leider nicht so auf Anhieb.


oneP - Mo 11.05.09 16:24

irgendwie wird bei diesem code in der 3. Zeile die ganze zeile rot markiert:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm2.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = vk_up then
    Image1.Top := Image1.Top + 1;


Webo - Mo 11.05.09 16:59

So, wie du es angegeben hat, gehört es in OnKeyDown, dann funktioniert es auch ;-)


oneP - Mo 11.05.09 17:16

jap jetz hab ichs auch!

und wenn ich will, dass eine Meldung gezeigt wird wenn ich mit dem Button ein Label als ziel erreiche, dann müsste der code so irgendwie ähnlich lauten - oder?


Delphi-Quelltext
1:
2:
  if (image1.Top = Label1.Top) and (image1.Left = Label1.left) then
     showmessage('Ziel erreicht!');


weil dieser funktioniert irgendwie nicht...


Yogu - Mo 11.05.09 17:38

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
weil dieser funktioniert irgendwie nicht...

Er funktioniert irgendwie nicht - ich liebe diese präzise Art, Fehler zu beschreiben ;)

Was geht denn nicht? Das sieht eigentlich ganz gut aus. Bedenke, dass die Meldung nur kommt, wenn sich die beiden linken oberen Ecken überlappen - denn schließlich ist der Ursprung des Koordinatensystems in Delphi ja links oben.


Webo - Mo 11.05.09 17:44

Du fragst jetzt nur ab, ob sich die beiden oberen Ecken (und zwar die linken) überlappen, du musst aber ja die ganze Fläche abfragen ...


Georg08 - Mo 11.05.09 17:46

@oneP & ffgorcky

Also mich hat der Tread interessiert, aber

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if Key=VK_Right then
   GesteuerterButton.Left:=GesteuerterButton.Left+1;
if Key=VK_Left then
   GesteuerterButton.Left:=GesteuerterButton.Left-1;
if Key=VK_Up then
   GesteuerterButton.Top:=GesteuerterButton.Top-1;
if Key=VK_Down then
   GesteuerterButton.Top:=GesteuerterButton.Top+1;
end;

macht bei mir nichts, mein button bleibt da wo er ist...


oneP - Mo 11.05.09 17:51

@ffgorcky:
sorry für diese unpräzise beschreibung.
ich bin mit dem button einfach nicht genau auf den Pixel gekommen. Aber es funktioniert.
Es gibt aber bestimmt eine möglichkeit, das eine meldung gezeigt wird sobald der Button das label erreicht, oder?

@Georg08:
war bei mir genauso. Ich hab einfach ein TImage genommen und ein bild rein gemacht. Der Button muss weg.


Dude566 - Mo 11.05.09 17:53

Du machst eine Kollisionsabfrage die am besten in einem Timer stattfindet, kannst aber auch bei jedem Tastendruck abfragen.


oneP - Mo 11.05.09 17:58

user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
Du machst eine Kollisionsabfrage die am besten in einem Timer stattfindet, kannst aber auch bei jedem Tastendruck abfragen.


...und wie mach ich das?


Dude566 - Mo 11.05.09 18:04

Ich dachte du könntest die Grundlagen, dann wirst du ja wohl im Stande sein eine If-Abfrage zu machen mit der überprüft wird ob die beiden Koordinaten sich bereits berühren.


Yogu - Mo 11.05.09 18:07

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
Es gibt aber bestimmt eine möglichkeit, das eine meldung gezeigt wird sobald der Button das label erreicht, oder?

Ja, die gibt es. Und zwar musst du prüfen, ob sich Rechteck 1 (Button) und Rechteck 2 (Label) überlappen. Ich schreibe dir jetzt keinen fertigen Quelltext, aber eine Anregung:


Delphi-Quelltext
1:
2:
3:
4:
5:
Erreicht :=
  ((Rect1.Right > Rect2.Left) or     // X-Achse
   (Rect2.Right > Rect1.Left)) and
  ((Rect1.Bottom > Rect2.Top) or     // Y-Achse
   (Rect2.Bottom > Rect1.Top));

Die Eigenschaften Right und Bottom kannst du aus Left bzw. Right und den Ausmaßen des Steuerelements herausbekommen.

user profile iconGeorg08 hat folgendes geschrieben Zum zitierten Posting springen:
[...] macht bei mir nichts, mein button bleibt da wo er ist...

Das Problem ist, dass OnKeyDown nur reagiert, wenn das Formular den Fokus hat, d.h. wenn kein Control, das einen Fokus bekommen kann, vorhanden ist. Da der Button sofort fokusiert ist, müsstest du das Ereignis des Buttons verwenden :idea:


Dude566 - Mo 11.05.09 18:17

Dann muss er es halt mit GetASyncKeyState machen.

Hier z.B.: http://forum.delphi-treff.de/showthread.php?t=20917


oneP - Mo 11.05.09 18:42

Yogu,
könntest du mir das mal vielleicht bissel genauer erklären?
ich blick im moment gar nichts durch mit diesen Rechtecken und Bottom und Right...
und wie man "Erreicht" Deklarieren muss usw.

wäre dir sehr dankbar!!


ffgorcky - Mo 11.05.09 18:46

Also ich denke, Du müsstest das eher so schreiben:

Delphi-Quelltext
1:
2:
3:
4:
if ((image1.Top = Label1.Top+Label1.Height) and (image1.Left>Label1.left+Label1.Width) and(image1.Top>Label1.Top+Label1.Height))//Also wenn das Image unten an das Label "angedockt" hat...
 or ((Label1.Top = image1.Top+Label1.Height) and (image1.Left>Label1.left+image1.Width) and(Label1.Top>image1.Top+image1.Height))//Also wenn das Image oben an das Label "angedockt" hat...
 or ((image1.Left = Label1.left+Label1.Width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width))//Also wenn das Image rechts an das Label "angedockt" hat
 or ((Label1.left = image1.Left+image1.width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width)) then//Also wenn das Image links an das Label "angedockt" hat

Ich hoffe, dass ich mich da jetzt nirgendwo vertan habe, weil ich im Moment keine Möglichkeit habe, das zu überprüfen.


Yogu - Mo 11.05.09 18:52

Das von mir war nur ein kleiner Pseudo-Code, natürlich gibt es kein Right und Bottom. Das kann man ganz einfach durch Left+Width bzw. Top+Height ersetzen, hätte aber meinen Code unübersichtlicher gemacht.

Und dann ersetze noch Rect1 durch deinen Button und Rect2 durch das Label - fertig :D


oneP - Mo 11.05.09 19:13

also mein Quellcode lautet jetzt:

Delphi-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:
53:
54:
55:
56:
57:
58:
59:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm2 = class(TForm)
    Image1: TImage;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);

    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);


  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;


implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
  Image1.Picture.loadfromfile ('Kegel.bmp');
end;



procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key = vk_left then
     image1.Left := image1.Left - 1;
  if key = vk_right then
     image1.Left := image1.Left +1;
  if key = vk_up then
     image1.Top := image1.Top - 1;
  if key = vk_Down then
     image1.Top := Image1.Top + 1;

     if ((image1.Top = Label1.Top+Label1.Height) and (image1.Left>Label1.left+Label1.Width) and(image1.Top>Label1.Top+Label1.Height))//Also wenn das Image unten an das Label "angedockt" hat...
 or ((Label1.Top = image1.Top+Label1.Height) and (image1.Left>Label1.left+image1.Width) and(Label1.Top>image1.Top+image1.Height))//Also wenn das Image oben an das Label "angedockt" hat...
 or ((image1.Left = Label1.left+Label1.Width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width))//Also wenn das Image rechts an das Label "angedockt" hat
 or ((Label1.left = image1.Left+image1.width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width)) //Also wenn das Image links an das Label "angedockt" hat  then showmessage('Ziel erreicht!');
    then showmessage('Ziel erreicht!');
end;


end.

aber es wird schon "Ziel erreicht" wenn ich noch nicht mal am Label bin.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

und bei deinem, Yogu , wird schon kurz nach dem Start "Ziel erreicht" angezeigt.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

..und noch ne Frage:

wenn ich mit den Pfeiltasten den Punkt zB nach links steuern will und die links-taste gedrückt halte bleibt der Punkt erst einen kurzen Moment stehen und bewegt sich dann erst. (genauso wie ein Cursor im Text)
kann man das irgendwie im Quellcode abschalten sodass sich der Punkt gleich nach links bewegt?

und wie kann man den Punkt quer steuern?


Webo - Di 12.05.09 16:55

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:

wenn ich mit den Pfeiltasten den Punkt zB nach links steuern will und die links-taste gedrückt halte bleibt der Punkt erst einen kurzen Moment stehen und bewegt sich dann erst.

Das ist die automatische Eingabeverzögerung, damit man bei Texten nicht ausversehen mehrere Buchstaben hat !

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
und wie kann man den Punkt quer steuern?

Wenn du es gleich richtig "quer" steuern willst, also auch diagonal und beliebige Richtungen, solltest du dich mal mit Sinus/Cosinus befassem, darüber könntest du das hinbekommen. Da du aber ja zum Bewegen ständig die Tasten drückst, wird nur das Diagonale gehen ... (vllt lässt du das "laufen" des Punktes über nen Timer laufen und lenkst nur die Richtung mit den Tasten ? )


Grüße
Webo


Jakob_Ullmann - Di 12.05.09 17:29

Zitat:
Das ist die automatische Eingabeverzögerung, damit man bei Texten nicht ausversehen mehrere Buchstaben hat !


Genau aus diesem Grund sollte man lieber auf Timer + GetAsyncKeystate umsteigen.

Zitat:

Delphi-Quelltext
1:
2:
3:
4:
if ((image1.Top = Label1.Top+Label1.Height) and (image1.Left>Label1.left+Label1.Width) and(image1.Top>Label1.Top+Label1.Height))//Also wenn das Image unten an das Label "angedockt" hat...
 or ((Label1.Top = image1.Top+Label1.Height) and (image1.Left>Label1.left+image1.Width) and(Label1.Top>image1.Top+image1.Height))//Also wenn das Image oben an das Label "angedockt" hat...
 or ((image1.Left = Label1.left+Label1.Width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width))//Also wenn das Image rechts an das Label "angedockt" hat
 or ((Label1.left = image1.Left+image1.width) and (image1.Top > Label1.Top+Label1.Height) and (image1.Left < Label1.left+Label1.Width)) then//Also wenn das Image links an das Label "angedockt" hat


Noch umständlicher geht's nicht? Der Code wurde doch schon von Yogu gepostet. Als kleine Anregung noch die Eigenschaften Width und Height.

edit: Eventuell sollte man auch noch TForm.DoubleBuffered auf True stellen.


oneP - Di 12.05.09 18:37

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Eventuell sollte man auch noch TForm.DoubleBuffered auf True stellen.

und wo finde ich diese Eigenschaft? oder wo und wie muss ich sie im Quelltext schreiben?

und noch ne Frage: wie könnte ich eine Kollision mit den Wänden machen? die müsste doch irgendwie so gehn:

Delphi-Quelltext
1:
2:
 if Image1.Left = Form1.clientwidth then
  ....


Moderiert von user profile iconNarses: Zitat repariert


Yogu - Di 12.05.09 19:29

Hallo user profile icononeP,

hier wieder mal ein Pseudo-Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
AusserFormular :=
  ((Button.Right > Form.Right) or     // X-Achse
   (Button.Left < Form.Left)) or
  ((Button.Bottom > Form.BottomTop) or     // Y-Achse
   (Button.Top < Form.Top));

Edit: Hervorgehobenen Fehler behoben :autsch:


oneP - Di 12.05.09 20:13

Yogu danke für den Code.
Der sieht ganz logisch aus. Aber komischerweise rast der Punkt immer noch durch die Wand...
also der sieht jetz bei mir so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
if
((Image1.Left+width > Form1.clientwidth) or     // X-Achse
(Image1.Left < Form1.Left)) and
((Image1.top+height > Form1.clientHeight) or     // Y-Achse
(Image1.Top < Form1.Top))
then  begin
 rechts := 0;
 runter := 0;
end;

rechts und runter sind variablen des timers.


Yogu - Di 12.05.09 20:15

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
if
((Image1.Left+width > Form1.clientwidth) or     // X-Achse
(Image1.Left < Form1.Left)) and
((Image1.top+height > Form1.clientHeight) or     // Y-Achse
(Image1.Top < Form1.Top))
then  begin
 rechts := 0;
 runter := 0;
end;

Tja - Faulheit wird bestraft :mrgreen:

Natürlich musst du das Image1. vor Width bzw. Height wiederholen - sonst greifst du ja auf die Eigenschaften des Formulars zu :idea:


oneP - Di 12.05.09 20:43

Ja ich habs jetzt geändert. Trotzdem rennt der Punkt durch die wand.


Jakob_Ullmann - Di 12.05.09 20:44

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Eventuell sollte man auch noch TForm.DoubleBuffered auf True stellen.

und wo finde ich diese Eigenschaft? oder wo und wie muss ich sie im Quelltext schreiben?


Zumindest bei D2006 nicht im Objektinspektor. Du könntest zum Beispiel bei FormCreate schreiben:


Delphi-Quelltext
1:
DoubleBuffered := True;                    


Hilft gegen das Flimmern. :P


Xentar - Di 12.05.09 20:58

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
Ja ich habs jetzt geändert. Trotzdem rennt der Punkt durch die wand.

Zeig bitte nochmal den Quellcode, wie du ihn dafür im Moment stehen hast.
Und, mit welcher Wand hast du das ausprobiert?

Edit: Ähh.. dsa Beispiel von Yogu geht nur, wenn der Punkt auf der X- UND Y-Achse außerhalb des Bildes ist. Du musst das noch so abändern, dass es ausreicht, wenn man auf einer der Seiten raus ist.


Jakob_Ullmann - Di 12.05.09 21:02

Ungetestet, aber imho müsste es reichen, aus dem AND ein OR zu machen.


Xentar - Di 12.05.09 21:06

Spielverderber :D


Jakob_Ullmann - Di 12.05.09 21:07

Sorry, jetzt sehe ich es auch. :oops:


oneP - Di 12.05.09 21:25

Das AND hab ich schon lang geändert. Bin selbst drauf gekommen :D Jetz funktionierts.
aber wieso hält der Punkt ein paar millimeter vor der Wand schon an?

und noch paar weitere Fragen:
- wie stellt man im Formular ein, dass der user das fenster selbst nicht vergrößern kann?
- wenn der Punkt zB an der Linken Wand andockt dann bleibt er dort "hängen" und man kann ihn nicht rauf und
runter steuern nur rechts. Wie kann man dieses "Heften" abschalten?
- wie kann ich ein anderes Image durch Andocken verschwinden lassen? (wie man die aktion auslößt weiß ich, aber
ich weiß nicht welche eigenschaft man da ändern muss)

wäre sehr dankbar für die hilfe


Xentar - Di 12.05.09 21:34

Normalerweise soll man ja für jede neue Frage einen eigenen Thread aufmachen..

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
aber wieso hält der Punkt ein paar millimeter vor der Wand schon an?

Füllt der Punkt vielleicht nich das ganze Image aus?

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
und noch paar weitere Fragen:
- wie stellt man im Formular ein, dass der user das fenster selbst nicht vergrößern kann?

Eigenschaft: "Constraints" heißt die glaub ich. Setze da jeweils Min = Max.

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
- wenn der Punkt zB an der Linken Wand andockt dann bleibt er dort "hängen" und man kann ihn nicht rauf und
runter steuern nur rechts. Wie kann man dieses "Heften" abschalten?

Tja.. Code?

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
- wie kann ich ein anderes Image durch Andocken verschwinden lassen? (wie man die aktion auslößt weiß ich, aber
ich weiß nicht welche eigenschaft man da ändern muss)

Mal überlegen.. verschwinden bedeutet "nicht sichtbar". Und was sichtbar im englischen heißt, kannst du selber nachschauen ;) Tipp: Guck dir die Eigenschaften von dem Image an..


oneP - Mi 13.05.09 13:33

Danke thepaine91!
Moderiert von user profile iconNarses: Der Dank bezieht sich auf den Code aus diesem Beitrag [http://www.delphi-forum.de/viewtopic.php?p=562167#562167] - wird ab hier allerdings nicht mehr verfolgt und ist deshalb in einen eigenen Thread verlagert.

@Xentar:
Zitat:

Füllt der Punkt vielleicht nich das ganze Image aus?

stimmt. Daran habe ich gar nicht gedacht.

Zitat:
Mal überlegen.. verschwinden bedeutet "nicht sichtbar". Und was sichtbar im englischen heißt, kannst du selber nachschauen ;) Tipp: Guck dir die Eigenschaften von dem Image an..

"visible" macht das Image nur unsichtbar. Aber es ist immer noch aktiv d.h. wenn man über das unsichtbare drüberfährt wird trotzdem die aktion ausgelößt. Ich will aber das es ganz verschwindet. Verstehste was ich mein?

Zitat:
Tja.. Code?

So sieht mein Code aus. Ist vllt sehr anfängerhaft aber alles funzt soweit. Nur dass die Kugel nicht mehr nach oben oder unten steuerbar ist wenn sie zB an der linken Wand "heftet"


Delphi-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:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
unit Punkt2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  runter, rechts: integer;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
  image1.Picture.loadfromfile('Punkt2.bmp');
  doublebuffered := true;
  rechts := 0 ;
  runter := -1;
end;


procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   //links
  if key = vk_left then
  begin
    rechts := rechts -1;
    runter := 0;
    if rechts < -1 then
      rechts := -1;
    if rechts =0 then
      rechts := -1;
    
  end;



  //rechts
  if key = vk_right then
  begin
    rechts :=rechts +1;
    runter := 0;
    if rechts > 1 then
      rechts := 1;
    if rechts = 0 then
     rechts := +1;
  end;


  //oben
  if key = vk_up then
  begin
    runter := runter -1;
    rechts := 0;
    if runter < -1 then
      runter := -1;
    if runter = 0 then
      runter := -1;
  end;

  //unten
  if key = vk_down then
  begin
    runter := runter +1;
    rechts := 0;
    if runter >1 then
      runter := 1;
    if runter = 0 then
      runter := +1;
  end;

  //stop
  if key = vk_numpad0 then
   begin
     runter := 0;
     rechts := 0;
   end;

end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
  with Image1 do begin
    Top := Top + (runter);
    Left := Left +(rechts);
    if
    ((Image1.Left+Image1.width > Form1.clientwidth) or     // X-Achse
    (Image1.Left < Form1.Left)) or
    ((Image1.top+Image1.height > Form1.clientHeight) or     // Y-Achse
    (Image1.Top < Form1.Top))
    then  begin
     rechts := 0;
     runter := 0;
    end;
  end;
end;

end.


oneP - Mi 13.05.09 15:31

Zitat:
So sieht mein Code aus. Ist vllt sehr anfängerhaft aber alles funzt soweit. Nur dass die Kugel nicht mehr nach oben oder unten steuerbar ist wenn sie zB an der linken Wand "heftet"

könnte vielleicht jemand oben gucken und mir auf die Frage antworten? Please :wink:


Narses - Do 14.05.09 22:51

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
1. würde ich

Delphi-Quelltext
1:
if runter <= 0 then runter := -1//machen                    

2. Nenne mal runter und rechts in : Horizontal/Vertikal o. Wagerecht/Senkrecht um so verwirren sie nur.

3. Dein Fehler finde ich gerade durch pures lesen nicht der Quelltext verwirrt mich auch ordentlich würde die Lösung nochmal überdenken finde sie nicht so toll. Aber vielleicht kann dir jemand anders helfen.

(falls ich später zeit hab guck ich ihn mir mal in delphi an)


thepaine91 - Fr 15.05.09 00:23

Danke für dein wundervolles Zitat Narses.

onep hab dein Quelltext so übernommen da Funktioniert eigentlich nichts. Konnte deinen Fehler nicht reproduzieren da meine Kugel garnicht haftete.

Auch kann man keine nordwestliche bewegung usw. machen das ist aber dem quelltext nach zu urteilen absicht.

Trotzdem lege ich dir nah mal meine Thread version anzuschauen dort bewegt sich das ganze viel schneller. Bleibt dir überlassen deinen Fehler kann ich somit nicht finden.

EDIT:
Ein fehler bei deiner Kollisionsabfrage:

Delphi-Quelltext
1:
2:
    if Panel1.Left >= Form1.ClientWidth - Panel1.width then //do somthing
    if Panel1.Top >= Form1.ClientHeight - Panel1.Height then //do somthing

Zur erklärung Form1.Width schliest auch den Rand ein der aber schon auserhalb des Clientsbereichs liegt so addieren sich dort zur width links und rechts einige mm dazu.
Bei der Form1.height das selbe.
bei Panel1.width deshalb damit dort die Ränder einberechnet werden in dem Fall wichtig!
Wenn du das befolgst sollte deine Kollisionsabfrage einwandfrei Funktionieren.


Narses - Fr 15.05.09 17:13

Moin!

user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
könnte vielleicht jemand oben gucken und mir auf die Frage antworten? Please :wink:
user profile icononeP hat folgendes geschrieben Zum zitierten Posting springen:
So sieht mein Code aus. [...] Nur dass die Kugel nicht mehr nach oben oder unten steuerbar ist wenn sie zB an der linken Wand "heftet"
Ich habe deinen Quelltext auch mal in ein Projekt eingefügt und getestet. Sieht man davon ab, dass die Kollisionsabfrage an den Formular-Rändern nicht korrekt funktioniert (dazu hast du ja schon Tipps bekommen), kann ich deine Fehlerbeschreibung nicht nachvollziehen. :nixweiss:


user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Trotzdem lege ich dir nah mal meine Thread version anzuschauen dort bewegt sich das ganze viel schneller. Bleibt dir überlassen deinen Fehler kann ich somit nicht finden.
Ich halte den Thread-Ansatz immer noch für daneben, sorry. :nixweiss: Wenn das Objekt sich schneller bewegen soll, dann muss man halt mehr als 1 Pixel schieben, fertig. Hier sind einfach die Grenzen der VCL. Wenn man das "vernünftig" machen will, geht eh kein Weg an DirectX oder OpenGL vorbei... :| Noch dazu scheint es mir, als würde der threadbasierte Ansatz den Fragesteller überfordern. :?

cu
Narses


thepaine91 - Fr 15.05.09 17:26

Dann solltest du auch begründen warum meine letztige Version daneben ist.
Die kollisionsfrage kann man meine Threadobjekt entnehmen dort funktioniert sie einwandfrei.
mehr als ein Pixel zu bewegen sieht zu dem Unschön und ruckelig aus.
Aber Panels oder ähnliche Vcl objekte über ein Formular zu bewegen ist grundsätzlich kein schöner Ansatz, denn dafür gibt es ander möglichkeiten.

Aber der OpenGL verweis ist durchaus berechtigt und da ich überlegt habe aus dem Testprogramm ein kleines Spiel zu programmieren durchaus hilfreich.

Nochmal zum Thread hier. Nimm meine Kollisionsabfrage und schon solltest du keine Probleme mehr haben. Sofern das Formular sizeable ist lege ich dir noch folgendes nah:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.FormResize(Sender: TObject);
begin
  if Image1.Left >= Form1.ClientWidth - Image1.width then image1.Left := Form1.ClientWidth - Image1.width;
  if Image1.Top >= Form1.ClientHeight - Image1.Height then image1.Top := Form1.ClientHeight - Image1.Height;
  if form1.ClientWidth < image1.Width then
  begin
    form1.ClientWidth := image1.Width;
    image1.Left := 0;
  end;
  if form1.ClientHeight < image1.Height then
  begin
    form1.ClientHeight := image1.Height;
    image1.Top := 0;
  end;
end;


Narses - Fr 15.05.09 18:39

Moin!

Worum geht´s hier eigentlich? :gruebel: Dem Threadersteller unbedingt deinen Code aufzuquatschen oder ihm dabei helfen, einen Ansatz zu entwickeln, den er auch versteht und der ihn weiter bringt? :idea: Du hast doch jetzt schon 26x darauf hingewiesen, dass dein Code toll ist, reicht langsam. :zwinker: da ist der Nickname echt Programm *g*

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Dann solltest du auch begründen warum meine letztige Version daneben ist.
Das brauche ich gar nicht, der Threadersteller zeigt durch Ignorieren seit einigen Posts bereits, dass der Ansatz nicht nach seinem Geschmack ist. :) Und wenn dir das noch nicht genug ist, nimmst du dir gleich selbst den Wind aus den Segeln:
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Aber Panels oder ähnliche Vcl objekte über ein Formular zu bewegen ist grundsätzlich kein schöner Ansatz,
Genau so ist das, es ist einfach VCL, da macht der Thread-Timer-CPU-Last-Generator auch keinen Rennwagen draus. :lol:

Mal sehen, wenn noch Zeit ist, schreib ich dir vielleicht noch was zu deinem Code im anderen Thread. ;)

cu
Narses


thepaine91 - Fr 15.05.09 23:26

Er ist ohne frage schneller aber hat sicher Nachteile du hast recht hab vil sehr penetrant auf meine Projekt hingewiesen.
Aber habe auch nur auf codeausschnitte für die Kollisionsabfrage hingewiesen beim letzten mal denn diese Funktioniert wie bereits erwähnt einwandfrei und diese könnte er sich als Vorlage nehmen. Denn darum gings ja die Kollisionsabfrage funktionierte nicht richtig. Da ich wie schon erwähnt den FEhler nicht reproduzieren konnte kann ich nur darauf verweisen. Als ansatz sollte das genügen und mit ein wenig bemühung kann er das in seinen "TIMER" einbauen :-)

[Schleimen]
Wenn du Zeit für eine Antwort findest wäre super :-) Denn ich kleiner unwissender Delphinoob(Anfänger) bin ohne dich hoffnungslos verloren bzw. ohne diese Community :-)
[/Schleimen]


Webo - Sa 16.05.09 12:47

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
und diese könnte er sich als Vorlage nehmen

Wie heisst es denn so schön : "Aus Fehlern lernt man". Und das stimmt ! Copy+Paste hilft ihm absolut nicht, denn das hilft ihm nicht seinen Fehler zu erkennen, zu verstehen und daraus zu lernen !


thepaine91 - Sa 16.05.09 18:59

Richtig lesen bitte. Mit copy paste erreicht er nicht viel deswegen "VORLAGE" um es so umzubauen das es in seinem Timer funktioniert soll als richtlinie dienen mehr nicht.