home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / Fracas20867210102007.psc / Fracas_VB / Boom.bas < prev    next >
BASIC Source File  |  2007-08-24  |  11KB  |  345 lines

  1. Attribute VB_Name = "Boom"
  2. 'This form contains code from Boom! Particle Explosion Simulation.
  3. 'Written by Jason Merlo 10/26/99.
  4.  
  5. Option Explicit
  6. Option Base 1
  7.  
  8. 'The balls array contains the vital statistics of each ball.
  9. Dim Balls(BALLMAX) As Ball
  10.  
  11. 'Water variables dimensions.
  12. Public WaterColors(6) As Long
  13. Dim Waves(WAVEMAX) As Wave
  14.  
  15. Private Sub PrepareBallBuffer()
  16.  
  17. 'This sub simply copies the MapBuffer background picture into the PicBuffer.
  18.  
  19. Land!PicBuffer.Cls   'Get rid of that stinkin' edging problem!
  20. u% = BitBlt(Land!PicBuffer.hdc, 0, 0, Wide, Tall, Land!MapBuffer.hdc, 0, 0, SRCCOPY)
  21.  
  22. End Sub
  23.  
  24. Private Function DrawBall(i As Integer, Source As Long, Dest As Long, Shape As Integer, Color As Integer, x As Long, y As Long)
  25.  
  26. 'Now we draw the new ball.
  27. If Balls(i).Shape < 5 Then
  28.   u% = BitBlt(Dest, x, y, 5, 5, Source, (Shape - 1) * 7, 91, SRCAND)
  29.   u% = BitBlt(Dest, x, y, 5, 5, Source, (Shape - 1) * 7, (Color * 7), SRCINVERT)
  30. Else
  31.   u% = BitBlt(Dest, x - 2, y, 7, 7, Source, (Shape - 1) * 7, 91, SRCAND)
  32.   u% = BitBlt(Dest, x - 2, y, 7, 7, Source, (Shape - 1) * 7, (Color * 7), SRCINVERT)
  33. End If
  34.  
  35. End Function
  36.  
  37. Private Function DrawShadow(i As Integer, Source As Long, Dest As Long, Shape As Integer, x As Long, Newshad As Long)
  38.  
  39. 'Draw the shadow so that the ball will overlap it.
  40. If Balls(i).Shape < 5 Then
  41.   u% = BitBlt(Dest, x, Newshad, 5, 3, Source, (Shape - 1) * 7, 100, SRCAND)
  42.   u% = BitBlt(Dest, x, Newshad, 5, 3, Source, (Shape - 1) * 7, 97, SRCINVERT)
  43. Else
  44.   u% = BitBlt(Dest, x - 2, Newshad + 5, 7, 3, Source, (Shape - 1) * 7, 101, SRCAND)
  45.   u% = BitBlt(Dest, x - 2, Newshad + 5, 7, 3, Source, (Shape - 1) * 7, 98, SRCINVERT)
  46. End If
  47.  
  48. End Function
  49.  
  50. Public Sub BallTimerSub()
  51.  
  52. Dim i As Integer
  53. Dim Absorb As Single
  54. Dim Xpos As Single
  55. Dim Ypos As Single
  56. Dim Yvel As Single
  57. Dim Ytilt As Single
  58. Dim Ytiltvel As Single
  59. Dim Ystartloc As Single
  60. Dim Yshadow As Long
  61.  
  62. 'This is where we modify each ball's position based on
  63. 'the explosion's properties and global settings.
  64.  
  65. 'Step 1:  Copy the blank background over.
  66. Call PrepareBallBuffer
  67.  
  68. 'Step 2:  Ball physics.
  69. For i = 1 To BALLMAX
  70.   'Get out of this loop if there are no balls -- the most we'll have
  71.   'is a single selection arrow.
  72.   If (i > 2) And (CFGExplosions = 0) Then Exit For
  73.   'Only operate on balls that are still bouncing.
  74.   If Balls(i).Enabled = True Then
  75.     'Get the class properties so we can work locally.  Now the values
  76.     'in the class are the 'old' values, used for erasing balls
  77.     'and for shadow calculations.
  78.     Xpos = Balls(i).Xpos
  79.     Ypos = Balls(i).Ypos
  80.     Yvel = Balls(i).Yvel
  81.     Ytilt = Balls(i).Ytilt
  82.     Ytiltvel = Balls(i).Ytiltvel
  83.     Ystartloc = Balls(i).Ystart
  84.     Absorb = Balls(i).Elastic
  85.     'Apply gravity to the vertical velocity.
  86.     Yvel = Yvel + GRAVITY
  87.     'Adjust the tilt of the ball. This is used to skew the pattern for
  88.     'a 3-d type of effect.  A z-axis modifier, if you will.
  89.     Ytilt = Ytilt + Ytiltvel
  90.     'Now check if we can kill this ball because it's out of bounds.
  91.     'Note that the -5 on the Xpos check is because that is the width
  92.     'of a single ball!  Just a fudge since they were hanging over to the right.
  93.     If (Xpos < 0) Or (Xpos > Wide - 5) Or (Balls(i).Yshadow < 0) Or ((Ypos + Ytilt + Ytiltvel) > Tall) Then
  94.       Balls(i).Enabled = False
  95.     Else
  96.       'Move ball.
  97.       Xpos = Xpos + Balls(i).Xvel
  98.       Ypos = Ypos + Yvel
  99.       'Calculate the shadow position.
  100.       Yshadow = (Int(Balls(i).Ypos + Ytilt) + Int(Ystartloc - Balls(i).Ypos)) + 2
  101.       'If we went past our starting point, we need to rebound.
  102.       If Ypos > Ystartloc Then
  103.         'The ground absorbs some velocity and reverses the ball's direction.
  104.         Yvel = Absorb * (-Yvel)
  105.         Ypos = Ystartloc
  106.         'If the ball has slowed down enough, or if it has hit water,
  107.         'we will stop it altogether.
  108.         If Abs(Yvel) < (0.5 * GRAVITY) Then
  109.           'Take this ball out of service and free up a slot for a new one.
  110.           Balls(i).Enabled = False
  111.         End If
  112.         If (MyMap.Grid(((Xpos - 2) / 8) + 1, ((Yshadow - 2) / 8) + 1) > TILEVAL_COASTLINE) Then
  113.           'Take this ball out of service and free up a slot for a new one...
  114.           Balls(i).Enabled = False
  115.           '...and make a splash since we hit water!
  116.           Call MakeSplash(Int(Xpos), Int(Yshadow))
  117.         End If
  118.       End If
  119.     End If
  120.     'If this ball didn't die, we need to get its shadow position
  121.     'and copy its stats over to the class properties.
  122.     If Balls(i).Enabled = True Then
  123.       'Update the values of all the parameters in the class.  These will
  124.       'be the 'old' values on the next scan!
  125.       Balls(i).Yshadow = Yshadow
  126.       Balls(i).Xpos = Xpos
  127.       Balls(i).Ypos = Ypos
  128.       Balls(i).Yvel = Yvel
  129.       Balls(i).Ytilt = Ytilt
  130.       Balls(i).Ytiltvel = Ytiltvel
  131.       Balls(i).Ystart = Ystartloc
  132.     End If
  133.   End If
  134. Next i
  135.  
  136. 'Now update the video buffer.  Note that balls are only drawn to PicBuffer.
  137.  
  138. 'Step 3:  Draw all the shadows FIRST so that they don't overlap any balls.
  139. For i = 1 To BALLMAX
  140.   'Leave if we're only doing selection arrows.
  141.   If (i > 2) And (CFGExplosions = 0) Then Exit For
  142.   If Balls(i).Enabled = True Then
  143.     If (Balls(i).Shape < 5) Or ((Balls(i).Shape = 5) And (Balls(i).Yvel > 0)) Or _
  144.                                ((Balls(i).Shape = 6) And (Balls(i).Yvel < 0)) Or _
  145.                                (Balls(i).Shape > 6) Then
  146.       Call DrawShadow(i, Land!BallPic.hdc, Land!PicBuffer.hdc, Balls(i).Shape, Int(Balls(i).Xpos), Balls(i).Yshadow)
  147.     End If
  148.   End If
  149. Next i
  150.  
  151. 'Step 4:  Draw all the balls.
  152. For i = 1 To BALLMAX
  153.   'Leave if we're only doing selection arrows.
  154.   If (i > 2) And (CFGExplosions = 0) Then Exit For
  155.   If Balls(i).Enabled = True Then
  156.     If (Balls(i).Shape < 5) Or ((Balls(i).Shape = 5) And (Balls(i).Yvel > 0)) Or _
  157.                                ((Balls(i).Shape = 6) And (Balls(i).Yvel < 0)) Or _
  158.                                (Balls(i).Shape > 6) Then
  159.       Call DrawBall(i, Land!BallPic.hdc, Land!PicBuffer.hdc, Balls(i).Shape, Balls(i).Color, Int(Balls(i).Xpos), Int(Balls(i).Ypos + Balls(i).Ytilt))
  160.     End If
  161.   End If
  162. Next i
  163.  
  164. 'Leave if we don't want waves.
  165. If CFGWaves > 0 Then
  166.   'Animate the water.
  167.   AnimateWater
  168. End If
  169.  
  170. 'Draw the screen once a scan to keep it fresh and clean.
  171. Call Land.Form_Paint
  172.  
  173. End Sub
  174.  
  175. Public Sub AnimateWater()
  176.  
  177. Dim x As Integer
  178. Dim y As Integer
  179. Dim i As Integer
  180. Dim j As Integer
  181. Dim k As Integer
  182. Dim Resp As Long
  183.  
  184. For i = 1 To WAVEMAX
  185.   'Let's see if we can start a random new wave.
  186.   If Waves(i).Enabled = False And Rnd(1) < 0.02 Then
  187.     x = Int(Rnd(1) * MyMap.Xsize) + 1
  188.     y = Int(Rnd(1) * MyMap.Ysize) + 1
  189.     
  190.     If MyMap.Grid(x, y) > TILEVAL_COASTLINE Then
  191.       'Found a slot with water!  Make a wave here.
  192.       Waves(i).Enabled = True
  193.       Waves(i).Frame = 0
  194.       Waves(i).Count = 0
  195.       Waves(i).Speed = Rnd(1) * 3 + 1
  196.       Waves(i).Shape = Int(Rnd(1) * 8)
  197.       Waves(i).Xpos = ((x - 1) * 8) + Int(Rnd(1) * 3)
  198.       Waves(i).Ypos = ((y - 1) * 8) + Int(Rnd(1) * 7)
  199.     End If
  200.     
  201.   ElseIf Waves(i).Enabled = True Then
  202.     'Animate this one!
  203.     Waves(i).Count = Waves(i).Count + 1
  204.     If Waves(i).Count >= Waves(i).Speed Then
  205.       'We advance the frame.
  206.       Waves(i).Count = Waves(i).Count - Waves(i).Speed
  207.       Waves(i).Frame = Waves(i).Frame + 1
  208.     End If
  209.     'Now draw the wave.
  210.     If Waves(i).Frame < 6 Then
  211.       u% = BitBlt(Land!PicBuffer.hdc, Waves(i).Xpos, Waves(i).Ypos, 5, 1, Land!WaterPic.hdc, (Waves(i).Frame - 1) * 5, (Waves(i).Shape * 2) + 1, SRCAND)
  212.       u% = BitBlt(Land!PicBuffer.hdc, Waves(i).Xpos, Waves(i).Ypos, 5, 1, Land!WaterPic.hdc, (Waves(i).Frame - 1) * 5, Waves(i).Shape * 2, SRCINVERT)
  213.     Else
  214.       'This wave is done.
  215.       Waves(i).Enabled = False
  216.     End If
  217.   End If
  218. Next i
  219.  
  220. End Sub
  221.  
  222. Public Sub MakeSplash(xxx As Long, yyy As Long)
  223.  
  224. 'This function is called whenever a ball hits water.
  225.  
  226. Dim j As Integer
  227.  
  228. If CFGWaves = 0 Then Exit Sub
  229.  
  230. For j = 1 To WAVEMAX
  231.   If Waves(j).Enabled = False Then
  232.     'We'll put the splash at j.
  233.     Waves(j).Enabled = True
  234.     Waves(j).Frame = 0
  235.     Waves(j).Count = 0
  236.     Waves(j).Speed = Rnd(1) * 5 + 1
  237.     Waves(j).Shape = Int(Rnd(1) * 2) + 8
  238.     Waves(j).Xpos = xxx
  239.     Waves(j).Ypos = yyy
  240.     Exit For
  241.   End If
  242. Next j
  243.  
  244. End Sub
  245.  
  246. Public Sub ClearAllBalls()
  247.  
  248. Dim i As Integer
  249.  
  250. 'This sub cleans out the whole ball array.
  251. For i = 1 To BALLMAX
  252.   Set Balls(i) = New Ball
  253.   Balls(i).Enabled = False
  254. Next i
  255.  
  256. End Sub
  257.  
  258. Public Sub ClearAllWaves()
  259.  
  260. Dim i As Integer
  261.  
  262. 'Clean out the wave array.
  263. For i = 1 To WAVEMAX
  264.   Set Waves(i) = New Wave
  265.   Waves(i).Enabled = False
  266. Next i
  267.  
  268. End Sub
  269.  
  270. Public Sub BuildBalls(StartNum As Long, Xstart As Long, Ystart As Long, Intensity As Long, Spread As Long, AbsorbPct As Long, Size As Integer, Color As Integer)
  271.  
  272. 'This sub creates an explosion!
  273.  
  274. Dim i As Integer
  275. Dim j As Integer
  276.  
  277. 'Leave unless we know we're making a selection arrow.
  278. If (CFGExplosions = 0) And ((Size < 5) Or (Size > 6)) Then Exit Sub
  279.  
  280. 'Do this for each new ball.
  281. For j = 1 To StartNum
  282.  
  283.   'Find an empty ball slot and fill it up with info.
  284.   For i = 1 To BALLMAX
  285.     If Not Balls(i).Enabled Then
  286.       'Slot i is free.  Let's populate it.
  287.       Set Balls(i) = New Ball
  288.       Balls(i).Enabled = True
  289.       Balls(i).Xpos = Xstart
  290.       Balls(i).Ypos = Ystart
  291.       Balls(i).Xvel = (Rnd(1) * (Spread / 5)) - ((Spread / 5) / 2)
  292.       If Intensity = -1 Then 'Used for Computer turns.
  293.         Balls(i).Yvel = -11.37
  294.       Else
  295.         Balls(i).Yvel = -((Rnd(1) * Intensity / 3) + (Intensity / 20))
  296.       End If
  297.       Balls(i).Ystart = Ystart
  298.       Balls(i).Ytilt = 0
  299.       Balls(i).Ytiltvel = (Rnd(1) * (Spread / 5)) - ((Spread / 5) / 2)
  300.       Balls(i).Yshadow = Ystart + 2
  301.       Select Case Size
  302.         Case 5
  303.             'Used for Computer turns.
  304.             Balls(i).Shape = 5
  305.         Case 6
  306.             'Used for Computer turns.
  307.             Balls(i).Shape = 6
  308.         Case 7
  309.             'Used for bonus twinkles.
  310.             Balls(i).Shape = Int(Rnd(1) * 4) + 7
  311.         Case 9
  312.             'Used for small bonus twinkles.
  313.             Balls(i).Shape = Int(Rnd(1) * 2) + 9
  314.         Case Else
  315.             Balls(i).Shape = Int(Rnd(1) * Size) + 1
  316.       End Select
  317.       Balls(i).Color = Color
  318.       Balls(i).Elastic = AbsorbPct / 100
  319.       'Now fudge out of the loop and initialize the next ball.
  320.       Exit For
  321.     End If
  322.   Next i
  323.  
  324. Next j
  325.  
  326. End Sub
  327.  
  328. Public Function NoBalls() As Boolean
  329.  
  330. 'This function returns a true if no balls are active,
  331. 'and a false if even one is bouncing.
  332.  
  333. Dim i As Integer
  334.  
  335. For i = 1 To BALLMAX
  336.   If Balls(i).Enabled = True Then
  337.     NoBalls = False
  338.     Exit Function
  339.   End If
  340. Next i
  341.  
  342. NoBalls = True
  343.  
  344. End Function
  345.