AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Tastatursteuerung für Objekt im 3D-Raum

Ein Thema von ZYLAGON · begonnen am 15. Jun 2017 · letzter Beitrag vom 18. Jun 2017
Antwort Antwort
ZYLAGON

Registriert seit: 11. Nov 2015
50 Beiträge
 
Delphi 10.3 Rio
 
#1

Tastatursteuerung für Objekt im 3D-Raum

  Alt 15. Jun 2017, 22:26
Schönen guten Abend zusammen,

ich habe mir eine primitive 3D-Steuerung zusammengebastelt.
Das Objekt fährt immer in Blickrichtung solange die Geschwindigkeit positiv ist.
Sieht auch so aus als ob alles korrekt funktioniert.
Bin allerdings mit der Tastatursteuerung unzufrieden und hoffe auf Hilfe.

Hier mal der Code der Steuerung:

Delphi-Quellcode:
unit Test_Vektor;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Viewport3D,
  System.Math.Vectors, FMX.Controls3D, FMX.Objects3D, FMX.StdCtrls,
  FMX.Controls.Presentation, Windows, FMX.MaterialSources;

type
  TForm1 = class(TForm)
    ColorMaterialSource2: TColorMaterialSource;
    Viewport3D1: TViewport3D;
    Dummy1: TDummy;
    Figur: TCube;
    Auge: TSphere;
    Zielpunkt: TSphere;
    procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
      Shift: TShiftState);
  private
    { Private-Deklarationen }
    fZielpunktVektor:TVector3D;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
begin
  if GetAsyncKeystate(VK_UP)<0 then
    begin
      fZielpunktVektor:=Zielpunkt.LocalToAbsoluteVector(Zielpunkt.Position.Vector);
      Figur.Position.Vector:= fZielpunktVektor;
    end;

  if GetAsyncKeystate(VK_LEFT)<0 then
    begin
      Figur.RotationAngle.Y:=Figur.RotationAngle.Y-1;
    end;

  if GetAsyncKeystate(VK_RIGHT)<0 then
    begin
      Figur.RotationAngle.Y:=Figur.RotationAngle.Y+1;
    end;

  if GetAsyncKeystate(VK_Prior)<0 then
    begin
      Figur.RotationAngle.X:=Figur.RotationAngle.X+1;
    end;

  if GetAsyncKeystate(VK_Next)<0 then
    begin
      Figur.RotationAngle.X:=Figur.RotationAngle.X-1;
    end;

  if GetAsyncKeystate(VK_HOME)<0 then
    begin
      Figur.RotationAngle.Z:=Figur.RotationAngle.Z+1;
    end;

  if GetAsyncKeystate(VK_END)<0 then
    begin
      Figur.RotationAngle.Z:=Figur.RotationAngle.Z-1;
    end;

end;

end.


Wenn ich z.B. Pfeiltaste hoch gedrückt halte, bewegt sich das Objekt in Blickrichtung.
Drücke ich jetzt zusätzlich Pfeiltaste links, gibt´s einen kurzen Aussetzer, Objekt bewegt sich dann allerdings korrekt nach vorne links aus Blickwinkelsicht.
Lasse ich irgendwann die Pfeiltaste links los, dann bleibt das Objekt stehen.
Das kann ich noch umgehen, wenn ich eine beliebige Taste (z.B. Taste F) beim Loslassen der Pfeiltaste Links drücke.
Dann habe ich wieder diesen kurzen Aussetzer und das Objekt bewegt sich wie gewünscht nach vorne in Blickrichtung.

Also gibt es 2 Probleme:
1) Kurzer Aussetzer bei Zuschalten einer weiteren Taste.
2) Bei Loslassen einer Taste wird eine zusätzliche, unbeteiligte Taste benötigt, damit Objekt nicht zum Stillstand kommt. Das führt allerdings auch zu einem kurzen Aussetzer.


Falls jemand den obigen Code testen möchte, bedarf es möglicherweise noch ein paar Erklärungen:

Struktur:
Viewport ist Parent von Dummy
Dummy ist Parent von Figur (Dummy wird nicht unbedingt benötigt. Dann wäre Viewport der Parent für Figur)
Figur (hier habe ich einfach nur einen StandardCube der Größe 1 genommen) ist Parent von sowohl Auge als auch von Zielpunkt

Das Auge der Figur dient zur Erkennung der Blickrichtung.
Ich habe hier eine Sphere Größe 0,2 gewählt bei einer Z-Position von 0,51.
Als MaterialSource habe ich ColorMaterialSource2 zugeordnet, um das Auge erkennen zu können.

Jetzt zum Zielpunkt.
Die Figur fährt immer in Richtung Zielpunkt.
So ist es möglich, in Blickrichtung zu fahren.
Ich habe hier eine Sphere Größe 0,1 gewählt bei einer Z-Position von 0,01.
Die Z-Position ist sozusagen die Geschwindigkeit.

VG
ZYL
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#2

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 16. Jun 2017, 09:33
Was genau soll denn passieren ?

Vielleicht musst du KeyDown UND KeyUp benutzen um das gewünschte Verhalten hinzubekommen ?
KeyDown merkt sich dann den KeyPress und feuert nur einmal, weitere Bewegung könntest du selber über einen Timer steuern.
KeyUp setzt dann diese Bewegung (Timer) wieder zurück.

Rollo
  Mit Zitat antworten Zitat
ZYLAGON

Registriert seit: 11. Nov 2015
50 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 16. Jun 2017, 21:29
Hallo Rollo62,

beispielsweise drücke ich gleichzeitig die Pfeiltaste oben und die Pfeiltaste links.
Das Objekt fährt in die gewünschten Richtungen.
Lasse ich dann Pfeiltaste links los, bleibt das Objekt leider stehen.

Ich weiß noch nicht, welcher Code im OnKeyUp-Ereignis das gewünschte Resultat bringen kann.
Habe da noch eine Idee, welche ich aber erst am Montag überprüfen kann, da der dazugehörige Code momentan leider nicht verfügbar ist.

VG
ZYL
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 16. Jun 2017, 21:41
Das liegt vorallem davon, weil DU hier zwei Methoden vermischst.

AsyncKey liefert immer den aktuellen Status aller Tasten.
Die KeyDown/KeyUp-Events liefern immer nur für die letzte Taste ein Repeat-Ereignis und lässt du eine Taste los, dann wird kein Repeat mehr ausgelöst und die Messages stoppen.
$2B or not $2B
  Mit Zitat antworten Zitat
ZYLAGON

Registriert seit: 11. Nov 2015
50 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 16. Jun 2017, 23:38
Hallo himitsu,

habe das jetzt verstanden.
Anstelle alles über OnKeyDown abzufragen, löse ich das Problem über den von Rollo62 erwähnten Timer.
Der OnKeyDown-Code kommt in das OnTimer-Ereignis des Timers (Intervall habe ich jetzt mal so niedrig wie möglich auf 1 gesetzt.)
Funktioniert alles (weder Aussetzer noch Anhalten).

Kann man auch anders lösen als mit einem Timer wegen Performance?

Jedenfalls mal schon vielen Dank, dass die Steuerung funktioniert.

VG
ZYL
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#6

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 17. Jun 2017, 23:00
Kann man auch anders machen.
Die Frage ist ob du eine GameLoop irgendwo laufen hast, mit Timer oder auch in z.B. IdleEvents o.ä.
Da kann man auch die AsyncKey-Abfrage reinlegen.

Ich denke das du womöglich im Moment die ersten Versuche machst, und da würde ich auch erstmal einen Teimer nehmen.
Dasist nicht schlecht, da musst du nur aufpassen das es kein EventFlodding gibt, also Timer.Interval 100ms
reicht vielleicht aus für eine flüssige Bewegung, und deine Bearbeitungsroutine sollte weitere TimerEvents ignorieren während du in der Routine noch rechnest.

Rollo
  Mit Zitat antworten Zitat
ZYLAGON

Registriert seit: 11. Nov 2015
50 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Tastatursteuerung für Objekt im 3D-Raum

  Alt 18. Jun 2017, 19:28
Danke für die Tipps, Rollo62.
Habe jetzt den Timer ein wenig entschärft und bin auf 30ms hoch.
Einfaches Projekt im Anhang, falls sich jemand mit den gleichen Problemen herumplagt.
Ergänzt wurden noch Kleinigkeiten wie Kamerasteuerung, Beschleunigung, Station.
Insgesamt beurteilt, ist das für den Anfang schon eine recht ordentliche Steuerung.
Vielen Dank nochmals für die Hilfe.

VG ZYL
Angehängte Dateien
Dateityp: zip Test_Vektor.zip (54,4 KB, 10x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz