Accueil > > > RUBIK'S CUBE AVEC FIREMONKEY 3D
RUBIK'S CUBE AVEC FIREMONKEY 3D
Information sur la source
Description
Le but de ce programme a été pour moi de travailler avec la partie 3D de Firemonkey et d'une certaine manière promouvoir mon outil preferé. A/ But et limites Le Rubik's Cube est fonctionnel mais ne dispose pas la fonctionnalité resolution automatique. Ceci a deja été fait et ne presente plus de fort interet. Ceux qui s'attendent a un respect de la notation officielle des faces du Rubik's cube seront déçus. Comment reperer la face AVANT apres des rotations des plans X Y ou Z. J'ai donc utilisé la couleur du cube pivot (central à chaque face) pour decrire un plan. Ceci est important pour la lecture du source. Mais aussi pour le jeu au clavier et avec les boutons colorés. Par contre pour le jeu à la souris no souci ! les cubes coins sont sensibles au clic souris pour les rotations de face. Un tirer/Lacher sur la zone grise permet une rotation de tout le cube. Z- plan Rouge (avant au depart) Z+ plan Orange (arriere au depart) X+ plan Bleu (Droit au depart) X- plan Vert (Gauche au depart) Y- plan Blanc (Haut au depart) Y+ plan Jaune (Bas au depart)
Source
- unit UMain;
-
- interface
- // ______ __
- // /\ ___\ /\ \__
- // _____ \ \ \__/ ___ ___\ \ ,_\ __ ___ __ __ __ __
- // /\ '__`\ \ \ _\/ __`\/' _ `\ \ \/ /'__`\/' _ `\ /'__`\ /'__`\ /\ \/\ \
- // \ \ \_\ \ __ \ \ \/\ \_\ \\ \/\ \ \ \_/\ __//\ \/\ \/\ __//\ \_\ \_\ \ \_\ \
- // \ \ ,__/ / \_\ \ \_\ \____/ \_\ \_\ \__\ \____\ \_\ \_\ \____\ \__/ \_\\ \____/
- // \ \ \/ \/_/ \/_/\/___/ \/_/\/_/\/__/\/____/\/_/\/_/\/____/\/__/\/_/ \/___/
- // \ \_\
- // \/_/ P2F - 2012 - Rubik'sCube
- // FREEWARE - Aucune diffusion commerciale basée sur ce code source
- // n'est autorisée sans autorisation préalable de l'auteur.
- // Rubik's Cube 3D Pascal Fonteneau
- // Interfaces- Fun Parts - Pascal Fonteneau and Whiler
-
- uses
- System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
- FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Types3D, FMX.Objects3D,
- FMX.Ani, FMX.Layouts, FMX.Memo, System.Math, System.StrUtils, FMX.Effects, FMX.Platform,
- FMX.Objects, FMX.ListBox, FMX.Colors;
-
- const
- FUN_LABELS : array[0..11] of string = ('Damier', 'Barre', '2 Cubes',
- '3 Cubes', 'Carré', 'Damier coloré',
- 'Plus', 'Bande', 'Diagonale',
- 'Angle', 'L', 'Tetris');
- FUN_VALUES : array[0..11] of AnsiString =
- ('OORRWWYYGGBB', 'RRGGOORRGGor', 'WWGGRRwOOYBrBrBryOOw',
- 'GGyRRyowoRByWBOGGOWW', 'gBrOYwgB', 'OORRWWYYGGBBgBrOYwgFB',
- 'RGGBBRROOWWGGBBRROOYYr', 'rGGRRbyRRWRRBBRRYRRwbRRGG', 'GBROGBROGBRO',
- 'WGGRbGoRRBgYWWrGGw', 'OBBYRbGyoRyWgRRw', 'GBROGBROGBROWWYY');
-
- ANIMATION : array[0..10] of String = ('Linear','Quadratic','Cubic','Quartic','Quintic','Sinusoidal',
- 'Exponential','Circular','Elastic','Back','Bounce');
-
- type
- TStickPosition = (PoFront, PoBack, PoTop, PoBottom, PoRight, PoLeft, PoNone);
- TDirection = (DiNone, DiLeft, DiRight, DiTop, DiBottom);
-
- TFormMain = class(TForm)
- LabelX: TLabel;
- LabelY: TLabel;
- LabelZ: TLabel;
- StyleBook1: TStyleBook;
- Viewport3D2: TViewport3D;
- CubeCentral: TCube;
- RedPivot: TCube;
- GreenPivot: TCube;
- WhitePivot: TCube;
- OrangePivot: TCube;
- BluePivot: TCube;
- YellowPivot: TCube;
- BtnRedLeft: TButton;
- BtnRedRight: TButton;
- BtnGreenLeft: TButton;
- BtnGreenRight: TButton;
- BtnWhiteLeft: TButton;
- BtnWhiteRight: TButton;
- BtnOrangeLeft: TButton;
- BtnOrangeRight: TButton;
- BtnBlueLeft: TButton;
- BtnBlueRight: TButton;
- BtnYellowLeft: TButton;
- BtnYellowRight: TButton;
- FaTurnRed: TFloatAnimation;
- FaTurnGreen: TFloatAnimation;
- FaTurnWhite: TFloatAnimation;
- FaTurnOrange: TFloatAnimation;
- FaTurnYellow: TFloatAnimation;
- Dummy: TDummy;
- Camera: TCamera;
- GbRotation: TGroupBox;
- ArcDialX: TArcDial;
- ArcDialY: TArcDial;
- ArcDialZ: TArcDial;
- FaTurnBlue: TFloatAnimation;
- CC1: TCube;
- CC2: TCube;
- CC5: TCube;
- CC3: TCube;
- CC4: TCube;
- CC6: TCube;
- CC8: TCube;
- CC7: TCube;
- CA1: TCube;
- CA2: TCube;
- CA3: TCube;
- CA4: TCube;
- CA5: TCube;
- CA6: TCube;
- CA7: TCube;
- CA8: TCube;
- CA9: TCube;
- CA10: TCube;
- CA11: TCube;
- CA12: TCube;
- PLCC1R: TPlane;
- PLCA1R: TPlane;
- PLCA2R: TPlane;
- PLCA3R: TPlane;
- PLCA4R: TPlane;
- PLCC2R: TPlane;
- PLCC3R: TPlane;
- PLCC4R: TPlane;
- PLCC5W: TPlane;
- PLCA9W: TPlane;
- PLCC6W: TPlane;
- PLCA5W: TPlane;
- PLCA6W: TPlane;
- PLCC1W: TPlane;
- PLCA1W: TPlane;
- PLCC2W: TPlane;
- PLCC2B: TPlane;
- PLCA6B: TPlane;
- PLCC6B: TPlane;
- PLCA3B: TPlane;
- PLCA11B: TPlane;
- PLCC3B: TPlane;
- PLCA7B: TPlane;
- PLCC7B: TPlane;
- PLCC5V: TPlane;
- PLCA5V: TPlane;
- PLCC1V: TPlane;
- PLCA10V: TPlane;
- PLCA2V: TPlane;
- PLCC8V: TPlane;
- PLCA8V: TPlane;
- PLCC4V: TPlane;
- PLCC4J: TPlane;
- PLCA4J: TPlane;
- PLCC3J: TPlane;
- PLCA8J: TPlane;
- PLCA7J: TPlane;
- PLCC8J: TPlane;
- PLCA12J: TPlane;
- PLCC7J: TPlane;
- PLCC6O: TPlane;
- PLCA9O: TPlane;
- PLCC5O: TPlane;
- PLCA11O: TPlane;
- PLCA10O: TPlane;
- PLCC7O: TPlane;
- PLCA12O: TPlane;
- PLCC8O: TPlane;
- GbSize: TGroupBox;
- BtnStart: TButton;
- GBFun: TGroupBox;
- LbInfoLink: TLabel;
- ShadowEffectP2F: TShadowEffect;
- cbFun: TComboBox;
- sclytCommand: TScaledLayout;
- recCommand: TRectangle;
- pbFun: TProgressBar;
- GbAnimation: TGroupBox;
- CbAnimation: TComboBox;
- tbSpeedAnim: TTrackBar;
- CPnlSpeedAnimHint: TCalloutPanel;
- txtSpeedAnimHint: TText;
- FaSpeedAnimHint: TFloatAnimation;
- TbSize: TTrackBar;
- CbRotateX: TCheckBox;
- CbRotateY: TCheckBox;
- CbRotateZ: TCheckBox;
- FaAutoRotateZ: TFloatAnimation;
- FaAutoRotateY: TFloatAnimation;
- FaAutoRotateX: TFloatAnimation;
- LbSpeedAnimation: TLabel;
- TbSpeedRotation: TTrackBar;
- CPnlSpeedRotatHint: TCalloutPanel;
- TxtSpeedRotateHint: TText;
- FaSpeedRotateHint: TFloatAnimation;
- LbSpeedRotate: TLabel;
- CpnlCubeSize: TCalloutPanel;
- TxtCubeSize: TText;
- FaCubeSize: TFloatAnimation;
- MainLight: TLight;
- GbLight: TGroupBox;
- RbAmbiance: TRadioButton;
- RbSpotLight: TRadioButton;
- BwTbLight: TBWTrackBar;
- procedure ColorBtnClick(Sender: TObject);
- procedure RotationFinish(Sender: TObject);
- procedure ArcDialXChange(Sender: TObject);
- procedure BtnStartClick(Sender: TObject);
- procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
- procedure StickCornerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
- procedure StickMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
- procedure FormCreate(Sender: TObject);
- procedure LbInfoLinkClick(Sender: TObject);
- procedure Viewport3D2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
- procedure Viewport3D2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
- procedure Viewport3D2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
- procedure StickCornerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
- RayPos, RayDir: TVector3D);
- procedure cbFunChange(Sender: TObject);
- procedure RotatePlan(Pos1, Pos2: Single; TheDirection, Di1, Di2, Di3, Di4: TDirection;
- P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12: AnsiChar);
- procedure CbAnimationChange(Sender: TObject);
- procedure tbSpeedAnimChange(Sender: TObject);
- procedure TbSizeChange(Sender: TObject);
- procedure CbRotateZChange(Sender: TObject);
- procedure CbRotateXChange(Sender: TObject);
- procedure CbRotateYChange(Sender: TObject);
- procedure TbSpeedRotationChange(Sender: TObject);
- procedure TbHorizontalChange(Sender: TObject);
- procedure RbAmbianceChange(Sender: TObject);
- procedure BwTbLightChange(Sender: TObject);
-
- private
- { Déclarations privées }
- LastDirection: ShortInt; // Sens de la dernière rotation 90 Aig -90 Inv
- Direction: TDirection; // Sens du Mvt de la souris
- ClickX: Single; // Emplacement du clic X initial
- ClickY: Single; // Emplacement du clic Y initial
- ClickXR: Single; // Emplacement du clic X Radial
- ClickYR: Single; // Emplacement du clic Y Radial
-
- MvtOn: Boolean; // Vaut Vrai lors d'un clic sur un stick
- MvtAuto: Boolean; // Vaut Vrai lors des déplacements programmés
- procedure Rotate(ThePivotAnimation: TFloatAnimation; StartValue, StepValue: Integer); overload;
- procedure Rotate(Value: AnsiChar); overload;
- procedure TurnXPlan(TheCube: TCube);
- procedure TurnYPlan(TheCube: TCube);
- procedure TurnZPlan(TheCube: TCube);
- Function GetStickPosition(TheStick: TPlane): TStickPosition;
- procedure MoveStick(TheStick: TPlane; Px, Py, Pz, Rx, Ry, Rz: Single);
- procedure PlayMvt(TheMvts: AnsiString);
- procedure SortRubik;
- procedure SortCubes;
- procedure SortCube(TheCube: TCube; Px, Py, Pz: Single);
- procedure SortSticks;
- procedure SetLight;
- // function Translate(s: string): string;
- public
- { Déclarations publiques }
-
- end;
-
- var
- FormMain: TFormMain;
-
- implementation
-
- {$R *.fmx}
-
- uses uWxPlatform;
-
- procedure TFormMain.FormCreate(Sender: TObject);
- var
- iLoop: Integer;
- begin
- MvtOn := False; // pas de mouvement de la souris en cours
- MvtAuto := False; // pas de mouvement automatique en cours
-
- // Load the arrays
- for iLoop := Low(FUN_LABELS) to High(FUN_LABELS) do
- cbFun.Items.Add(FUN_LABELS[iLoop] + ' (' + IntToStr(Length(FUN_VALUES[iLoop])) + ')');
-
- for iLoop := Low(ANIMATION) to High(ANIMATION) do
- CbAnimation.Items.Add(ANIMATION[iLoop]);
-
- CbAnimation.ItemIndex := 0;
- CbAnimation.OnChange(Self);
-
- tbSpeedAnim.Value := 1.6;
- TbSpeedRotation.Value := 11;
- TbSize.Value := 39;
- end;
-
- /// *************************************************
- /// Rubik's cube camera zoom +/-
- /// *************************************************
-
- procedure TFormMain.TbSizeChange(Sender: TObject);
- begin
- FaCubeSize.Stop;
- CpnlCubeSize.Opacity := 1;
- TxtCubeSize.Text := Format('%2.0f', [TbSize.Value + 10]);
- Camera.Position.Z := TbSize.Value - 60;
- FaCubeSize.Start;
- end;
-
- // Rotation speed
- procedure TFormMain.tbSpeedAnimChange(Sender: TObject);
- var
- speed: Single;
- begin
- FaSpeedAnimHint.Stop;
- CPnlSpeedAnimHint.Opacity := 1;
- speed := 2.1 - tbSpeedAnim.Value;
- txtSpeedAnimHint.Text := Format('%2.1f s', [speed]);
- FaTurnRed.Duration := speed;
- FaTurnGreen.Duration := speed;
- FaTurnWhite.Duration := speed;
- FaTurnOrange.Duration := speed;
- FaTurnYellow.Duration := speed;
- FaTurnBlue.Duration := speed;
- FaSpeedAnimHint.Start;
- end;
-
- // ****************************************
- // Automatic speed rotation of the cube
- // ****************************************
-
- procedure TFormMain.TbSpeedRotationChange(Sender: TObject);
- begin
- FaSpeedRotateHint.Stop;
- CPnlSpeedRotatHint.Opacity := 1;
- TxtSpeedRotateHint.Text := Format('%2.1f s', [Abs(TbSpeedRotation.Value - 22)]);
- FaAutoRotateX.Duration := 22 - TbSpeedRotation.Value;
- FaAutoRotateY.Duration := 22 - TbSpeedRotation.Value;
- FaAutoRotateZ.Duration := 22 - TbSpeedRotation.Value;
- FaSpeedRotateHint.Start;
- end;
-
- procedure TFormMain.TbHorizontalChange(Sender: TObject);
- begin
-
- end;
-
- // ******************************************************
- // Lors du changement de l'animation
- // ******************************************************
- procedure TFormMain.CbAnimationChange(Sender: TObject);
- begin
- FaTurnRed.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- FaTurnGreen.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- FaTurnWhite.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- FaTurnOrange.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- FaTurnYellow.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- FaTurnBlue.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
- end;
-
- /// *************************************************
- /// Common procedure for the click on a color button
- /// *************************************************
- procedure TFormMain.ColorBtnClick(Sender: TObject);
- begin
- cbFun.ItemIndex := -1;
- Rotate(AnsiChar((Sender as TButton).Text[1]));
- end;
-
- /// *************************************************
- /// Procedure de lancement de rotation au clavier
- /// *************************************************
- procedure TFormMain.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
- begin
- Rotate(AnsiChar(KeyChar));
- end;
-
- /// *************************************************
- /// Lance un appel au bon FloatAnimation et boucle en
- /// Attendant la fin de l'animation
- /// *************************************************
- procedure TFormMain.Rotate(Value: AnsiChar);
- begin
- case Value of
- 'r': Rotate(FaTurnRed, 360, 270);
- 'R': Rotate(FaTurnRed, 0, 90);
- 'o': Rotate(FaTurnOrange, 0, 90);
- 'O': Rotate(FaTurnOrange, 360, 270);
- 'y': Rotate(FaTurnYellow, 0, 90);
- 'Y': Rotate(FaTurnYellow, 360, 270);
- 'b': Rotate(FaTurnBlue, 0, 90);
- 'B': Rotate(FaTurnBlue, 360, 270);
- 'g': Rotate(FaTurnGreen, 360, 270);
- 'G': Rotate(FaTurnGreen, 0, 90);
- 'w': Rotate(FaTurnWhite, 360, 270);
- 'W': Rotate(FaTurnWhite, 0, 90);
- end;
- end;
-
- /// *****************************************************
- /// Rechercher les cubes Coins et Arretes situés sur le
- /// même plan que le cube allant pivoter et en faire ses
- /// enfants.
- /// Puis, lancement de l'animation ROTATION
- /// *****************************************************
- procedure TFormMain.Rotate(ThePivotAnimation: TFloatAnimation; StartValue, StepValue: Integer);
- var
- I: Integer;
- begin
- recCommand.Enabled := False; // desactiver le panneau de commandes
-
- // récuperation du sens de la rotation
- LastDirection := 90; // sens des aiguilles d'une montre pour 90 degres
- if StartValue = 360 then
- LastDirection := -90; // sens trigo
-
- // Lier les cubes Coins et Arretes au cube allant pivoter
- for I := 0 to FormMain.ComponentCount - 1 do
- begin
- if (FormMain.Components[I] Is TCube) then
- begin
- if ((FormMain.Components[I] As TCube).Tag = 2) or ((FormMain.Components[I] As TCube).Tag = 3) then
- begin
- // Red plan
- if (SameValue((FormMain.Components[I] As TCube).Position.Z, -3, 0.1)) and (ThePivotAnimation = FaTurnRed) then
- begin
- (FormMain.Components[I] As TCube).Parent := RedPivot;
- (FormMain.Components[I] As TCube).Position.Z := 0;
- end;
- // Orange plan
- if (SameValue((FormMain.Components[I] As TCube).Position.Z, 3, 0.1)) and (ThePivotAnimation = FaTurnOrange) then
- begin
- (FormMain.Components[I] As TCube).Parent := OrangePivot;
- (FormMain.Components[I] As TCube).Position.Z := 0;
- end;
- // Green plan
- if (SameValue((FormMain.Components[I] As TCube).Position.X, -3, 0.1)) and (ThePivotAnimation = FaTurnGreen) then
- begin
- (FormMain.Components[I] As TCube).Parent := GreenPivot;
- (FormMain.Components[I] As TCube).Position.X := 0;
- end;
- // Blue plan
- if (SameValue((FormMain.Components[I] As TCube).Position.X, 3, 0.1)) and (ThePivotAnimation = FaTurnBlue) then
- begin
- (FormMain.Components[I] As TCube).Parent := BluePivot;
- (FormMain.Components[I] As TCube).Position.X := 0;
- end;
- // White plan
- if (SameValue((FormMain.Components[I] As TCube).Position.Y, -3, 0.1)) and (ThePivotAnimation = FaTurnWhite) then
- begin
- (FormMain.Components[I] As TCube).Parent := WhitePivot;
- (FormMain.Components[I] As TCube).Position.Y := 0;
- end;
- // Yellow plan
- if (SameValue((FormMain.Components[I] As TCube).Position.Y, 3, 0.1)) and (ThePivotAnimation = FaTurnYellow) then
- begin
- (FormMain.Components[I] As TCube).Parent := YellowPivot;
- (FormMain.Components[I] As TCube).Position.Y := 0;
- end;
- end; // si cube Coin ou cuble arrete
- end; // si un cube
- end; // du for
-
- // Valuer et lancer l'animation
- ThePivotAnimation.StartValue := StartValue;
- ThePivotAnimation.StopValue := StepValue;
- ThePivotAnimation.Start;
- while ThePivotAnimation.Running do Application.ProcessMessages;
- end;
-
- /// *************************************************
- /// En fin d'animation ROTATION le cube ayant pivoté
- // rend au cube central les enfants
- /// *************************************************
- procedure TFormMain.RotationFinish(Sender: TObject);
- Var
- I: Integer;
- TmpX, TmpY, TmpZ: Single;
- ThePlan: TCube;
- begin
- for I := 0 to FormMain.ComponentCount - 1 do
- begin
- if (FormMain.Components[I] Is TCube) then
- begin
- if ((FormMain.Components[I] As TCube).Tag = 2) or ((FormMain.Components[I] As TCube).Tag = 3) then
- begin
- if (FormMain.Components[I] As TCube).Parent <> CubeCentral then
- begin
- TmpX := (FormMain.Components[I] As TCube).AbsolutePosition.X;
- TmpY := (FormMain.Components[I] As TCube).AbsolutePosition.Y;
- TmpZ := (FormMain.Components[I] As TCube).AbsolutePosition.Z;
- ThePlan := TCube((FormMain.Components[I] As TCube).Parent);
- (FormMain.Components[I] As TCube).Position.X := TmpX;
- (FormMain.Components[I] As TCube).Position.Y := TmpY;
- (FormMain.Components[I] As TCube).Position.Z := TmpZ;
- (FormMain.Components[I] As TCube).Parent := CubeCentral;
-
- // plan Rouge (plan Z)
- if ThePlan = RedPivot then
- begin
- (FormMain.Components[I] As TCube).Position.Z := -3;
- TurnZPlan((FormMain.Components[I] As TCube));
- end;
-
- // plan Orange (Plan Z)
- if ThePlan = OrangePivot then
- begin
- (FormMain.Components[I] As TCube).Position.Z := 3;
- TurnZPlan((FormMain.Components[I] As TCube));
- end;
-
- // plan bleu (Plan X)
- if ThePlan = BluePivot then
- begin
- (FormMain.Components[I] As TCube).Position.X := 3;
- TurnXPlan((FormMain.Components[I] As TCube));
- end;
-
- // plan Vert (Plan X)
- if ThePlan = GreenPivot then
- begin
- (FormMain.Components[I] As TCube).Position.X := -3;
- TurnXPlan((FormMain.Components[I] As TCube));
- end;
-
- // plan Blanc (Plan Y)
- if ThePlan = WhitePivot then
- begin
- (FormMain.Components[I] As TCube).Position.Y := -3;
- TurnYPlan((FormMain.Components[I] As TCube));
- end;
-
- // plan Jaune (Plan Y)
- if ThePlan = YellowPivot then
- begin
- (FormMain.Components[I] As TCube).Position.Y := 3;
- TurnYPlan((FormMain.Components[I] As TCube));
- end;
- end;
- end;
- end;
- if not MvtAuto then
- recCommand.Enabled := True; // le panneau de commande redevient actif
- end;
- end;
-
- /// *************************************************
- /// Renvoi la position (le plan ) d'un stick
- /// *************************************************
- Function TFormMain.GetStickPosition(TheStick: TPlane): TStickPosition;
- begin
- Result := PoNone;
- if SameValue(TheStick.Position.Y, -1.51, 0.1) then
- Result := PoTop;
- if SameValue(TheStick.Position.Y, 1.51, 0.1) then
- Result := PoBottom;
- if SameValue(TheStick.Position.X, -1.51, 0.1) then
- Result := PoLeft;
- if SameValue(TheStick.Position.X, 1.51, 0.1) then
- Result := PoRight;
- if SameValue(TheStick.Position.Z, 1.51, 0.1) then
- Result := PoBack;
- if SameValue(TheStick.Position.Z, -1.51, 0.1) then
- Result := PoFront;
- end;
-
- /// *************************************************
- /// Place (colle) un stick sur un plan des 6 plans
- /// du cube
- /// ************************************************
- procedure TFormMain.MoveStick(TheStick: TPlane; Px, Py, Pz, Rx, Ry, Rz: Single);
- begin
- TheStick.ResetRotationAngle; // Remise à zero des angles de rotation IMPORTANT
- TheStick.Position.X := Px;
- TheStick.Position.Y := Py;
- TheStick.Position.Z := Pz;
- TheStick.RotationAngle.X := Rx;
- TheStick.RotationAngle.Y := Ry;
- TheStick.RotationAngle.Z := Rz;
- end;
-
- /// **********************************************
- /// Pour le plan Z ( Rouge et Orange)
- /// En fonction du dernier sens de rotation
- /// replace les sticks sur la bonne facette
- /// **********************************************
- procedure TFormMain.TurnZPlan(TheCube: TCube);
- var
- I: Integer;
- begin
- for I := 0 to TheCube.ChildrenCount - 1 do
- begin
- if LastDirection = 90 then // sens des aiguilles
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
- MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
- MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0) // Up
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
- MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0); // Down
-
- end
- else
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
- MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0) // Down
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
- MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
- MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0); // Up
- end;
- end;
- end;
-
- /// / **********************************************
- /// Idem, pour le plan X ( Bleu et vert)
- /// / **********************************************
- procedure TFormMain.TurnXPlan(TheCube: TCube);
- var
- I: Integer;
- begin
- for I := 0 to TheCube.ChildrenCount - 1 do
- begin
- if LastDirection = 90 then // sens INVERSE des aiguilles
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
- MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0) // Up
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0); // Down
- end
- else
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0) // Down
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
- MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0); // Up
- end;
- end;
- end;
-
- /// **********************************************
- /// Idem, pour le plan Y ( Blanc et Jaune)
- /// **********************************************
- procedure TFormMain.TurnYPlan(TheCube: TCube);
- var
- I: Integer;
- begin
- for I := 0 to TheCube.ChildrenCount - 1 do
- begin
- if LastDirection = 90 then // sens des aiguilles
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
- MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
- MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0); // Front
-
- end
- else
- begin
- if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
- MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
- MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
- else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
- MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0); // Back
- end;
- end;
- end;
-
- {$REGION 'Jeu à la souris'}
-
- /// **********************************************
- /// en cliquant sur un stick on arme la recherche
- /// d'un mouvement
- /// **********************************************
- procedure TFormMain.StickMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
- RayPos, RayDir: TVector3D);
- begin
- if MvtAuto then
- Exit;
- ClickXR := RayDir.X; // emplacement du clic en X Radial
- ClickYR := RayDir.Y; // emplacement du clic en Y Radial
- MvtOn := True;
- end;
-
- /// **********************************************
- /// En cliquant sur le fond on arme la rotation
- /// du cube
- /// **********************************************
- procedure TFormMain.Viewport3D2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
- begin
- ClickX := X; // emplacement du clic en X
- ClickY := Y; // emplacement du clic en Y
- end;
-
- /// **********************************************
- /// le deplacement de la souris fait pivoter le cube
- /// **********************************************
- procedure TFormMain.Viewport3D2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
- begin
- IF MvtOn then
- Exit;
- if ssLeft in Shift then // si la souris bouge avec le clic droit enfoncé
- begin
- Direction := DiNone;
- IF (ClickX - X) > 3 then
- Direction := DiLeft;
- IF (X - ClickX) > 3 then
- Direction := DiRight;
- IF (ClickY - Y) > 3 then
- Direction := DiTop;
- IF (Y - ClickY) > 3 then
- Direction := DiBottom;
-
- if Direction <> DiNone then // une direction a été trouvée
- begin
- ClickX := X;
- ClickY := Y;
- if Direction = DiBottom then
- ArcDialX.Value := ArcDialX.Value - 5;
- if Direction = DiTop then
- ArcDialX.Value := ArcDialX.Value + 5;
- if Direction = DiLeft then
- ArcDialY.Value := ArcDialY.Value - 5;
- if Direction = DiRight then
- ArcDialY.Value := ArcDialY.Value + 5;
- ArcDialXChange(Self);
- end;
- end;
- end;
-
- /// **********************************************
- /// Desarmement du mouvement
- /// **********************************************
- procedure TFormMain.Viewport3D2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
- begin
- MvtOn := False;
- end;
-
- procedure TFormMain.StickCornerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
- RayPos, RayDir: TVector3D);
- begin
- MvtOn := False;
- end;
-
- procedure TFormMain.StickCornerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
- var
- PosXCube, PosYCube, PosZCube: int64;
- begin
- if not MvtOn then
- Exit; // si pas de mouvement d'armé
-
- if ssLeft in Shift then // si la souris bouge avec le clic droit enfoncé
- begin
- Direction := DiNone;
- IF (ClickXR - RayDir.X) > 0.02 then
- Direction := DiLeft;
- IF (RayDir.X - ClickXR) > 0.02 then
- Direction := DiRight;
- IF (ClickYR - RayDir.Y) > 0.02 then
- Direction := DiTop;
- IF (RayDir.Y - ClickYR) > 0.02 then
- Direction := DiBottom;
-
- if Direction <> DiNone then // une direction a été trouvée
- begin
- cbFun.ItemIndex := -1;
- // recup de la position XYU du cube sous le stick
- PosXCube := Round(((Sender as TPlane).Parent as TCube).Position.X);
- PosYCube := Round(((Sender as TPlane).Parent as TCube).Position.Y);
- PosZCube := Round(((Sender as TPlane).Parent as TCube).Position.Z);
- // desarment du mouvement et reinitialisation de l'emplacement de la souris
- MvtOn := False;
- ClickXR := RayDir.X;
- ClickYR := RayDir.Y;
- if (PosZCube = -3) and (SameValue((Sender as TPlane).Position.Z, -1.51, 0.1)) then // Plan Avant Rouge
- RotatePlan(PosXCube, PosYCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'w', 'W', 'Y', 'y', 'B', 'b', 'w',
- 'W', 'Y', 'y')
- else if (PosZCube = 3) and (SameValue((Sender as TPlane).Position.Z, 1.51, 0.1)) then // Plan Arriere Orange
- RotatePlan(PosXCube, PosYCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'W', 'w', 'y', 'Y', 'B', 'b', 'W',
- 'w', 'y', 'Y')
- else if (PosYCube = -3) and (SameValue((Sender as TPlane).Position.Y, -1.51, 0.1)) then // Plan Haut Blanc
- RotatePlan(PosXCube, PosZCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'R', 'r', 'o', 'O', 'B', 'b', 'R',
- 'r', 'o', 'O')
- else if (PosYCube = 3) and (SameValue((Sender as TPlane).Position.Y, 1.51, 0.1)) then // Plan Bas Jaune
- RotatePlan(PosXCube, PosZCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'r', 'R', 'O', 'o', 'B', 'b', 'r',
- 'R', 'O', 'o')
- else if (PosXCube = -3) and (SameValue((Sender as TPlane).Position.X, -1.51, 0.1)) then // Plan Gauche Vert
- RotatePlan(PosYCube, PosZCube, Direction, DiRight, DiLeft, DiBottom, DiTop, 'w', 'W', 'r', 'R', 'O', 'o', 'Y', 'y', 'r',
- 'R', 'O', 'o')
- else if (PosXCube = 3) and (SameValue((Sender as TPlane).Position.X, 1.51, 0.1)) then // Plan Droit Bleu
- RotatePlan(PosYCube, PosZCube, Direction, DiRight, DiLeft, DiBottom, DiTop, 'w', 'W', 'R', 'r', 'o', 'O', 'Y', 'y', 'R',
- 'r', 'o', 'O');
- end;
- end;
- end;
-
- procedure TFormMain.RotatePlan(Pos1, Pos2: Single; TheDirection, Di1, Di2, Di3, Di4: TDirection;
- P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12: AnsiChar);
- begin
- if Pos1 = -3 then
- begin
- if (TheDirection = Di1) then
- Rotate(P1);
- if (TheDirection = Di2) then
- Rotate(P2);
- if Pos2 = -3 then
- begin
- if (TheDirection = Di3) then
- Rotate(P3);
- if (TheDirection = Di4) then
- Rotate(P4);
- end
- else
- begin
- if (TheDirection = Di3) then
- Rotate(P5);
- if (TheDirection = Di4) then
- Rotate(P6);
- end;
- end
- else
- begin // coté bas
- if (TheDirection = Di1) then
- Rotate(P7);
- if (TheDirection = Di2) then
- Rotate(P8);
- if Pos2 = -3 then
- begin
- if (TheDirection = Di3) then
- Rotate(P9);
- if (TheDirection = Di4) then
- Rotate(P10);
- end
- else
- begin
- if (TheDirection = Di3) then
- Rotate(P11);
- if (TheDirection = Di4) then
- Rotate(P12);
- end;
- end;
- end;
-
- {$ENDREGION}
- {$REGION 'Sort the cube (not solving)'}
-
- procedure TFormMain.BtnStartClick(Sender: TObject);
- begin
- if MessageDlg('Restore initial cube?', TMsgDlgType.mtInformation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0) = MrNo then
- Exit;
- SortRubik();
- CbRotateX.IsChecked := False;
- CbRotateY.IsChecked := False;
- CbRotateZ.IsChecked := False;
- ArcDialX.Value := -35;
- ArcDialY.Value := -45;
- ArcDialZ.Value := -18;
- cbFun.ItemIndex := -1;
- ArcDialXChange(Self);
- end;
-
- procedure TFormMain.SortRubik();
- begin
- SortCubes();
- SortSticks();
- end;
-
- procedure TFormMain.SortSticks();
- begin
- // face Rouge
- MoveStick( PLCC1R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCC2R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCC4R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCC3R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCA1R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCA2R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCA3R, 0, 0, -1.51, 0, 0, 0);
- MoveStick( PLCA4R, 0, 0, -1.51, 0, 0, 0);
- // Face Bleu
- MoveStick( PLCC2B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCC6B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCC3B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCC7B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCA6B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCA3B, 1.51, 0, 0, 0, -90, 0);
- MoveStick(PLCA11B, 1.51, 0, 0, 0, -90, 0);
- MoveStick( PLCA7B, 1.51, 0, 0, 0, -90, 0);
- // Face Verte
- MoveStick( PLCC5V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCC1V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCC8V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCC4V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCA5V, -1.51, 0, 0, 0, 90, 0);
- MoveStick(PLCA10V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCA8V, -1.51, 0, 0, 0, 90, 0);
- MoveStick( PLCA2V, -1.51, 0, 0, 0, 90, 0);
- // Orange
- MoveStick( PLCC6O, 0, 0, 1.51, 180, 0, 0);
- MoveStick( PLCC5O, 0, 0, 1.51, 180, 0, 0);
- MoveStick( PLCC7O, 0, 0, 1.51, 180, 0, 0);
- MoveStick( PLCC8O, 0, 0, 1.51, 180, 0, 0);
- MoveStick( PLCA9O, 0, 0, 1.51, 180, 0, 0);
- MoveStick(PLCA11O, 0, 0, 1.51, 180, 0, 0);
- MoveStick(PLCA10O, 0, 0, 1.51, 180, 0, 0);
- MoveStick(PLCA12O, 0, 0, 1.51, 180, 0, 0);
- // Face Blanche
- MoveStick( PLCC5W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCC6W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCC1W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCC2W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCA9W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCA5W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCA6W, 0, -1.51, 0, -90, 0, 0);
- MoveStick( PLCA1W, 0, -1.51, 0, -90, 0, 0);
- // Face Jaune
- MoveStick( PLCC4J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCC3J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCC8J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCC7J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCA4J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCA8J, 0, 1.51, 0, 90, 0, 0);
- MoveStick( PLCA7J, 0, 1.51, 0, 90, 0, 0);
- MoveStick(PLCA12J, 0, 1.51, 0, 90, 0, 0);
- end;
-
- procedure TFormMain.SortCubes();
- begin
- // les cubes coins
- SortCube( CC1, -3, -3, -3);
- SortCube( CC2, 3, -3, -3);
- SortCube( CC3, 3, 3, -3);
- SortCube( CC4, -3, 3, -3);
- SortCube( CC5, -3, -3, 3);
- SortCube( CC6, 3, -3, 3);
- SortCube( CC7, 3, 3, 3);
- SortCube( CC8, -3, 3, 3);
- // les cubes arretes
- SortCube( CA1, 0, -3, -3);
- SortCube( CA2, -3, 0, -3);
- SortCube( CA3, 3, 0, -3);
- SortCube( CA4, 0, 3, -3);
- SortCube( CA5, -3, -3, 0);
- SortCube( CA6, 3, -3, 0);
- SortCube( CA7, 3, 3, 0);
- SortCube( CA8, -3, 3, 0);
- SortCube( CA9, 0, -3, 3);
- SortCube(CA10, -3, 0, 3);
- SortCube(CA11, 3, 0, 3);
- SortCube(CA12, 0, 3, 3);
- end;
-
- procedure TFormMain.SortCube(TheCube: TCube; Px, Py, Pz: Single);
- begin
- TheCube.ResetRotationAngle;
- TheCube.Position.X := Px;
- TheCube.Position.Y := Py;
- TheCube.Position.Z := Pz;
- end;
-
- {$ENDREGION}
- {$REGION 'Jouer des mouvements enregistrés'}
-
- procedure TFormMain.cbFunChange(Sender: TObject);
- begin
- if cbFun.ItemIndex <> -1 then
- begin
- cbFun.DropDown; // Pour refermer immédiatement la dropdown
- SortRubik();
- PlayMvt(FUN_VALUES[cbFun.ItemIndex]);
- end;
- end;
-
- procedure TFormMain.PlayMvt(TheMvts: AnsiString);
- var
- I: Integer;
- iMax: Integer;
- begin
- // Platform.SetCursor(nil, crHourGlass); // ProcessMessages casse le curseur
- MvtAuto := True; // On enchaine une série (l'utilisateur ne peut pas faire de modif manuelle)
- iMax := Length(TheMvts);
- pbFun.Value := 1;
- pbFun.Max := iMax;
- pbFun.Visible := True;
- recCommand.Enabled := False; // desactiver le panneau de commandes
- for I := 1 to iMax do
- begin
- Rotate(TheMvts[I]);
- pbFun.Value := pbFun.Value + 1;
- end;
- MvtAuto := False; // La série est terminée, l'utilisateur peut à nouveau jouer
- pbFun.Visible := False;
- recCommand.Enabled := True; // le panneau de commande redevient actif
- end;
-
- {$ENDREGION}
- {$REGION 'Ouverture de la page Web'}
-
- procedure TFormMain.LbInfoLinkClick(Sender: TObject);
- begin
- TMisc.Open((Sender as TLabel).Text);
- end;
- {$ENDREGION}
- {$REGION 'Rotation automatique du cube'}
-
- /// *************************************************
- /// Déplacement de la caméra autour du rubik's cube
- /// *************************************************
- Procedure TFormMain.ArcDialXChange(Sender: TObject);
- begin
- Dummy.RotationAngle.X := ArcDialX.Value;
- Dummy.RotationAngle.Y := ArcDialY.Value;
- Dummy.RotationAngle.Z := ArcDialZ.Value;
- end;
-
- Procedure TFormMain.CbRotateXChange(Sender: TObject);
- begin
- FaAutoRotateX.Stop;
- if CbRotateX.IsChecked then
- FaAutoRotateX.Start;
- end;
-
- Procedure TFormMain.CbRotateYChange(Sender: TObject);
- begin
- FaAutoRotateY.Stop;
- if CbRotateY.IsChecked then
- FaAutoRotateY.Start;
- end;
-
- Procedure TFormMain.CbRotateZChange(Sender: TObject);
- begin
- FaAutoRotateZ.Stop;
- if CbRotateZ.IsChecked then
- FaAutoRotateZ.Start;
- end;
- {$ENDREGION}
- {$REGION 'Les lumières'}
-
- procedure TFormMain.RbAmbianceChange(Sender: TObject);
- Var
- I: Integer;
- Color: TAlphaColor;
- begin
- MainLight.Enabled := RbSpotLight.IsChecked;
- BwTbLight.Enabled := RbSpotLight.IsChecked;
-
- if RbSpotLight.IsChecked then
- begin
- Color := claNull;
- SetLight;
- end
- else
- Color := claWhite;
- for I := 0 to FormMain.ComponentCount - 1 do
- begin
- // les stickers
- if (FormMain.Components[I] Is TPlane) then
- (FormMain.Components[I] As TPlane).material.Emissive := Color;
- // Les cubes pivots
- if (FormMain.Components[I] Is TCube) then
- if (FormMain.Components[I] As TCube).Tag = 1 then
- (FormMain.Components[I] As TCube).material.Emissive := Color;
- end;
- end;
-
- procedure TFormMain.SetLight;
- var
- cLight: TAlphaColorRec;
- begin
- cLight.R := Round(255 * BwTbLight.Value);
- cLight.G := Round(255 * BwTbLight.Value);
- cLight.B := Round(255 * BwTbLight.Value);
- MainLight.Diffuse := cLight.Color;
- Viewport3D2.Repaint;
- end;
-
- procedure TFormMain.BwTbLightChange(Sender: TObject);
- begin
- SetLight;
- end;
-
- {$ENDREGION}
-
- end.
unit UMain;
interface
// ______ __
// /\ ___\ /\ \__
// _____ \ \ \__/ ___ ___\ \ ,_\ __ ___ __ __ __ __
// /\ '__`\ \ \ _\/ __`\/' _ `\ \ \/ /'__`\/' _ `\ /'__`\ /'__`\ /\ \/\ \
// \ \ \_\ \ __ \ \ \/\ \_\ \\ \/\ \ \ \_/\ __//\ \/\ \/\ __//\ \_\ \_\ \ \_\ \
// \ \ ,__/ / \_\ \ \_\ \____/ \_\ \_\ \__\ \____\ \_\ \_\ \____\ \__/ \_\\ \____/
// \ \ \/ \/_/ \/_/\/___/ \/_/\/_/\/__/\/____/\/_/\/_/\/____/\/__/\/_/ \/___/
// \ \_\
// \/_/ P2F - 2012 - Rubik'sCube
// FREEWARE - Aucune diffusion commerciale basée sur ce code source
// n'est autorisée sans autorisation préalable de l'auteur.
// Rubik's Cube 3D Pascal Fonteneau
// Interfaces- Fun Parts - Pascal Fonteneau and Whiler
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Types3D, FMX.Objects3D,
FMX.Ani, FMX.Layouts, FMX.Memo, System.Math, System.StrUtils, FMX.Effects, FMX.Platform,
FMX.Objects, FMX.ListBox, FMX.Colors;
const
FUN_LABELS : array[0..11] of string = ('Damier', 'Barre', '2 Cubes',
'3 Cubes', 'Carré', 'Damier coloré',
'Plus', 'Bande', 'Diagonale',
'Angle', 'L', 'Tetris');
FUN_VALUES : array[0..11] of AnsiString =
('OORRWWYYGGBB', 'RRGGOORRGGor', 'WWGGRRwOOYBrBrBryOOw',
'GGyRRyowoRByWBOGGOWW', 'gBrOYwgB', 'OORRWWYYGGBBgBrOYwgFB',
'RGGBBRROOWWGGBBRROOYYr', 'rGGRRbyRRWRRBBRRYRRwbRRGG', 'GBROGBROGBRO',
'WGGRbGoRRBgYWWrGGw', 'OBBYRbGyoRyWgRRw', 'GBROGBROGBROWWYY');
ANIMATION : array[0..10] of String = ('Linear','Quadratic','Cubic','Quartic','Quintic','Sinusoidal',
'Exponential','Circular','Elastic','Back','Bounce');
type
TStickPosition = (PoFront, PoBack, PoTop, PoBottom, PoRight, PoLeft, PoNone);
TDirection = (DiNone, DiLeft, DiRight, DiTop, DiBottom);
TFormMain = class(TForm)
LabelX: TLabel;
LabelY: TLabel;
LabelZ: TLabel;
StyleBook1: TStyleBook;
Viewport3D2: TViewport3D;
CubeCentral: TCube;
RedPivot: TCube;
GreenPivot: TCube;
WhitePivot: TCube;
OrangePivot: TCube;
BluePivot: TCube;
YellowPivot: TCube;
BtnRedLeft: TButton;
BtnRedRight: TButton;
BtnGreenLeft: TButton;
BtnGreenRight: TButton;
BtnWhiteLeft: TButton;
BtnWhiteRight: TButton;
BtnOrangeLeft: TButton;
BtnOrangeRight: TButton;
BtnBlueLeft: TButton;
BtnBlueRight: TButton;
BtnYellowLeft: TButton;
BtnYellowRight: TButton;
FaTurnRed: TFloatAnimation;
FaTurnGreen: TFloatAnimation;
FaTurnWhite: TFloatAnimation;
FaTurnOrange: TFloatAnimation;
FaTurnYellow: TFloatAnimation;
Dummy: TDummy;
Camera: TCamera;
GbRotation: TGroupBox;
ArcDialX: TArcDial;
ArcDialY: TArcDial;
ArcDialZ: TArcDial;
FaTurnBlue: TFloatAnimation;
CC1: TCube;
CC2: TCube;
CC5: TCube;
CC3: TCube;
CC4: TCube;
CC6: TCube;
CC8: TCube;
CC7: TCube;
CA1: TCube;
CA2: TCube;
CA3: TCube;
CA4: TCube;
CA5: TCube;
CA6: TCube;
CA7: TCube;
CA8: TCube;
CA9: TCube;
CA10: TCube;
CA11: TCube;
CA12: TCube;
PLCC1R: TPlane;
PLCA1R: TPlane;
PLCA2R: TPlane;
PLCA3R: TPlane;
PLCA4R: TPlane;
PLCC2R: TPlane;
PLCC3R: TPlane;
PLCC4R: TPlane;
PLCC5W: TPlane;
PLCA9W: TPlane;
PLCC6W: TPlane;
PLCA5W: TPlane;
PLCA6W: TPlane;
PLCC1W: TPlane;
PLCA1W: TPlane;
PLCC2W: TPlane;
PLCC2B: TPlane;
PLCA6B: TPlane;
PLCC6B: TPlane;
PLCA3B: TPlane;
PLCA11B: TPlane;
PLCC3B: TPlane;
PLCA7B: TPlane;
PLCC7B: TPlane;
PLCC5V: TPlane;
PLCA5V: TPlane;
PLCC1V: TPlane;
PLCA10V: TPlane;
PLCA2V: TPlane;
PLCC8V: TPlane;
PLCA8V: TPlane;
PLCC4V: TPlane;
PLCC4J: TPlane;
PLCA4J: TPlane;
PLCC3J: TPlane;
PLCA8J: TPlane;
PLCA7J: TPlane;
PLCC8J: TPlane;
PLCA12J: TPlane;
PLCC7J: TPlane;
PLCC6O: TPlane;
PLCA9O: TPlane;
PLCC5O: TPlane;
PLCA11O: TPlane;
PLCA10O: TPlane;
PLCC7O: TPlane;
PLCA12O: TPlane;
PLCC8O: TPlane;
GbSize: TGroupBox;
BtnStart: TButton;
GBFun: TGroupBox;
LbInfoLink: TLabel;
ShadowEffectP2F: TShadowEffect;
cbFun: TComboBox;
sclytCommand: TScaledLayout;
recCommand: TRectangle;
pbFun: TProgressBar;
GbAnimation: TGroupBox;
CbAnimation: TComboBox;
tbSpeedAnim: TTrackBar;
CPnlSpeedAnimHint: TCalloutPanel;
txtSpeedAnimHint: TText;
FaSpeedAnimHint: TFloatAnimation;
TbSize: TTrackBar;
CbRotateX: TCheckBox;
CbRotateY: TCheckBox;
CbRotateZ: TCheckBox;
FaAutoRotateZ: TFloatAnimation;
FaAutoRotateY: TFloatAnimation;
FaAutoRotateX: TFloatAnimation;
LbSpeedAnimation: TLabel;
TbSpeedRotation: TTrackBar;
CPnlSpeedRotatHint: TCalloutPanel;
TxtSpeedRotateHint: TText;
FaSpeedRotateHint: TFloatAnimation;
LbSpeedRotate: TLabel;
CpnlCubeSize: TCalloutPanel;
TxtCubeSize: TText;
FaCubeSize: TFloatAnimation;
MainLight: TLight;
GbLight: TGroupBox;
RbAmbiance: TRadioButton;
RbSpotLight: TRadioButton;
BwTbLight: TBWTrackBar;
procedure ColorBtnClick(Sender: TObject);
procedure RotationFinish(Sender: TObject);
procedure ArcDialXChange(Sender: TObject);
procedure BtnStartClick(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
procedure StickCornerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
procedure StickMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
procedure FormCreate(Sender: TObject);
procedure LbInfoLinkClick(Sender: TObject);
procedure Viewport3D2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
procedure Viewport3D2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
procedure Viewport3D2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
procedure StickCornerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
RayPos, RayDir: TVector3D);
procedure cbFunChange(Sender: TObject);
procedure RotatePlan(Pos1, Pos2: Single; TheDirection, Di1, Di2, Di3, Di4: TDirection;
P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12: AnsiChar);
procedure CbAnimationChange(Sender: TObject);
procedure tbSpeedAnimChange(Sender: TObject);
procedure TbSizeChange(Sender: TObject);
procedure CbRotateZChange(Sender: TObject);
procedure CbRotateXChange(Sender: TObject);
procedure CbRotateYChange(Sender: TObject);
procedure TbSpeedRotationChange(Sender: TObject);
procedure TbHorizontalChange(Sender: TObject);
procedure RbAmbianceChange(Sender: TObject);
procedure BwTbLightChange(Sender: TObject);
private
{ Déclarations privées }
LastDirection: ShortInt; // Sens de la dernière rotation 90 Aig -90 Inv
Direction: TDirection; // Sens du Mvt de la souris
ClickX: Single; // Emplacement du clic X initial
ClickY: Single; // Emplacement du clic Y initial
ClickXR: Single; // Emplacement du clic X Radial
ClickYR: Single; // Emplacement du clic Y Radial
MvtOn: Boolean; // Vaut Vrai lors d'un clic sur un stick
MvtAuto: Boolean; // Vaut Vrai lors des déplacements programmés
procedure Rotate(ThePivotAnimation: TFloatAnimation; StartValue, StepValue: Integer); overload;
procedure Rotate(Value: AnsiChar); overload;
procedure TurnXPlan(TheCube: TCube);
procedure TurnYPlan(TheCube: TCube);
procedure TurnZPlan(TheCube: TCube);
Function GetStickPosition(TheStick: TPlane): TStickPosition;
procedure MoveStick(TheStick: TPlane; Px, Py, Pz, Rx, Ry, Rz: Single);
procedure PlayMvt(TheMvts: AnsiString);
procedure SortRubik;
procedure SortCubes;
procedure SortCube(TheCube: TCube; Px, Py, Pz: Single);
procedure SortSticks;
procedure SetLight;
// function Translate(s: string): string;
public
{ Déclarations publiques }
end;
var
FormMain: TFormMain;
implementation
{$R *.fmx}
uses uWxPlatform;
procedure TFormMain.FormCreate(Sender: TObject);
var
iLoop: Integer;
begin
MvtOn := False; // pas de mouvement de la souris en cours
MvtAuto := False; // pas de mouvement automatique en cours
// Load the arrays
for iLoop := Low(FUN_LABELS) to High(FUN_LABELS) do
cbFun.Items.Add(FUN_LABELS[iLoop] + ' (' + IntToStr(Length(FUN_VALUES[iLoop])) + ')');
for iLoop := Low(ANIMATION) to High(ANIMATION) do
CbAnimation.Items.Add(ANIMATION[iLoop]);
CbAnimation.ItemIndex := 0;
CbAnimation.OnChange(Self);
tbSpeedAnim.Value := 1.6;
TbSpeedRotation.Value := 11;
TbSize.Value := 39;
end;
/// *************************************************
/// Rubik's cube camera zoom +/-
/// *************************************************
procedure TFormMain.TbSizeChange(Sender: TObject);
begin
FaCubeSize.Stop;
CpnlCubeSize.Opacity := 1;
TxtCubeSize.Text := Format('%2.0f', [TbSize.Value + 10]);
Camera.Position.Z := TbSize.Value - 60;
FaCubeSize.Start;
end;
// Rotation speed
procedure TFormMain.tbSpeedAnimChange(Sender: TObject);
var
speed: Single;
begin
FaSpeedAnimHint.Stop;
CPnlSpeedAnimHint.Opacity := 1;
speed := 2.1 - tbSpeedAnim.Value;
txtSpeedAnimHint.Text := Format('%2.1f s', [speed]);
FaTurnRed.Duration := speed;
FaTurnGreen.Duration := speed;
FaTurnWhite.Duration := speed;
FaTurnOrange.Duration := speed;
FaTurnYellow.Duration := speed;
FaTurnBlue.Duration := speed;
FaSpeedAnimHint.Start;
end;
// ****************************************
// Automatic speed rotation of the cube
// ****************************************
procedure TFormMain.TbSpeedRotationChange(Sender: TObject);
begin
FaSpeedRotateHint.Stop;
CPnlSpeedRotatHint.Opacity := 1;
TxtSpeedRotateHint.Text := Format('%2.1f s', [Abs(TbSpeedRotation.Value - 22)]);
FaAutoRotateX.Duration := 22 - TbSpeedRotation.Value;
FaAutoRotateY.Duration := 22 - TbSpeedRotation.Value;
FaAutoRotateZ.Duration := 22 - TbSpeedRotation.Value;
FaSpeedRotateHint.Start;
end;
procedure TFormMain.TbHorizontalChange(Sender: TObject);
begin
end;
// ******************************************************
// Lors du changement de l'animation
// ******************************************************
procedure TFormMain.CbAnimationChange(Sender: TObject);
begin
FaTurnRed.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
FaTurnGreen.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
FaTurnWhite.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
FaTurnOrange.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
FaTurnYellow.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
FaTurnBlue.Interpolation := TInterpolationType(CbAnimation.ItemIndex);
end;
/// *************************************************
/// Common procedure for the click on a color button
/// *************************************************
procedure TFormMain.ColorBtnClick(Sender: TObject);
begin
cbFun.ItemIndex := -1;
Rotate(AnsiChar((Sender as TButton).Text[1]));
end;
/// *************************************************
/// Procedure de lancement de rotation au clavier
/// *************************************************
procedure TFormMain.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
Rotate(AnsiChar(KeyChar));
end;
/// *************************************************
/// Lance un appel au bon FloatAnimation et boucle en
/// Attendant la fin de l'animation
/// *************************************************
procedure TFormMain.Rotate(Value: AnsiChar);
begin
case Value of
'r': Rotate(FaTurnRed, 360, 270);
'R': Rotate(FaTurnRed, 0, 90);
'o': Rotate(FaTurnOrange, 0, 90);
'O': Rotate(FaTurnOrange, 360, 270);
'y': Rotate(FaTurnYellow, 0, 90);
'Y': Rotate(FaTurnYellow, 360, 270);
'b': Rotate(FaTurnBlue, 0, 90);
'B': Rotate(FaTurnBlue, 360, 270);
'g': Rotate(FaTurnGreen, 360, 270);
'G': Rotate(FaTurnGreen, 0, 90);
'w': Rotate(FaTurnWhite, 360, 270);
'W': Rotate(FaTurnWhite, 0, 90);
end;
end;
/// *****************************************************
/// Rechercher les cubes Coins et Arretes situés sur le
/// même plan que le cube allant pivoter et en faire ses
/// enfants.
/// Puis, lancement de l'animation ROTATION
/// *****************************************************
procedure TFormMain.Rotate(ThePivotAnimation: TFloatAnimation; StartValue, StepValue: Integer);
var
I: Integer;
begin
recCommand.Enabled := False; // desactiver le panneau de commandes
// récuperation du sens de la rotation
LastDirection := 90; // sens des aiguilles d'une montre pour 90 degres
if StartValue = 360 then
LastDirection := -90; // sens trigo
// Lier les cubes Coins et Arretes au cube allant pivoter
for I := 0 to FormMain.ComponentCount - 1 do
begin
if (FormMain.Components[I] Is TCube) then
begin
if ((FormMain.Components[I] As TCube).Tag = 2) or ((FormMain.Components[I] As TCube).Tag = 3) then
begin
// Red plan
if (SameValue((FormMain.Components[I] As TCube).Position.Z, -3, 0.1)) and (ThePivotAnimation = FaTurnRed) then
begin
(FormMain.Components[I] As TCube).Parent := RedPivot;
(FormMain.Components[I] As TCube).Position.Z := 0;
end;
// Orange plan
if (SameValue((FormMain.Components[I] As TCube).Position.Z, 3, 0.1)) and (ThePivotAnimation = FaTurnOrange) then
begin
(FormMain.Components[I] As TCube).Parent := OrangePivot;
(FormMain.Components[I] As TCube).Position.Z := 0;
end;
// Green plan
if (SameValue((FormMain.Components[I] As TCube).Position.X, -3, 0.1)) and (ThePivotAnimation = FaTurnGreen) then
begin
(FormMain.Components[I] As TCube).Parent := GreenPivot;
(FormMain.Components[I] As TCube).Position.X := 0;
end;
// Blue plan
if (SameValue((FormMain.Components[I] As TCube).Position.X, 3, 0.1)) and (ThePivotAnimation = FaTurnBlue) then
begin
(FormMain.Components[I] As TCube).Parent := BluePivot;
(FormMain.Components[I] As TCube).Position.X := 0;
end;
// White plan
if (SameValue((FormMain.Components[I] As TCube).Position.Y, -3, 0.1)) and (ThePivotAnimation = FaTurnWhite) then
begin
(FormMain.Components[I] As TCube).Parent := WhitePivot;
(FormMain.Components[I] As TCube).Position.Y := 0;
end;
// Yellow plan
if (SameValue((FormMain.Components[I] As TCube).Position.Y, 3, 0.1)) and (ThePivotAnimation = FaTurnYellow) then
begin
(FormMain.Components[I] As TCube).Parent := YellowPivot;
(FormMain.Components[I] As TCube).Position.Y := 0;
end;
end; // si cube Coin ou cuble arrete
end; // si un cube
end; // du for
// Valuer et lancer l'animation
ThePivotAnimation.StartValue := StartValue;
ThePivotAnimation.StopValue := StepValue;
ThePivotAnimation.Start;
while ThePivotAnimation.Running do Application.ProcessMessages;
end;
/// *************************************************
/// En fin d'animation ROTATION le cube ayant pivoté
// rend au cube central les enfants
/// *************************************************
procedure TFormMain.RotationFinish(Sender: TObject);
Var
I: Integer;
TmpX, TmpY, TmpZ: Single;
ThePlan: TCube;
begin
for I := 0 to FormMain.ComponentCount - 1 do
begin
if (FormMain.Components[I] Is TCube) then
begin
if ((FormMain.Components[I] As TCube).Tag = 2) or ((FormMain.Components[I] As TCube).Tag = 3) then
begin
if (FormMain.Components[I] As TCube).Parent <> CubeCentral then
begin
TmpX := (FormMain.Components[I] As TCube).AbsolutePosition.X;
TmpY := (FormMain.Components[I] As TCube).AbsolutePosition.Y;
TmpZ := (FormMain.Components[I] As TCube).AbsolutePosition.Z;
ThePlan := TCube((FormMain.Components[I] As TCube).Parent);
(FormMain.Components[I] As TCube).Position.X := TmpX;
(FormMain.Components[I] As TCube).Position.Y := TmpY;
(FormMain.Components[I] As TCube).Position.Z := TmpZ;
(FormMain.Components[I] As TCube).Parent := CubeCentral;
// plan Rouge (plan Z)
if ThePlan = RedPivot then
begin
(FormMain.Components[I] As TCube).Position.Z := -3;
TurnZPlan((FormMain.Components[I] As TCube));
end;
// plan Orange (Plan Z)
if ThePlan = OrangePivot then
begin
(FormMain.Components[I] As TCube).Position.Z := 3;
TurnZPlan((FormMain.Components[I] As TCube));
end;
// plan bleu (Plan X)
if ThePlan = BluePivot then
begin
(FormMain.Components[I] As TCube).Position.X := 3;
TurnXPlan((FormMain.Components[I] As TCube));
end;
// plan Vert (Plan X)
if ThePlan = GreenPivot then
begin
(FormMain.Components[I] As TCube).Position.X := -3;
TurnXPlan((FormMain.Components[I] As TCube));
end;
// plan Blanc (Plan Y)
if ThePlan = WhitePivot then
begin
(FormMain.Components[I] As TCube).Position.Y := -3;
TurnYPlan((FormMain.Components[I] As TCube));
end;
// plan Jaune (Plan Y)
if ThePlan = YellowPivot then
begin
(FormMain.Components[I] As TCube).Position.Y := 3;
TurnYPlan((FormMain.Components[I] As TCube));
end;
end;
end;
end;
if not MvtAuto then
recCommand.Enabled := True; // le panneau de commande redevient actif
end;
end;
/// *************************************************
/// Renvoi la position (le plan ) d'un stick
/// *************************************************
Function TFormMain.GetStickPosition(TheStick: TPlane): TStickPosition;
begin
Result := PoNone;
if SameValue(TheStick.Position.Y, -1.51, 0.1) then
Result := PoTop;
if SameValue(TheStick.Position.Y, 1.51, 0.1) then
Result := PoBottom;
if SameValue(TheStick.Position.X, -1.51, 0.1) then
Result := PoLeft;
if SameValue(TheStick.Position.X, 1.51, 0.1) then
Result := PoRight;
if SameValue(TheStick.Position.Z, 1.51, 0.1) then
Result := PoBack;
if SameValue(TheStick.Position.Z, -1.51, 0.1) then
Result := PoFront;
end;
/// *************************************************
/// Place (colle) un stick sur un plan des 6 plans
/// du cube
/// ************************************************
procedure TFormMain.MoveStick(TheStick: TPlane; Px, Py, Pz, Rx, Ry, Rz: Single);
begin
TheStick.ResetRotationAngle; // Remise à zero des angles de rotation IMPORTANT
TheStick.Position.X := Px;
TheStick.Position.Y := Py;
TheStick.Position.Z := Pz;
TheStick.RotationAngle.X := Rx;
TheStick.RotationAngle.Y := Ry;
TheStick.RotationAngle.Z := Rz;
end;
/// **********************************************
/// Pour le plan Z ( Rouge et Orange)
/// En fonction du dernier sens de rotation
/// replace les sticks sur la bonne facette
/// **********************************************
procedure TFormMain.TurnZPlan(TheCube: TCube);
var
I: Integer;
begin
for I := 0 to TheCube.ChildrenCount - 1 do
begin
if LastDirection = 90 then // sens des aiguilles
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0) // Up
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0); // Down
end
else
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0) // Down
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0); // Up
end;
end;
end;
/// / **********************************************
/// Idem, pour le plan X ( Bleu et vert)
/// / **********************************************
procedure TFormMain.TurnXPlan(TheCube: TCube);
var
I: Integer;
begin
for I := 0 to TheCube.ChildrenCount - 1 do
begin
if LastDirection = 90 then // sens INVERSE des aiguilles
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0) // Up
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0); // Down
end
else
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoTop then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
MoveStick((TheCube.Children[I] AS TPlane), 0, 1.51, 0, 90, 0, 0) // Down
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBottom then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
MoveStick((TheCube.Children[I] AS TPlane), 0, -1.51, 0, -90, 0, 0); // Up
end;
end;
end;
/// **********************************************
/// Idem, pour le plan Y ( Blanc et Jaune)
/// **********************************************
procedure TFormMain.TurnYPlan(TheCube: TCube);
var
I: Integer;
begin
for I := 0 to TheCube.ChildrenCount - 1 do
begin
if LastDirection = 90 then // sens des aiguilles
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0) // Back
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0); // Front
end
else
begin
if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoFront then
MoveStick((TheCube.Children[I] AS TPlane), 1.51, 0, 0, 0, -90, 0) // Right
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoLeft then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, -1.51, 0, 0, 0) // Front
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoBack then
MoveStick((TheCube.Children[I] AS TPlane), -1.51, 0, 0, 0, 90, 0) // Left
else if GetStickPosition((TheCube.Children[I] AS TPlane)) = PoRight then
MoveStick((TheCube.Children[I] AS TPlane), 0, 0, 1.51, 180, 0, 0); // Back
end;
end;
end;
{$REGION 'Jeu à la souris'}
/// **********************************************
/// en cliquant sur un stick on arme la recherche
/// d'un mouvement
/// **********************************************
procedure TFormMain.StickMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
RayPos, RayDir: TVector3D);
begin
if MvtAuto then
Exit;
ClickXR := RayDir.X; // emplacement du clic en X Radial
ClickYR := RayDir.Y; // emplacement du clic en Y Radial
MvtOn := True;
end;
/// **********************************************
/// En cliquant sur le fond on arme la rotation
/// du cube
/// **********************************************
procedure TFormMain.Viewport3D2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
ClickX := X; // emplacement du clic en X
ClickY := Y; // emplacement du clic en Y
end;
/// **********************************************
/// le deplacement de la souris fait pivoter le cube
/// **********************************************
procedure TFormMain.Viewport3D2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
IF MvtOn then
Exit;
if ssLeft in Shift then // si la souris bouge avec le clic droit enfoncé
begin
Direction := DiNone;
IF (ClickX - X) > 3 then
Direction := DiLeft;
IF (X - ClickX) > 3 then
Direction := DiRight;
IF (ClickY - Y) > 3 then
Direction := DiTop;
IF (Y - ClickY) > 3 then
Direction := DiBottom;
if Direction <> DiNone then // une direction a été trouvée
begin
ClickX := X;
ClickY := Y;
if Direction = DiBottom then
ArcDialX.Value := ArcDialX.Value - 5;
if Direction = DiTop then
ArcDialX.Value := ArcDialX.Value + 5;
if Direction = DiLeft then
ArcDialY.Value := ArcDialY.Value - 5;
if Direction = DiRight then
ArcDialY.Value := ArcDialY.Value + 5;
ArcDialXChange(Self);
end;
end;
end;
/// **********************************************
/// Desarmement du mouvement
/// **********************************************
procedure TFormMain.Viewport3D2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
MvtOn := False;
end;
procedure TFormMain.StickCornerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single;
RayPos, RayDir: TVector3D);
begin
MvtOn := False;
end;
procedure TFormMain.StickCornerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single; RayPos, RayDir: TVector3D);
var
PosXCube, PosYCube, PosZCube: int64;
begin
if not MvtOn then
Exit; // si pas de mouvement d'armé
if ssLeft in Shift then // si la souris bouge avec le clic droit enfoncé
begin
Direction := DiNone;
IF (ClickXR - RayDir.X) > 0.02 then
Direction := DiLeft;
IF (RayDir.X - ClickXR) > 0.02 then
Direction := DiRight;
IF (ClickYR - RayDir.Y) > 0.02 then
Direction := DiTop;
IF (RayDir.Y - ClickYR) > 0.02 then
Direction := DiBottom;
if Direction <> DiNone then // une direction a été trouvée
begin
cbFun.ItemIndex := -1;
// recup de la position XYU du cube sous le stick
PosXCube := Round(((Sender as TPlane).Parent as TCube).Position.X);
PosYCube := Round(((Sender as TPlane).Parent as TCube).Position.Y);
PosZCube := Round(((Sender as TPlane).Parent as TCube).Position.Z);
// desarment du mouvement et reinitialisation de l'emplacement de la souris
MvtOn := False;
ClickXR := RayDir.X;
ClickYR := RayDir.Y;
if (PosZCube = -3) and (SameValue((Sender as TPlane).Position.Z, -1.51, 0.1)) then // Plan Avant Rouge
RotatePlan(PosXCube, PosYCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'w', 'W', 'Y', 'y', 'B', 'b', 'w',
'W', 'Y', 'y')
else if (PosZCube = 3) and (SameValue((Sender as TPlane).Position.Z, 1.51, 0.1)) then // Plan Arriere Orange
RotatePlan(PosXCube, PosYCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'W', 'w', 'y', 'Y', 'B', 'b', 'W',
'w', 'y', 'Y')
else if (PosYCube = -3) and (SameValue((Sender as TPlane).Position.Y, -1.51, 0.1)) then // Plan Haut Blanc
RotatePlan(PosXCube, PosZCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'R', 'r', 'o', 'O', 'B', 'b', 'R',
'r', 'o', 'O')
else if (PosYCube = 3) and (SameValue((Sender as TPlane).Position.Y, 1.51, 0.1)) then // Plan Bas Jaune
RotatePlan(PosXCube, PosZCube, Direction, DiTop, DiBottom, DiRight, DiLeft, 'g', 'G', 'r', 'R', 'O', 'o', 'B', 'b', 'r',
'R', 'O', 'o')
else if (PosXCube = -3) and (SameValue((Sender as TPlane).Position.X, -1.51, 0.1)) then // Plan Gauche Vert
RotatePlan(PosYCube, PosZCube, Direction, DiRight, DiLeft, DiBottom, DiTop, 'w', 'W', 'r', 'R', 'O', 'o', 'Y', 'y', 'r',
'R', 'O', 'o')
else if (PosXCube = 3) and (SameValue((Sender as TPlane).Position.X, 1.51, 0.1)) then // Plan Droit Bleu
RotatePlan(PosYCube, PosZCube, Direction, DiRight, DiLeft, DiBottom, DiTop, 'w', 'W', 'R', 'r', 'o', 'O', 'Y', 'y', 'R',
'r', 'o', 'O');
end;
end;
end;
procedure TFormMain.RotatePlan(Pos1, Pos2: Single; TheDirection, Di1, Di2, Di3, Di4: TDirection;
P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12: AnsiChar);
begin
if Pos1 = -3 then
begin
if (TheDirection = Di1) then
Rotate(P1);
if (TheDirection = Di2) then
Rotate(P2);
if Pos2 = -3 then
begin
if (TheDirection = Di3) then
Rotate(P3);
if (TheDirection = Di4) then
Rotate(P4);
end
else
begin
if (TheDirection = Di3) then
Rotate(P5);
if (TheDirection = Di4) then
Rotate(P6);
end;
end
else
begin // coté bas
if (TheDirection = Di1) then
Rotate(P7);
if (TheDirection = Di2) then
Rotate(P8);
if Pos2 = -3 then
begin
if (TheDirection = Di3) then
Rotate(P9);
if (TheDirection = Di4) then
Rotate(P10);
end
else
begin
if (TheDirection = Di3) then
Rotate(P11);
if (TheDirection = Di4) then
Rotate(P12);
end;
end;
end;
{$ENDREGION}
{$REGION 'Sort the cube (not solving)'}
procedure TFormMain.BtnStartClick(Sender: TObject);
begin
if MessageDlg('Restore initial cube?', TMsgDlgType.mtInformation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0) = MrNo then
Exit;
SortRubik();
CbRotateX.IsChecked := False;
CbRotateY.IsChecked := False;
CbRotateZ.IsChecked := False;
ArcDialX.Value := -35;
ArcDialY.Value := -45;
ArcDialZ.Value := -18;
cbFun.ItemIndex := -1;
ArcDialXChange(Self);
end;
procedure TFormMain.SortRubik();
begin
SortCubes();
SortSticks();
end;
procedure TFormMain.SortSticks();
begin
// face Rouge
MoveStick( PLCC1R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCC2R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCC4R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCC3R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCA1R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCA2R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCA3R, 0, 0, -1.51, 0, 0, 0);
MoveStick( PLCA4R, 0, 0, -1.51, 0, 0, 0);
// Face Bleu
MoveStick( PLCC2B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCC6B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCC3B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCC7B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCA6B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCA3B, 1.51, 0, 0, 0, -90, 0);
MoveStick(PLCA11B, 1.51, 0, 0, 0, -90, 0);
MoveStick( PLCA7B, 1.51, 0, 0, 0, -90, 0);
// Face Verte
MoveStick( PLCC5V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCC1V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCC8V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCC4V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCA5V, -1.51, 0, 0, 0, 90, 0);
MoveStick(PLCA10V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCA8V, -1.51, 0, 0, 0, 90, 0);
MoveStick( PLCA2V, -1.51, 0, 0, 0, 90, 0);
// Orange
MoveStick( PLCC6O, 0, 0, 1.51, 180, 0, 0);
MoveStick( PLCC5O, 0, 0, 1.51, 180, 0, 0);
MoveStick( PLCC7O, 0, 0, 1.51, 180, 0, 0);
MoveStick( PLCC8O, 0, 0, 1.51, 180, 0, 0);
MoveStick( PLCA9O, 0, 0, 1.51, 180, 0, 0);
MoveStick(PLCA11O, 0, 0, 1.51, 180, 0, 0);
MoveStick(PLCA10O, 0, 0, 1.51, 180, 0, 0);
MoveStick(PLCA12O, 0, 0, 1.51, 180, 0, 0);
// Face Blanche
MoveStick( PLCC5W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCC6W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCC1W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCC2W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCA9W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCA5W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCA6W, 0, -1.51, 0, -90, 0, 0);
MoveStick( PLCA1W, 0, -1.51, 0, -90, 0, 0);
// Face Jaune
MoveStick( PLCC4J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCC3J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCC8J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCC7J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCA4J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCA8J, 0, 1.51, 0, 90, 0, 0);
MoveStick( PLCA7J, 0, 1.51, 0, 90, 0, 0);
MoveStick(PLCA12J, 0, 1.51, 0, 90, 0, 0);
end;
procedure TFormMain.SortCubes();
begin
// les cubes coins
SortCube( CC1, -3, -3, -3);
SortCube( CC2, 3, -3, -3);
SortCube( CC3, 3, 3, -3);
SortCube( CC4, -3, 3, -3);
SortCube( CC5, -3, -3, 3);
SortCube( CC6, 3, -3, 3);
SortCube( CC7, 3, 3, 3);
SortCube( CC8, -3, 3, 3);
// les cubes arretes
SortCube( CA1, 0, -3, -3);
SortCube( CA2, -3, 0, -3);
SortCube( CA3, 3, 0, -3);
SortCube( CA4, 0, 3, -3);
SortCube( CA5, -3, -3, 0);
SortCube( CA6, 3, -3, 0);
SortCube( CA7, 3, 3, 0);
SortCube( CA8, -3, 3, 0);
SortCube( CA9, 0, -3, 3);
SortCube(CA10, -3, 0, 3);
SortCube(CA11, 3, 0, 3);
SortCube(CA12, 0, 3, 3);
end;
procedure TFormMain.SortCube(TheCube: TCube; Px, Py, Pz: Single);
begin
TheCube.ResetRotationAngle;
TheCube.Position.X := Px;
TheCube.Position.Y := Py;
TheCube.Position.Z := Pz;
end;
{$ENDREGION}
{$REGION 'Jouer des mouvements enregistrés'}
procedure TFormMain.cbFunChange(Sender: TObject);
begin
if cbFun.ItemIndex <> -1 then
begin
cbFun.DropDown; // Pour refermer immédiatement la dropdown
SortRubik();
PlayMvt(FUN_VALUES[cbFun.ItemIndex]);
end;
end;
procedure TFormMain.PlayMvt(TheMvts: AnsiString);
var
I: Integer;
iMax: Integer;
begin
// Platform.SetCursor(nil, crHourGlass); // ProcessMessages casse le curseur
MvtAuto := True; // On enchaine une série (l'utilisateur ne peut pas faire de modif manuelle)
iMax := Length(TheMvts);
pbFun.Value := 1;
pbFun.Max := iMax;
pbFun.Visible := True;
recCommand.Enabled := False; // desactiver le panneau de commandes
for I := 1 to iMax do
begin
Rotate(TheMvts[I]);
pbFun.Value := pbFun.Value + 1;
end;
MvtAuto := False; // La série est terminée, l'utilisateur peut à nouveau jouer
pbFun.Visible := False;
recCommand.Enabled := True; // le panneau de commande redevient actif
end;
{$ENDREGION}
{$REGION 'Ouverture de la page Web'}
procedure TFormMain.LbInfoLinkClick(Sender: TObject);
begin
TMisc.Open((Sender as TLabel).Text);
end;
{$ENDREGION}
{$REGION 'Rotation automatique du cube'}
/// *************************************************
/// Déplacement de la caméra autour du rubik's cube
/// *************************************************
Procedure TFormMain.ArcDialXChange(Sender: TObject);
begin
Dummy.RotationAngle.X := ArcDialX.Value;
Dummy.RotationAngle.Y := ArcDialY.Value;
Dummy.RotationAngle.Z := ArcDialZ.Value;
end;
Procedure TFormMain.CbRotateXChange(Sender: TObject);
begin
FaAutoRotateX.Stop;
if CbRotateX.IsChecked then
FaAutoRotateX.Start;
end;
Procedure TFormMain.CbRotateYChange(Sender: TObject);
begin
FaAutoRotateY.Stop;
if CbRotateY.IsChecked then
FaAutoRotateY.Start;
end;
Procedure TFormMain.CbRotateZChange(Sender: TObject);
begin
FaAutoRotateZ.Stop;
if CbRotateZ.IsChecked then
FaAutoRotateZ.Start;
end;
{$ENDREGION}
{$REGION 'Les lumières'}
procedure TFormMain.RbAmbianceChange(Sender: TObject);
Var
I: Integer;
Color: TAlphaColor;
begin
MainLight.Enabled := RbSpotLight.IsChecked;
BwTbLight.Enabled := RbSpotLight.IsChecked;
if RbSpotLight.IsChecked then
begin
Color := claNull;
SetLight;
end
else
Color := claWhite;
for I := 0 to FormMain.ComponentCount - 1 do
begin
// les stickers
if (FormMain.Components[I] Is TPlane) then
(FormMain.Components[I] As TPlane).material.Emissive := Color;
// Les cubes pivots
if (FormMain.Components[I] Is TCube) then
if (FormMain.Components[I] As TCube).Tag = 1 then
(FormMain.Components[I] As TCube).material.Emissive := Color;
end;
end;
procedure TFormMain.SetLight;
var
cLight: TAlphaColorRec;
begin
cLight.R := Round(255 * BwTbLight.Value);
cLight.G := Round(255 * BwTbLight.Value);
cLight.B := Round(255 * BwTbLight.Value);
MainLight.Diffuse := cLight.Color;
Viewport3D2.Repaint;
end;
procedure TFormMain.BwTbLightChange(Sender: TObject);
begin
SetLight;
end;
{$ENDREGION}
end.
Conclusion
A/ Caméra et Dummy
Premier point important. Il existe 2 façons de voir un objet sous tous ses angles. Soit faire pivoter l'objet (rotationAngle) Soit pivoter autour de l'objet en continuant à le fixer (camera et Dummy)
Le premier cas convient tres bien avec un seul objet. Seuls les rotationAngle XYZ varient. Dans tous les autres cas utilisez la seconde méthode. Ainsi les coordonnées X,Y et Z des objets resteront bien mieux maitrisables.
B/ Notions diverses
Le rubik est composé : -D'un cube central (TCube) celui qui est invisible. -De 6 cubes Pivots (TCube) sitée au centre,avec un rendu Bitmap pour la couleur -6 Composants anitmations (TFloatAnimation) , un par pivot. Ils sont enfant des Pivots et mémorisent l'axe de rotation du pivot. -8 Cubes coins (TCube) Noir avec 3 facettes(TPlane) chacuns. Nommé Stickers dans le source et les commentaires. -12 cubes Arretes (TCube) Noir avec 2 facettes(TPlane) chacuns. Nommé Stickers dans le source et les commentaires.
C.1 Une fiche dispose de composants accèssibles depuis toujours avec ComponentCount et Components[]. Les objets 3D eux gerent des enfants accessibles avec ChildrenCount et Children[]. Pensez y !
C.2 Rotation des enfants La rotation d'un parent declenche la rotation de ses enfants autour du même axe (principe utilisé dans le prog). A l'issue de la rotation, les enfants ont gardé les mêmes positions X,Y,Z et rotationAngle puisque directement lié a leur parent. Bien retenir que les positions X,Y,Z et rotationAngle sont donc relatif au parent. Seules les positions Absolues Varient.
C.3 Changement de parent Pour effectuer une rotation le programme recherche les cubes coins et cubes arrêtes situés sur le même plan que le cube central devant pivoter et en fait ses enfants, Puis s'effectue la rotation. Enfin, les cubes enfants sont rendu au cube central.
Problème, le changement de parent replace l'enfant avec le même décalage et la même rotation qu'il avait avec son ex parent(4.2). les rotationsAngles et le repositionnement relatif au cube centrale doivent être refait (c'est a vous de le gerer)
C.4 Animation en Thread Les animations sont threadées, il faut donc attendre la fin d'une rotation pour en lancer une autre
C.6 Pour finir
C.6 Pour finir
les cubes coins sont sensibles au clic souris pour les rotations de face. Un tirer-lâcher sur la zone grise permet une rotation de tout le cube.
La partie 'Fun' exécute des figures pré-enregistrées.
Modifiez la taille de la fenêtre, changez l'éclairage, changez les animations, vitesse, jouez les auto-rotations et vous verrez la puissance de l'outil Firemonkey
Merci à Whiler pour son Aide. Pour ceux qui veulent tester l'exe ftp://ftp2.p2f-logiciels.com/pflogicie/SetupRubik. exe
Pascal Fonteneau Alias Fireman
Historique
- 19 avril 2012 11:38:07 :
- ajout image et zip
- 23 avril 2012 06:35:32 :
- Améliorations :
Gestion des lumières
Hints personnalisés actifs
Simplification des sources
Interfaces et noms de variables,procedures en anglais
Rotations automatique du cube.
Correction de bug mineurs
Pour ceux qui veulent tester l'exe
ftp://ftp2.p2f-logiciels.com/pflogicie/SetupRubik.exe
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
DELPHI et 3D [ par sebrs1 ]
Qu'est-ce que vous me conseillez pour faire de la 3D en delphi, parce que entre delphiX qui est pas compatible avec delphi6, glscene où il n'y a aucun
JE CHERCHE UN MOTEUR 3D POUR DELPHI! [ par nono009 ]
Voilà je recherche un moteur 3d pour delphi (gratuit si possible)Opengl ou directXMerci d'avancea+
creer un moteur de jeu 3D [ par ewertheimer ]
Bonjour,J'aimerais creerb un jeu en 3D sous delphi. Je mis connait pas mal en delphi mais j'aimerais juste savoir à quoi sert à creer un mot
Animations 3D [ par Katespower ]
Bonjour à tous !!Je développe en ce moment avec des amis un jeu en 3D sous Delphi à l'aide e DirectX. Nous avons réussi à créer ma base de notre jeu e
delphi modélisation 3D [ par gamellemaleh ]
Slt! Je bosse sur un projet de scanner d'empreinte dentaire et notamment sur la modélisation de l'empreinte à partir d'une liste de points.
fichier 3ds de GLscene [ par ahlemBH ]
salut tous l monde, je suis débutante en Delphi, et je suis entrain de faire un petit projet sur le traitement des images médicales. j'ai un problème
Version XE2 [ par jderf ]
Bonjour, Je voudrai avoir la confirmation sur les capacitées de connexion aux SGBD en fonction des versions. - Delphi XE2 starter (199¤) Une connec
Installation XE2 Delphi [ par sky1414 ]
Bonjour, Sur PC W7Pro formater il y a 2 jour et MAJ , j'obtiens le message suivant à la compilation d'un projet vierge [DCC Erreur] Compilateur pour l
A propos de FireMonkey 3D [ par dan479 ]
Bonjour à tous, Je viens juste de migrer de Delphi 7 vers XE2 Starter. C'est le jour et la nuit ! Firemonkey n'étant pas encore documenté, je ne peux
gestion de base de donnees avec delphi XE2 [ par mlamXE2 ]
bonjour, Est ce que qqn pourrait me donner une idée pour démarrer avec une application en delphi xe2 qui gère des base de données. j'ai lu les aides
|
Derniers Blogs
ETENDRE LE TEAM WEB ACCESS DE TFS 2012 - STEP 0ETENDRE LE TEAM WEB ACCESS DE TFS 2012 - STEP 0 par Philess
L'extensibilité du Team Web Access
Le Web Access (site d'équipe) de Team Foundation Server a été complètement réécrit dans la version 2012 avec pas moins de 400.000 lignes de JavaScript. Ce nouveau modèle a été pensé pour offrir de grandes...
Cliquez pour lire la suite de l'article par Philess SIMULER FACILEMENT L'ENVOI DE MAILSIMULER FACILEMENT L'ENVOI DE MAIL par JeremyJeanson
il m'a été demandé, à plusieurs reprises, comment je faisais pour simuler l'envoi de mail lors de mes démos de Workflow Foundation. Ma solution est plutôt simple : j'utilise la configuration par défaut du SmtpClient et j'oriente les mails vers un dossier ...
Cliquez pour lire la suite de l'article par JeremyJeanson VOTEZ POUR LE TOP 10 DES INFLUENCEURS SHAREPOINT FRANCOPHONES !VOTEZ POUR LE TOP 10 DES INFLUENCEURS SHAREPOINT FRANCOPHONES ! par Patrick Guimonet
Si ce n'est déjà fait (comme plus de 600 personnes déjà), il est encore temps de voter pour le concours TOP 10 des influenceurs SharePoint francophones ! Il est organisé par harmon.ie et accessible ici : http://harmon.ie/top-...
Cliquez pour lire la suite de l'article par Patrick Guimonet [CONF'SHAREPOINT] DERNIER RAPPEL ! :-)[CONF'SHAREPOINT] DERNIER RAPPEL ! :-) par Patrick Guimonet
La Conf'SharePoint en chiffres c'est : 3 jours de SharePoint ! 4 parcours et 60 sessions 17 partenaires représentant toutes les fac...
Cliquez pour lire la suite de l'article par Patrick Guimonet
Logiciels
Easy-Planning (4.5.0.11)EASY-PLANNING (4.5.0.11)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté a... Cliquez pour télécharger Easy-Planning CVEasy (3.1.0.51)CVEASY (3.1.0.51)PHMSD-CVEasy est un logiciel d'aide à la rédaction de CV d'une simplicité déconcertante.
PHMSD-C... Cliquez pour télécharger CVEasy LettresFaciles 2011 (8.6.0.31)LETTRESFACILES 2011 (8.6.0.31)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011 sDEVIS-FACTURES vlPRO (8.4.2.62)SDEVIS-FACTURES VLPRO (8.4.2.62)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO Devis-Factures PHMSD (2.1.0.11)DEVIS-FACTURES PHMSD (2.1.0.11)Configuration minimale
Nécessite Windows™ 2000, XP, Windows 7, 8, Vista (Service Pack à... Cliquez pour télécharger Devis-Factures PHMSD
|