home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch9 / Robot.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-05-29  |  18.7 KB  |  619 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmRobot 
  4.    Caption         =   "Robot []"
  5.    ClientHeight    =   4590
  6.    ClientLeft      =   2040
  7.    ClientTop       =   1035
  8.    ClientWidth     =   4635
  9.    LinkTopic       =   "Form1"
  10.    PaletteMode     =   1  'UseZOrder
  11.    ScaleHeight     =   306
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   309
  14.    Begin VB.TextBox txtFramesPerSecond 
  15.       Height          =   285
  16.       Left            =   4200
  17.       TabIndex        =   9
  18.       Text            =   "20"
  19.       Top             =   60
  20.       Width           =   375
  21.    End
  22.    Begin VB.CommandButton cmdPlay 
  23.       Caption         =   "Play"
  24.       Default         =   -1  'True
  25.       Height          =   495
  26.       Left            =   3480
  27.       TabIndex        =   7
  28.       Top             =   2160
  29.       Width           =   975
  30.    End
  31.    Begin VB.OptionButton optPlay 
  32.       Caption         =   "Reversing"
  33.       Height          =   255
  34.       Index           =   2
  35.       Left            =   3360
  36.       TabIndex        =   4
  37.       Top             =   1680
  38.       Width           =   1095
  39.    End
  40.    Begin VB.OptionButton optPlay 
  41.       Caption         =   "Looping"
  42.       Height          =   255
  43.       Index           =   1
  44.       Left            =   3360
  45.       TabIndex        =   3
  46.       Top             =   1320
  47.       Width           =   1095
  48.    End
  49.    Begin VB.OptionButton optPlay 
  50.       Caption         =   "Once"
  51.       Height          =   255
  52.       Index           =   0
  53.       Left            =   3360
  54.       TabIndex        =   2
  55.       Top             =   960
  56.       Value           =   -1  'True
  57.       Width           =   1095
  58.    End
  59.    Begin VB.HScrollBar sbarFrame 
  60.       Height          =   255
  61.       Left            =   0
  62.       Max             =   1
  63.       Min             =   1
  64.       TabIndex        =   1
  65.       Top             =   3960
  66.       Value           =   1
  67.       Width           =   3255
  68.    End
  69.    Begin VB.PictureBox picCanvas 
  70.       Height          =   3975
  71.       Left            =   0
  72.       ScaleHeight     =   261
  73.       ScaleMode       =   3  'Pixel
  74.       ScaleWidth      =   213
  75.       TabIndex        =   0
  76.       Top             =   0
  77.       Width           =   3255
  78.    End
  79.    Begin MSComDlg.CommonDialog dlgFile 
  80.       Left            =   3360
  81.       Top             =   3600
  82.       _ExtentX        =   847
  83.       _ExtentY        =   847
  84.       _Version        =   393216
  85.       CancelError     =   -1  'True
  86.    End
  87.    Begin VB.Label Label1 
  88.       Alignment       =   2  'Center
  89.       Caption         =   "Frames per Second"
  90.       Height          =   375
  91.       Index           =   1
  92.       Left            =   3360
  93.       TabIndex        =   8
  94.       Top             =   0
  95.       Width           =   855
  96.    End
  97.    Begin VB.Label lblFrame 
  98.       Alignment       =   1  'Right Justify
  99.       BorderStyle     =   1  'Fixed Single
  100.       Caption         =   "1/1"
  101.       Height          =   255
  102.       Left            =   1680
  103.       TabIndex        =   6
  104.       Top             =   4320
  105.       Width           =   735
  106.    End
  107.    Begin VB.Label Label1 
  108.       Caption         =   "Frame:"
  109.       Height          =   255
  110.       Index           =   0
  111.       Left            =   1080
  112.       TabIndex        =   5
  113.       Top             =   4320
  114.       Width           =   495
  115.    End
  116.    Begin VB.Menu mnuFile 
  117.       Caption         =   "&File"
  118.       Begin VB.Menu mnuFileOpen 
  119.          Caption         =   "&Open..."
  120.          Shortcut        =   ^O
  121.       End
  122.       Begin VB.Menu mnuFileSave 
  123.          Caption         =   "&Save"
  124.          Shortcut        =   ^S
  125.       End
  126.       Begin VB.Menu mnuFileSaveAs 
  127.          Caption         =   "Save &As..."
  128.          Shortcut        =   ^A
  129.       End
  130.       Begin VB.Menu mnuFileSep 
  131.          Caption         =   "-"
  132.       End
  133.       Begin VB.Menu mnuFileExit 
  134.          Caption         =   "E&xit"
  135.       End
  136.    End
  137.    Begin VB.Menu mnuFileFrames 
  138.       Caption         =   "Frames"
  139.       Begin VB.Menu mnuFrameAfter 
  140.          Caption         =   "Insert &After"
  141.       End
  142.       Begin VB.Menu mnuFrameBefore 
  143.          Caption         =   "Insert &Before"
  144.       End
  145.       Begin VB.Menu mnuFrameSep 
  146.          Caption         =   "-"
  147.       End
  148.       Begin VB.Menu mnuFrameDelete 
  149.          Caption         =   "&Delete"
  150.          Enabled         =   0   'False
  151.       End
  152.    End
  153. Attribute VB_Name = "frmRobot"
  154. Attribute VB_GlobalNameSpace = False
  155. Attribute VB_Creatable = False
  156. Attribute VB_PredeclaredId = True
  157. Attribute VB_Exposed = False
  158. Option Explicit
  159. Private NumFrames As Integer
  160. Private Frames() As New Robot
  161. Private SelectedFrame As Integer
  162. Private SelectingFrame As Boolean
  163. Private FileName As String
  164. Private FileTitle As String
  165. Private DataModified As Boolean
  166. Private Playing As Boolean
  167. Private NumPlayed As Long
  168. Private Dragging As Boolean
  169. Private DragPoint As Integer
  170. Private DragX As Integer
  171. Private DragY As Integer
  172. Private AnchorX As Integer
  173. Private AnchorY As Integer
  174. ' Convert (X, Y) into the point in the direction
  175. ' of (X, Y) that is the correct distance from the
  176. ' anchor point. For example, when dragging an
  177. ' elbow, the point should be UpperArmLength distance
  178. ' from the shoulders.
  179. Private Sub AdjustPoint(x As Single, y As Single)
  180. Dim dist As Single
  181. Dim factor As Single
  182. Dim dx As Single
  183. Dim dy As Single
  184.     ' Heads have no anchor point.
  185.     If DragPoint = part_Head Then
  186.         DragX = x
  187.         DragY = y
  188.         Exit Sub
  189.     End If
  190.     dx = x - AnchorX
  191.     dy = y - AnchorY
  192.     dist = Sqr(dx * dx + dy * dy)
  193.     Select Case DragPoint
  194.         Case part_Lelbow, part_RElbow
  195.             factor = Frames(1).UpperArmLength / dist
  196.         Case part_LHand, part_RHand
  197.             factor = Frames(1).LowerArmLength / dist
  198.         Case part_LKnee, part_RKnee
  199.             factor = Frames(1).UpperLegLength / dist
  200.         Case part_LFoot, part_RFoot
  201.             factor = Frames(1).LowerLegLength / dist
  202.     End Select
  203.     DragX = AnchorX + dx * factor
  204.     DragY = AnchorY + dy * factor
  205. End Sub
  206. ' Return true if the data has not been modified,
  207. ' or the user has saved the changes, or the user
  208. ' wants to lose the changes.
  209. Private Function DataSafe() As Boolean
  210. Dim ans As Integer
  211.     Do While DataModified
  212.         ans = MsgBox("The data has been modified." & _
  213.             " Do you want to save the changes?", _
  214.             vbYesNoCancel)
  215.         If ans = vbCancel Then Exit Do
  216.         If ans = vbNo Then
  217.             DataSafe = True
  218.             Exit Function
  219.         End If
  220.             
  221.         ' Otherwise save the data.
  222.         If FileName <> "" Then
  223.             mnuFileSave_Click
  224.         Else
  225.             mnuFileSaveAs_Click
  226.         End If
  227.     Loop
  228.     DataSafe = Not DataModified
  229. End Function
  230. ' Draw the highlight fot the drag.
  231. Private Sub DrawDrag()
  232.     If DragPoint = part_Head Then
  233.         picCanvas.Line (DragX - Near, DragY - Near)-Step(Near2, Near2), , BF
  234.     Else
  235.         picCanvas.Line (AnchorX, AnchorY)-(DragX, DragY)
  236.     End If
  237. End Sub
  238. ' Draw the selected configuration.
  239. Private Sub DrawSelected()
  240.     picCanvas.Cls
  241.     Frames(SelectedFrame).Draw picCanvas, True
  242. End Sub
  243. ' Save a robot script into the file.
  244. Private Sub SaveScript(ByVal file_name As String, ByVal file_title As String)
  245. Dim fnum As Integer
  246. Dim i As Integer
  247.     On Error GoTo SaveScriptError
  248.     ' Open the file.
  249.     fnum = FreeFile
  250.     Open file_name For Output As fnum
  251.     ' Write the number of frames.
  252.     Write #fnum, NumFrames
  253.     ' Write the parameters for each frame.
  254.     For i = 1 To NumFrames
  255.         Frames(i).FileWrite fnum
  256.     Next i
  257.     Close fnum
  258.     FileName = file_name
  259.     FileTitle = file_title
  260.     DataModified = False
  261.     Caption = "Robot [" & FileTitle & "]"
  262.     Exit Sub
  263. SaveScriptError:
  264.     Beep
  265.     MsgBox "Error saving file " & file_name & "." & _
  266.         vbCrLf & Format$(Err.Number) & " : " & _
  267.         Err.Description
  268.     Exit Sub
  269. End Sub
  270. ' Load a robot script from the file.
  271. Private Sub LoadScript(ByVal file_name As String, ByVal file_title As String)
  272. Dim fnum As Integer
  273. Dim i As Integer
  274.     On Error GoTo LoadScriptError
  275.     ' Open the file.
  276.     fnum = FreeFile
  277.     Open file_name For Input As fnum
  278.     ' Read the number of frames.
  279.     Input #fnum, NumFrames
  280.     ReDim Frames(1 To NumFrames)
  281.     sbarFrame.Max = NumFrames
  282.     ' Read the parameters for each frame.
  283.     For i = 1 To NumFrames
  284.         Frames(i).FileInput fnum
  285.     Next i
  286.     Close fnum
  287.     SelectFrame 1
  288.     mnuFrameDelete.Enabled = (NumFrames > 1)
  289.     FileName = file_name
  290.     FileTitle = file_title
  291.     DataModified = False
  292.     Caption = "Robot [" & FileTitle & "]"
  293.     Exit Sub
  294. LoadScriptError:
  295.     Beep
  296.     MsgBox "Error loading file " & file_name & "." & _
  297.         vbCrLf & Format$(Err.Number) & " : " & _
  298.         Err.Description
  299.     Exit Sub
  300. End Sub
  301. ' Select and display the indicated frame.
  302. Private Sub SelectFrame(index As Integer)
  303.     SelectedFrame = index
  304.     SelectingFrame = True
  305.     sbarFrame.Value = index
  306.     SelectingFrame = False
  307.     lblFrame.Caption = Format$(index) & _
  308.         "/" & Format$(NumFrames)
  309.     DrawSelected
  310. End Sub
  311. ' Set the point that anchors the selected control
  312. ' point. For example, when moving a hand the
  313. ' corresponding elbow is the control point.
  314. Private Sub SetAnchor()
  315.     Select Case DragPoint
  316.         Case part_Head  ' The head has no anchor.
  317.             AnchorX = -1
  318.         Case part_Lelbow, part_RElbow
  319.             Frames(SelectedFrame).Position _
  320.                 part_Shoulders, AnchorX, AnchorY
  321.         Case part_LHand
  322.             Frames(SelectedFrame).Position _
  323.                 part_Lelbow, AnchorX, AnchorY
  324.         Case part_RHand
  325.             Frames(SelectedFrame).Position _
  326.                 part_RElbow, AnchorX, AnchorY
  327.         Case part_LKnee, part_RKnee
  328.             Frames(SelectedFrame).Position _
  329.                 part_Hips, AnchorX, AnchorY
  330.         Case part_LFoot
  331.             Frames(SelectedFrame).Position _
  332.                 part_LKnee, AnchorX, AnchorY
  333.         Case part_RFoot
  334.             Frames(SelectedFrame).Position _
  335.                 part_RKnee, AnchorX, AnchorY
  336.     End Select
  337. End Sub
  338. ' Grab the nearest control point within distance
  339. ' Near of the mouse.
  340. Private Sub picCanvas_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
  341. Dim i As Integer
  342. Dim best_i As Integer
  343. Dim best_dist As Long
  344. Dim dx As Long
  345. Dim dy As Long
  346. Dim dist As Long
  347. Dim fx As Integer
  348. Dim fy As Integer
  349.     ' Find the closest control point.
  350.     best_dist = Near + 1
  351.     For i = part_MinPart To part_MaxControlPart
  352.         Frames(SelectedFrame).Position i, fx, fy
  353.         dx = x - fx
  354.         dy = y - fy
  355.         dist = Sqr(dx * dx + dy * dy)
  356.         If best_dist > dist Then
  357.             best_dist = dist
  358.             best_i = i
  359.         End If
  360.     Next i
  361.     ' If nothing is close enough, leave.
  362.     If best_dist > Near Then
  363.         Beep
  364.         Exit Sub
  365.     End If
  366.     ' Begin moving the control point.
  367.     Dragging = True
  368.     DragPoint = best_i
  369.     picCanvas.DrawMode = vbInvert
  370.     SetAnchor
  371.     DragX = x
  372.     DragY = y
  373.     DrawDrag
  374. End Sub
  375. ' Continue dragging a control point.
  376. Private Sub picCanvas_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
  377.     If Not Dragging Then Exit Sub
  378.     ' Erase the old highlight.
  379.     DrawDrag
  380.     ' Draw the new highlight.
  381.     AdjustPoint x, y
  382.     DrawDrag
  383. End Sub
  384. ' Finish dragging the control point.
  385. Private Sub picCanvas_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  386.     If Not Dragging Then Exit Sub
  387.     Dragging = False
  388.     ' Erase the old highlight.
  389.     DrawDrag
  390.     picCanvas.DrawMode = vbCopyPen
  391.     ' Adjust the control point.
  392.     AdjustPoint x, y
  393.     Frames(SelectedFrame).MoveControlPoint _
  394.         DragPoint, AnchorX, AnchorY, DragX, DragY
  395.     DrawSelected
  396.     DataModified = True
  397.     Caption = "Robot*[" & FileTitle & "]"
  398. End Sub
  399. ' Play the animation.
  400. Private Sub cmdPlay_Click()
  401.     If Playing Then
  402.         Playing = False
  403.         cmdPlay.Caption = "Stopped"
  404.         cmdPlay.Enabled = False
  405.     Else
  406.         Playing = True
  407.         cmdPlay.Caption = "Stop"
  408.         PlayData
  409.         cmdPlay.Caption = "Play"
  410.         Playing = False
  411.         cmdPlay.Enabled = True
  412.         DrawSelected
  413.     End If
  414. End Sub
  415. ' Play the animation.
  416. Private Sub PlayData()
  417. Dim ms_per_frame As Long
  418. Dim start_time As Single
  419. Dim stop_time As Single
  420.     ' See how fast we should go.
  421.     If Not IsNumeric(txtFramesPerSecond.Text) Then _
  422.         txtFramesPerSecond.Text = "10"
  423.     ms_per_frame = 1000 \ CLng(txtFramesPerSecond.Text)
  424.     ' See what kind of animation this should be.
  425.     NumPlayed = 0
  426.     start_time = Timer
  427.     If optPlay(0).Value Then
  428.         PlayDataOnce ms_per_frame
  429.     ElseIf optPlay(1).Value Then
  430.         PlayDataLooping ms_per_frame
  431.     ElseIf optPlay(2).Value Then
  432.         PlayDataBackAndForth ms_per_frame
  433.     End If
  434.     stop_time = Timer
  435.     MsgBox "Displayed" & Str$(NumPlayed) & _
  436.         " frames in " & _
  437.         Format$(stop_time - start_time, "0.00") & _
  438.         " seconds (" & _
  439.         Format$(NumPlayed / (stop_time - start_time), "0.00") & _
  440.         " FPS)."
  441. End Sub
  442. ' Play the animation once.
  443. Private Sub PlayDataOnce(ByVal ms_per_frame As Long)
  444. Dim next_time As Long
  445. Dim frame As Integer
  446.     ' Start the animation.
  447.     next_time = GetTickCount()
  448.     ' Show the frames once.
  449.     For frame = 1 To NumFrames
  450.         If Not Playing Then Exit For
  451.         NumPlayed = NumPlayed + 1
  452.         ' Draw the frame.
  453.         picCanvas.Cls
  454.         Frames(frame).Draw picCanvas, False
  455.         ' Wait until it's time for the next frame.
  456.         next_time = next_time + ms_per_frame
  457.         WaitTill next_time
  458.     Next frame
  459. End Sub
  460. ' Play the animation in a loop.
  461. Private Sub PlayDataLooping(ByVal ms_per_frame As Long)
  462.     Do While Playing
  463.         PlayDataOnce ms_per_frame
  464.     Loop
  465. End Sub
  466. ' Play the animation backward and forward.
  467. Private Sub PlayDataBackAndForth(ByVal ms_per_frame As Long)
  468.     Do While Playing
  469.         PlayDataOnce ms_per_frame
  470.         If Not Playing Then Exit Do
  471.         PlayDataBackwards ms_per_frame
  472.     Loop
  473. End Sub
  474. ' Play the animation once backwards.
  475. Private Sub PlayDataBackwards(ByVal ms_per_frame As Long)
  476. Dim next_time As Long
  477. Dim frame As Integer
  478.     ' Start the animation.
  479.     next_time = GetTickCount()
  480.     ' Show the frames once.
  481.     For frame = NumFrames To 1 Step -1
  482.         If Not Playing Then Exit For
  483.         NumPlayed = NumPlayed + 1
  484.         ' Draw the frame.
  485.         picCanvas.Cls
  486.         Frames(frame).Draw picCanvas, False
  487.         ' Wait until it's time for the next frame.
  488.         next_time = next_time + ms_per_frame
  489.         WaitTill next_time
  490.     Next frame
  491. End Sub
  492. Private Sub Form_Load()
  493.     dlgFile.Filter = _
  494.         "Robot Files (*.rob)|*.rob|" & _
  495.         "All Files (*.*)|*.*"
  496.         dlgFile.InitDir = App.Path
  497.     ' Create a single default frame.
  498.     NumFrames = 1
  499.     ReDim Frames(1 To NumFrames)
  500.     With Frames(1)
  501.         .SetParameters _
  502.             picCanvas.ScaleWidth / 2, _
  503.             (picCanvas.ScaleHeight - .MaxHeight) / 2 + _
  504.                 .HeadRoom, _
  505.             210, -30, 150, 30, 240, -60, 255, -75
  506.     End With
  507.     ' Position the scroll bar.
  508.     sbarFrame.Top = picCanvas.Top + picCanvas.Height + 1
  509.     SelectFrame 1
  510. End Sub
  511. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  512.     Cancel = Not DataSafe()
  513. End Sub
  514. Private Sub Form_Unload(Cancel As Integer)
  515.     End
  516. End Sub
  517. Private Sub mnuFileExit_Click()
  518.     Unload Me
  519. End Sub
  520. ' Load a robot script file.
  521. Private Sub mnuFileOpen_Click()
  522. Dim file_name As String
  523.     If Not DataSafe() Then Exit Sub
  524.     ' Allow the user to pick a file.
  525.     On Error Resume Next
  526.     dlgFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  527.     dlgFile.ShowOpen
  528.     If Err.Number = cdlCancel Then
  529.         Exit Sub
  530.     ElseIf Err.Number <> 0 Then
  531.         Beep
  532.         MsgBox "Error selecting file.", , vbExclamation
  533.         Exit Sub
  534.     End If
  535.     On Error GoTo 0
  536.     file_name = Trim$(dlgFile.FileName)
  537.     dlgFile.InitDir = Left$(file_name, Len(file_name) _
  538.         - Len(dlgFile.FileTitle) - 1)
  539.     ' Load the robot script file.
  540.     LoadScript file_name, dlgFile.FileTitle
  541. End Sub
  542. ' Save the robot script file.
  543. Private Sub mnuFileSave_Click()
  544.     If FileName = "" Then
  545.         mnuFileSaveAs_Click
  546.         Exit Sub
  547.     End If
  548.     SaveScript FileName, FileTitle
  549. End Sub
  550. ' Save the robot script file with a new name.
  551. Private Sub mnuFileSaveAs_Click()
  552. Dim file_name As String
  553.     ' Allow the user to pick a file.
  554.     On Error Resume Next
  555.     dlgFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  556.     dlgFile.ShowSave
  557.     If Err.Number = cdlCancel Then
  558.         Exit Sub
  559.     ElseIf Err.Number <> 0 Then
  560.         Beep
  561.         MsgBox "Error selecting file.", , vbExclamation
  562.         Exit Sub
  563.     End If
  564.     On Error GoTo 0
  565.     file_name = Trim$(dlgFile.FileName)
  566.     dlgFile.InitDir = Left$(file_name, Len(file_name) _
  567.         - Len(dlgFile.FileTitle) - 1)
  568.     ' Save the robot script file.
  569.     SaveScript file_name, dlgFile.FileTitle
  570. End Sub
  571. ' Insert a frame next to the selected one.
  572. Private Sub AddFrame()
  573. Dim i As Integer
  574.     NumFrames = NumFrames + 1
  575.     ReDim Preserve Frames(1 To NumFrames)
  576.     For i = NumFrames - 1 To SelectedFrame Step -1
  577.         Frames(i + 1).CopyFrame Frames(i)
  578.     Next i
  579.     sbarFrame.Max = NumFrames
  580.     mnuFrameDelete.Enabled = (NumFrames > 1)
  581. End Sub
  582. ' Insert a frame after the selected one.
  583. Private Sub mnuFrameAfter_Click()
  584.     AddFrame
  585.     SelectFrame SelectedFrame + 1
  586. End Sub
  587. ' Insert a frame before the selected one.
  588. Private Sub mnuFrameBefore_Click()
  589.     AddFrame
  590. End Sub
  591. ' Delete the selected frame.
  592. Private Sub mnuFrameDelete_Click()
  593. Dim i As Integer
  594.     For i = SelectedFrame To NumFrames - 1
  595.         Frames(i).CopyFrame Frames(i + 1)
  596.     Next i
  597.     NumFrames = NumFrames - 1
  598.     ReDim Preserve Frames(1 To NumFrames)
  599.     sbarFrame.Max = NumFrames
  600.     If SelectedFrame > NumFrames Then _
  601.        SelectedFrame = NumFrames
  602.     SelectFrame SelectedFrame
  603.     mnuFrameDelete.Enabled = (NumFrames > 1)
  604. End Sub
  605. ' Repaint the current frame.
  606. Private Sub picCanvas_Paint()
  607.     If SelectingFrame Then Exit Sub
  608.     SelectFrame sbarFrame.Value
  609. End Sub
  610. ' Select a new frame.
  611. Private Sub sbarFrame_Change()
  612.     If SelectingFrame Then Exit Sub
  613.     SelectFrame sbarFrame.Value
  614. End Sub
  615. ' Select a new frame.
  616. Private Sub sbarFrame_Scroll()
  617.     sbarFrame_Change
  618. End Sub
  619.