home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH5 / SRC / ROBOT.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-05-02  |  20.3 KB  |  659 lines

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