Last active
October 30, 2023 15:38
-
-
Save michaliskambi/7bd177b266f0255dc5dd880406fc48e6 to your computer and use it in GitHub Desktop.
Implement Motion method to make orbit around an object horizontally
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ Main view, where most of the application logic takes place. | |
Feel free to use this code as a starting point for your own projects. | |
This template code is in public domain, unlike most other CGE code which | |
is covered by BSD or LGPL (see https://castle-engine.io/license). } | |
unit GameViewMain; | |
interface | |
uses Classes, | |
CastleVectors, CastleComponentSerialize, | |
CastleUIControls, CastleControls, CastleKeysMouse, CastleViewport; | |
type | |
{ Main view, where most of the application logic takes place. } | |
TViewMain = class(TCastleView) | |
published | |
{ Components designed using CGE editor. | |
These fields will be automatically initialized at Start. } | |
LabelFps: TCastleLabel; | |
Viewport1: TCastleViewport; | |
public | |
constructor Create(AOwner: TComponent); override; | |
procedure Start; override; | |
procedure Update(const SecondsPassed: Single; var HandleInput: Boolean); override; | |
function Press(const Event: TInputPressRelease): Boolean; override; | |
function Motion(const Event: TInputMotion): Boolean; override; | |
end; | |
var | |
ViewMain: TViewMain; | |
implementation | |
uses SysUtils; | |
{ TViewMain ----------------------------------------------------------------- } | |
constructor TViewMain.Create(AOwner: TComponent); | |
begin | |
inherited; | |
DesignUrl := 'castle-data:/gameviewmain.castle-user-interface'; | |
end; | |
procedure TViewMain.Start; | |
begin | |
inherited; | |
end; | |
procedure TViewMain.Update(const SecondsPassed: Single; var HandleInput: Boolean); | |
begin | |
inherited; | |
{ This virtual method is executed every frame (many times per second). } | |
Assert(LabelFps <> nil, 'If you remove LabelFps from the design, remember to remove also the assignment "LabelFps.Caption := ..." from code'); | |
LabelFps.Caption := 'FPS: ' + Container.Fps.ToString; | |
end; | |
function TViewMain.Motion(const Event: TInputMotion): Boolean; | |
const | |
DesiredUp: TVector3 = (Data: (0, 1, 0)); | |
var | |
AngleRotate: Single; | |
LookTarget, LookDir: TVector3; | |
begin | |
Result := inherited; | |
if Result then Exit; // allow the ancestor to handle keys | |
if buttonLeft in Event.Pressed then | |
begin | |
AngleRotate := -0.01 * (Event.Position.X - Event.OldPosition.X); | |
LookTarget := Viewport1.Items.BoundingBox.Center; | |
{ Note that LookDir.Length determines distance from camera to LookTarget, | |
which we preserve. } | |
LookDir := LookTarget - Viewport1.Camera.Translation; | |
LookDir := RotatePointAroundAxis(Vector4(DesiredUp, AngleRotate), LookDir); | |
Viewport1.Camera.SetView( | |
LookTarget - LookDir, // new camera Translation (aka position) | |
LookDir, // new camera Direction (the length of LookDir given here is ignored, ok) | |
DesiredUp); | |
end; | |
end; | |
function TViewMain.Press(const Event: TInputPressRelease): Boolean; | |
begin | |
Result := inherited; | |
if Result then Exit; // allow the ancestor to handle keys | |
{ This virtual method is executed when user presses | |
a key, a mouse button, or touches a touch-screen. | |
Note that each UI control has also events like OnPress and OnClick. | |
These events can be used to handle the "press", if it should do something | |
specific when used in that UI control. | |
The TViewMain.Press method should be used to handle keys | |
not handled in children controls. | |
} | |
// Use this to handle keys: | |
{ | |
if Event.IsKey(keyXxx) then | |
begin | |
// DoSomething; | |
Exit(true); // key was handled | |
end; | |
} | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment