home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 3_2004-2005.ISO / Data / Zips / Bounce_off183587122005.psc / Form1.frm < prev    next >
Text File  |  2005-01-02  |  12KB  |  302 lines

  1. VERSION 5.00
  2. Begin VB.Form Form1 
  3.    BorderStyle     =   1  'Fixed Single
  4.    Caption         =   "Bounce off the walls!"
  5.    ClientHeight    =   6180
  6.    ClientLeft      =   45
  7.    ClientTop       =   435
  8.    ClientWidth     =   5955
  9.    LinkTopic       =   "Form1"
  10.    MaxButton       =   0   'False
  11.    MinButton       =   0   'False
  12.    ScaleHeight     =   6180
  13.    ScaleWidth      =   5955
  14.    StartUpPosition =   3  'Windows Default
  15.    Begin VB.PictureBox Pw 
  16.       AutoRedraw      =   -1  'True
  17.       AutoSize        =   -1  'True
  18.       FillColor       =   &H00008000&
  19.       FillStyle       =   0  'Solid
  20.       Height          =   6195
  21.       Left            =   0
  22.       Picture         =   "Form1.frx":0000
  23.       ScaleHeight     =   409
  24.       ScaleMode       =   3  'Pixel
  25.       ScaleWidth      =   394
  26.       TabIndex        =   0
  27.       Top             =   0
  28.       Width           =   5970
  29.    End
  30. End
  31. Attribute VB_Name = "Form1"
  32. Attribute VB_GlobalNameSpace = False
  33. Attribute VB_Creatable = False
  34. Attribute VB_PredeclaredId = True
  35. Attribute VB_Exposed = False
  36. 'Bounce off the walls!
  37. 'Created by Niranjan Paudyal (nirpaudyal@hotmail.com) 2/1/2005
  38. 'Please feel free to use this code as you wish!
  39. 'Dont understand something, than contact me!
  40.  
  41. 'I am sure you can find a 100 ways to make this code more faster as I have tried to
  42. 'keep everything simple and 'easy' to understand
  43. 'Enjoy!
  44.  
  45. 'HOW TO USE THE PROGRAM--------------------------------
  46. 'WHEN YOU FIRST RUN IT, CLICK WITH YOU LEFT MOUSE BUTON
  47. 'WHERE YOU WANT THE BALL TO START MOVING FROM
  48. 'IT WILL THEN START BOUNCING ABOUT LIKE A IDIOT
  49. 'CLICK ANOTHER POINT AT ANYTIME TO GET THE BALL MOVING FROM THERE
  50.  
  51. 'THE PICTURE ON THE PICTURE BOX CAN BE ANY COLOUR OR SHAPE, BUT THE AREA
  52. 'WHERE THE BALL CAN MOVE HAS TO BE BLACK!
  53.  
  54. 'Limitations of the code
  55. 'The WALLS on the picture box has to be greater than or equal to a thickness of 2 pixels!
  56. 'speed of ball has to be less than or equal to the diameter of the ball!
  57. 'The bigger the ball, the more accurate the motion!
  58. '----------------------------------------------------------------
  59.  
  60.  
  61.  
  62. Private Const Pi = 3.14159265358979
  63. Private Type PointAPI
  64.     X As Long
  65.     Y As Long
  66. End Type
  67. Private Type PointSNG
  68.     X As Single
  69.     Y As Single
  70. End Type
  71. Private Type Ball
  72.     Position As PointSNG
  73.     Vel As PointSNG
  74.     Radius As Long
  75.     Mass As Long
  76. End Type
  77.  
  78. Dim B As Ball
  79.  
  80. Dim Running As Boolean 'Is the program running?
  81.  
  82. Private Sub ChangeVelocities(B As Ball, cX As Long, cY As Long)
  83. 'ChangeVelocities(the ball in question, X position of contact with the wall, Y position of contact with the wall)
  84. 'This sub deals with the bouncing of ball off the wall
  85. 'This sub has been taken and modified from my 'bouncing balls' program
  86. 'The momemtum conservation is basically the same, however, in this program, walls
  87. 'have infinate mass and a velocity of 0, therefor, the wall will not move!
  88. 'See my 'bouncing balls' program as this procedure will make more sense then
  89.     Dim X1 As Single, Y1 As Single
  90.     Dim X2 As Single, Y2 As Single
  91.     Dim angle As Single
  92.  
  93.     X1 = B.Position.X   'center X of the ball
  94.     Y1 = B.Position.Y   'center Y of the ball
  95.     X2 = cX 'X point of collision with wall
  96.     Y2 = cY 'Y point of collision with wall
  97.     
  98.     'Get the angel between the ball and the wall
  99.     If (X2 - X1) <> 0 Then angle = Atn((Y2 - Y1) / (X2 - X1)) Else angle = Pi / 2
  100.     
  101.     hX1 = B.Vel.X
  102.     hY1 = B.Vel.Y
  103.     hX2 = 0 'This is the velocity of the wall at point of contact, note it is 0! thats because the walls are not moving!
  104.     hY2 = 0
  105.     
  106.     'resolve the velocitis such that they are along the line of collision
  107.     X1 = hX1 * Cos(-angle) - hY1 * Sin(-angle)
  108.     Y1 = hX1 * Sin(-angle) + hY1 * Cos(-angle)
  109.     X2 = hX2 * Cos(-angle) - hY2 * Sin(-angle)
  110.     'Y2 = hX2 * Sin(-angle) + hY2 * Cos(-angle)     'Left over from the Ball collision program, not needed here
  111.     
  112.     Mass = 1000000000    'This is the mass of the wall, otherewise, the balls energy will be lost to the wall and the ball will lose it velocity 'Try it by setting it to 100!
  113.     'Momemtum is conserved in the line of collision
  114.     hX1 = (X1 * (B.Mass - Mass) + (X2 * 2 * Mass)) / (B.Mass + Mass)
  115.     hX2 = ((X1 * 2 * Mass) + X2 * (B.Mass - Mass)) / (B.Mass + Mass)
  116.     
  117.     'keep the vertical component in the line of collision remains the same
  118.     hY1 = Y1
  119.     'hY2 = Y2   'This is for the wall, so ignore it!
  120.     
  121.     'resolve back the velocities to their normal coordinates
  122.     X1 = hX1 * Cos(angle) - hY1 * Sin(angle)    'For the ball
  123.     Y1 = hX1 * Sin(angle) + hY1 * Cos(angle)
  124.     'X2 = hX2 * Cos(angle) - hY2 * Sin(angle)   'For the wall
  125.     'Y2 = hX2 * Sin(angle) + hY2 * Cos(angle)
  126.     
  127.     'set the velocitie of the ball
  128.     B.Vel.X = X1
  129.     B.Vel.Y = Y1
  130. End Sub
  131.  
  132.  
  133. Private Function IsTouchingWall(BX As Long, BY As Long, BRadius As Long, ByRef rx As Long, ByRef ry As Long) As Boolean
  134. 'IsToughingWall(X position of the ball,Y position of the ball,Radius of the ball, return the X point of contact with wall, return the Y point of contact with wall)
  135. 'This sub is used to identify if the ball has crashed with the wall
  136. 'It will fo through every point at the radius of the ball and compare the color of
  137. 'those points to the color on the picture box, Pw
  138. 'if the color is not 0 (black), the ball must have crashed with the wall at that point
  139. 'For this reason, the walls must be of color other than 0
  140. 'Note that the sub will automatically detect outside the picture box because the color there is set to -1 by windows
  141.     
  142. 'If you want to speed this sub up then i suggest you use dibs to find the pixel color at the point
  143. 'I use Point because it makes the whole thing 'easier' to understand
  144.     Dim X As Long, Y As Long
  145.     Dim C As Long, br As Long
  146.     
  147.     br = BRadius * BRadius  'The hypotnuse^2 of the circle of the ball
  148.     
  149.     For X = 0 To BRadius
  150.         Y = Sqr(br - X * X)
  151.         C = Pw.Point(BX + X, BY + Y)
  152.         If C <> 0 Then
  153.             rx = BX + X: ry = BY + Y
  154.             IsTouchingWall = True
  155.             Exit Function
  156.         End If
  157.         C = Pw.Point(BX + X, BY - Y)
  158.         If C <> 0 Then
  159.             rx = BX + X: ry = BY - Y
  160.             IsTouchingWall = True
  161.             Exit Function
  162.         End If
  163.         C = Pw.Point(BX - X, BY + Y)
  164.         If C <> 0 Then
  165.             rx = BX - X: ry = BY + Y
  166.             IsTouchingWall = True
  167.             Exit Function
  168.         End If
  169.         C = Pw.Point(BX - X, BY - Y)
  170.         If C <> 0 Then
  171.             rx = BX - X: ry = BY - Y
  172.             IsTouchingWall = True
  173.             Exit Function
  174.         End If
  175.     Next X
  176.     
  177.     For Y = 0 To BRadius
  178.         X = Sqr(br - Y * Y)
  179.         C = Pw.Point(BX + X, BY + Y)
  180.         If C <> 0 Then
  181.             rx = BX + X: ry = BY + Y
  182.             IsTouchingWall = True
  183.             Exit Function
  184.         End If
  185.         C = Pw.Point(BX + X, BY - Y)
  186.         If C <> 0 Then
  187.             rx = BX + X: ry = BY - Y
  188.             IsTouchingWall = True
  189.             Exit Function
  190.         End If
  191.         C = Pw.Point(BX - X, BY + Y)
  192.         If C <> 0 Then
  193.             rx = BX - X: ry = BY + Y
  194.             IsTouchingWall = True
  195.             Exit Function
  196.         End If
  197.         C = Pw.Point(BX - X, BY - Y)
  198.         If C <> 0 Then
  199.             rx = BX - X: ry = BY - Y
  200.             IsTouchingWall = True
  201.             Exit Function
  202.         End If
  203.     Next Y
  204. End Function
  205. Private Sub GoBack(R As PointAPI)
  206. 'GoBack(Returen R is the point at which the actual collision occured)
  207.     'This sub is called when there is a collision
  208.     'If there is no collision and this sub is called, then there there will be problems!
  209.     'The purpose of this sub is the seperate the ball from the wall.
  210.     'if the ball is travelling at high speed, the ball will go into the wall, this
  211.     'Will cause problems when doing the momemtum calculations as the ball will tend to slide along the wall rather than bounce
  212.     'In order to solve this problem, 2 things have to be done
  213.     '1) ball needs to be backtracked to find when its actual point of contact with the wall was
  214.     '2) ball needs to be seperated from the wall
  215.     'To achieve this, we go from the current point of the ball, backwards along the path it came
  216.     'and location at which it no longer collides. The point just before this location is the point of contact!
  217.     Dim LastIntersect As PointAPI
  218.     Dim CurrentPoint As PointAPI
  219.     
  220.     'This little If, else is used to find how much a change in  X location of the ball affects the Y location by
  221.     If Abs(B.Vel.Y) >= Abs(B.Vel.X) Then
  222.         vs = 1
  223.         hs = Abs(B.Vel.X) / Abs(B.Vel.Y)
  224.     Else
  225.         hs = 1
  226.         vs = Abs(B.Vel.Y) / Abs(B.Vel.X)
  227.     End If
  228.     If B.Vel.Y > 0 Then vs = -vs
  229.     If B.Vel.X > 0 Then hs = -hs
  230.     
  231.     Do
  232.         'Update the position to check for collision by the above factors each time
  233.         CurrentPoint.X = B.Position.X + hs * i
  234.         CurrentPoint.Y = B.Position.Y + vs * i
  235.         If IsTouchingWall(CurrentPoint.X, CurrentPoint.Y, B.Radius, LastIntersect.X, LastIntersect.Y) Then
  236.             'If there is still collision than update the R value
  237.             R.X = LastIntersect.X
  238.             R.Y = LastIntersect.Y
  239.         Else
  240.             'If there is no more collisions, the sub must be exited, Remember that the R value will be returend from this procedure
  241.             B.Position.X = B.Position.X + hs * (i + 1)  'This is used to reset the position of the ball to a point just after when it would have first made contact
  242.             B.Position.Y = B.Position.Y + vs * (i + 1)  'Just after because sometimes it slides along the wall when it set to a point at which it just made contact!
  243.             Exit Do
  244.         End If
  245.                 
  246.         'If after a certain ammount of going back, we cant find the point at which it first made contact, there must have been some error, so just quit the sub
  247.         'otherwise, we get stuck in a loop!
  248.         If i > B.Radius * 2 Then
  249.             Exit Sub
  250.         End If
  251.         
  252.         'Update the factor
  253.         i = i + 1
  254.     Loop
  255.     
  256. End Sub
  257. Private Sub run()
  258.     'The heart of the program
  259.     
  260.     Dim Xr As Long, Yr As Long
  261.     Dim RR As PointAPI
  262.     'Check to see if program is running
  263.     While Running
  264.         Pw.Cls
  265.         'is there a collision?
  266.         If IsTouchingWall(CSng(B.Position.X), CSng(B.Position.Y), B.Radius, Xr, Yr) Then
  267.             'Backtrack to find actual point of collision
  268.             GoBack RR
  269.             'Change the speed of the ball
  270.             ChangeVelocities B, RR.X, RR.Y
  271.             
  272.         End If
  273.         'Draw the ball
  274.         Pw.Circle (B.Position.X, B.Position.Y), B.Radius, vbGreen
  275.         'Update the position of the ball
  276.         B.Position.X = B.Position.X + B.Vel.X
  277.         B.Position.Y = B.Position.Y + B.Vel.Y
  278.         
  279.         'allow time for other windows events
  280.         DoEvents
  281.     Wend
  282. End Sub
  283.  
  284. Private Sub Form_Unload(Cancel As Integer)
  285.     Running = False
  286. End Sub
  287.  
  288. Private Sub Pw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  289.     'This sub is used to set the starting properties of the ball and get is moving!
  290.     Dim rx As Long, ry As Long
  291.     B.Radius = 10
  292.     If IsTouchingWall(CLng(X), CLng(Y), B.Radius, rx, ry) Then
  293.         Exit Sub 'If the point at which the ball has been palced produces a collision, then dont bother settin the ball there!
  294.     Else
  295.         B.Mass = 2
  296.         B.Position.X = X: B.Position.Y = Y
  297.         B.Vel.Y = 3: B.Vel.X = 0
  298.         Running = True
  299.         run
  300.     End If
  301. End Sub
  302.