============================= Drop Targets - Basic Tutorial ============================= Written by shiva January 12, 2002 Code: Original by Spike Modified with a timer: cold1 Here's the complete code used in this example, as taken from the shivaengine script build1.1 Create the 3 lights, 3 targets, and 1 timer (names and settings below) then cut and paste the script in your table Rem *************************************** Rem *** Code Snippet *** Rem *** 3 Drop Targets with Delay Timer *** Rem *************************************** Rem written by Spike Rem modified by cold1 Rem Tutorial, script comments by shiva ' Create these objects for this example code: ' 3 Lights set to LightStateBlinking in the State Box, interval set at 200 ' The name is followed by a pattern setting in brackets, the number is placed in ' The Pattern box in the Options menu ' LightA {set to Pattern 100} ' LightB {set to Pattern 010} ' LightC {set to pattern 001} ' ' create 3 targets set to 50 top height, 0 bottom height ' both "has hit event" and "can drop" CHECKED in the options menu ' TargetA ' TargetB ' TargetC ' 'Create a timer, with a interval set at 1000, and enabled UNCHECKED. Name it this: ' TargetsABCTimer ' Rem ************************* Rem *** Start Target code *** Rem ************************* Rem *** Start of a Ball *** Rem Place this in the code for the start of each ball Rem Use this if you want to reset the targets Rem at the start of each Ball Sub NewBall() ResetTargets() 'resets targets at start of new ball End Sub Rem *** Hit Event Section *** Rem This code handles all of the routines for when the ball hits an target on the table. Sub TargetA_Hit() ' Target A was hit TargetA.IsDropped = true ' drop the target PlaySound "targetdropping" LightA.state = LightStateOn ' Light target A light addscore 1000 ' add 1000 points to the score TargetABCCheck() ' check to see if all targets have been hit End Sub Sub TargetB_Hit() ' Target B was hit TargetB.IsDropped = true ' drop the target PlaySound "targetdropping" LightB.state = LightStateOn ' Light target B light addscore 1000 ' add 1000 points to the score TargetABCCheck() ' check to see if all targets have been hit End Sub Sub TargetC_Hit() ' Target C was hit TargetC.IsDropped = true ' drop the target PlaySound "targetdropping" LightC.state = LightStateOn ' Light target C light addscore 1000 ' add 1000 points to the score TargetABCCheck() ' check to see if all targets have been hit End Sub Rem *** Reset Section *** Rem This code does all the resetting of the lights and the targets on the table. Rem It also resets the variables associated with those items. Sub ResetTargets() TargetA.IsDropped = false 'Target A pops up to maximum height LightA.state = LightStateOff 'Turn off TargetA Light TargetB.IsDropped = false 'Target B pops up to maximum height LightB.state = LightStateOff 'Turn off TargetB Light TargetC.IsDropped = false 'Target C pops up to maximum height LightC.state = LightStateOff 'Turn off TargetC Light End Sub Rem *** Scoring and Checking Section *** Rem This section handles the adding up of the players score as well as checking Rem for the completion of events (such as dropping all targets in a target bank). Sub TargetABCCheck() ' Check if all targets have been hit If LightA.state = 1 and LightB.state = 1 and LightC.state = 1 Then ' If they have then TargetsABCTimer.Enabled = 1 '1 = True so start timer to allow ball to clear area End If End Sub Sub TargetsABCTimer_Timer() ResetTargets() ' reset the targets and PlaySound "Targetup" addscore 25000 ' award 25,000 points TargetsABCTimer.Enabled = 0 '0 = False so the timer is switched off End Sub Rem *** End of Game *** Rem Add this to your demo attract mode, or in the routine that calls up or resets the light after the game is over Rem In the SpikeScript, the attract mode is called within the Match2() sub LightA.state = LightStateBlinking LightB.state = LightStateBlinking LightC.state = LightStateBlinking Rem *********************** Rem *** End Target Code *** Rem *********************** ============= Code Tutorial ============= As the targets were set from the original SpikeScript, the drop targets just give 20,000 points to your score every time all 3 A-B-C Targets are made. This is a very simple portion of the script, and very easy to modify. In fact, with the exception of the names and a couple pieces of extra code, you can use this for other objects as well. If you wish to use this snippet, then open a new table, and create 3 lights, and 3 targets. The Lights you should create are named: LightA LightB LightC Not much to set for the lights, though this example is set in the script to use LightStateBlinking in the State box, and a interval set at 200. For the demo routine, you need to set the pattern you need in the pattern box for each light. LightA is 100, lightB is 010, and LightC is 001. Basically, this is computer code, with one being on, and 0 being off. This sets a pattern with all three lights, that appears as the light is moving along the 3 lights. If you had six lights, you would have 6 numbers in that figure. (Example: 100000, 010000, 001000, 000100, 000010, 000001) The Interval just sets the amount of time. 200 is one fifth of a second, will 500 is half a second. 1000 is a full second The targets you need are named TargetA TargetB TargetC When you create the targets, make sure in the options menu that "has hit event" and the "can drop" boxes are dropped. Usually Targets have a setting of 50 for the Top Height, and 0 for the bottom Each light matches each target, so each target down will light the corresponding light. ************************ Breaking down the script ************************ Lets start with the basic Target Bank code. The first code to be done is to put in the basic drop target code, using TargetA as the example: Sub TargetA_Hit() ' Target A was hit TargetA.IsDropped = true ' drop the target End Sub All you are doing is telling the script that if TargetA is hit, the target, which is at it's top height of 50, is dropped to its bottom height set at 0. Now add the base score feature (addscore 1000) and the code to switch on the light ( LightA.state = LightStateOn) If you look at the Button Target code, it's almost exactly the same, except the target doesn't drop. Since you have 3 targets, you need the code for all three, and also a way to tell the script that these 3 targets are "banked" together. For that we use another sub for each Target to check as the targets go down... TargetCheck() So your code for the three targets should look like this: Sub TargetA_Hit() ' Target A was hit TargetA.IsDropped = true ' drop the target LightA.state = LightStateOn ' Light target A light addscore 1000 ' add 1000 points to the score TargetCheck() ' check to see if all targets have been hit End Sub Sub TargetB_Hit() ' Target B was hit TargetB.IsDropped = true ' drop the target LightB.state = LightStateOn ' Light target B light addscore 1000 ' add 1000 points to the score TargetCheck() ' check to see if all targets have been hit End Sub Sub TargetC_Hit() ' Target C was hit TargetC.IsDropped = true ' drop the target LightC.state = LightStateOn ' Light target C light addscore 1000 ' add 1000 points to the score TargetCheck() ' check to see if all targets have been hit End Sub ************************* Make it a bank of targets ************************* As mentioned before, each time a target is dropped, it checks a subroutine to see if all three targets are down. Since there is no way to tell the VP program that all 3 targets are a bank, you have to code it in yourself. The easiest way is to use the lights, and have the sub check to see which lights are on. (Now you know why there are lights there, there are other ways, but this is the easiest) Here's the sub: Sub TargetCheck() ' Check if all targets have been hit If LightA.state = 1 and LightB.state = 1 and LightC.state = 1 then ' If they have then ResetTargets() ' reset the targets and addscore 25000 ' award 25,000 points End If End Sub (Note the Light code LightA.state = 1. The one value means yes, that light is turned on. The other way is the standard LightA.State = LightStateOn) The sub is basically saying check if all 3 lights are On, then go here to reset the targets, and give me a big score. The ResetTargets() code could be added to this, but is a separate sub, which is also used to reset the targets and the lights at the start of each ball in the NewBall routine. All the ResetTargets() code is to reset the targets back to it's top height of 50, and to turn off the lights. Here's the code: Sub ResetTargets() TargetA.IsDropped = false LightA.state = LightStateOff TargetB.IsDropped = false LightB.state = LightStateOff TargetC.IsDropped = false LightC.state = LightStateOff End Sub Notice the difference in the target code. We are now telling the script that the Targets being dropped is FALSE, while to drop them to it's lowest height is TRUE in the code. If you wish to reset the targets, in other words have all targets "up", and all the lights turned off, then you point to this sub every time you start a new ball. Sub NewBall() ResetTargets() End Sub Because the code also includes a check for the ball in play, the NewBall sub in the script is like this: Sub NewBall() ' Puts a new ball into play If ball < (balls + 1) Then 'If we haven't played all balls then play another ResetTargets() ' Reset the drop targets Trough_Init() 'Go to routine to kick and start new ball in play End If ************** Adding a timer ************** You got the target bank code now, so it should work, but you will run into this problem very shortly. Actual Arcade machines have weight behind a drop target, so if a ball is over a dropped target that resets, the ball will just pop up a bit, and the target resets. But Visual Pinball isn't like that. The slightest hit will pop the target down, even if it was actually real. A feather tickle will drop a target. There's a couple things you can do. If you look in the table editor, you will see a couple small walls directly above and below the target bank. This is to prevent the ball from hitting the thin side of the targets, and if the angle is right, drop each of the three targets down one by one as the ball moves. (You will notice arcade games use this theory as well in different ways) The other problem is if there is a ball directly above the target as it resets, that target will be considered "a hit" by the script, and not pop up. Sometimes 2 targets do this at once, so basically, the player just gets to hit that one target that's up to collect the target bank score. This may be a happy bonus in the arcades, but it quickly becomes too easy, and gets rather boring from the loss of the challenge. The best way to prevent this is to add a delay to the targets resetting, so the ball has the time to clear away. For that, we use a timer, just like on other objects. ( Note: Some subs like the target checks were moved. Do a search for TargetABCCheck() ) You have to tell the script to start the timer delay when all 3 target lights are on, so you have to create a timer called TargetsABCTimer in the options menu. Make sure the "enabled" box is UNCHECKED, and also set the interval, or the amount of time you want for the timer to count down before resetting. We set this at 1500, or one and a half seconds for this example. There's no need to tell the script this interval, this is automatic in the program for this example. Here's the code to tell the target bank there's a timer for resetting the target banks: Sub TargetABCCheck() ' Check if all targets have been hit If LightA.state = 1 and LightB.state = 1 and LightC.state = 1 Then ' If they have then TargetsABCTimer.Enabled = 1 '1 = True so start timer to allow ball to clear area End If End Sub TargetsABCTimer is the actual timer that the script is using, so create the code for that sub like this: Sub TargetsABCTimer_Timer() ResetTargets() ' reset the targets and PlaySound "Targetup" addscore 25000 ' award 25,000 points TargetsABCTimer.Enabled = 0 '0 = False, so the timer is switched off End Sub The script just said "Check all 3 lights are on, if so, then switch the timer on, and after it's finished, then go to this routine to reset the target bank, play a sound, and give big points. Then I better switch the timer off afterwards. Note that 0 in the code means "false", while 1 is "true" The final step is for after the game is over. The SpikeScript, and the early versions of the shivaengine, which builds on the SpikeScript, places it's attract code in the Match2() sub. You may want to have a separate routine for your end of the game, or in a attract mode subroutine instead. Make sure this code is in this routine... LightA.state = LightStateBlinking LightB.state = LightStateBlinking LightC.state = LightStateBlinking A complete full script example for this tutorial is found at the top of this page.