This is mostly a collection of posts from Shiva Site……………..This is just easier to use, but it came from Shiva
If your creating a table this could help ya out a lot
Everythings hyperlinked below……………ahhh nice
The biggest tip of all, keep messing with the program & ask for help at Shiva
There an awesome bunch, but busy with their own tables
Decals Bonus: Counters End Of Ball Bonus
Solenoid Controlled Gates TOTAN Spinning Lamp
Targets/walls
http://www.hippie.net/shivasite/files/visualpinball/countdown/countdown.cgi?kmftofinal.zip
http://www.hippie.net/shivasite/upload/vpupload.shtml
uploaded to
http://www.hippie.net/shivasite/pages/vp_tables.shtml
Option
explicit?
Putting this at the top means you have to declare all variables. It prevents spelling errors.
Many people
had mentioned it takes them way too long to test out their creations, so I
thought I'd put this here. This will save time.
You can map any key to any subroutine in the KeyUp and KeyDown sections of the
script. Or you can set up a routine whenever the shift keys or return/enter
keys are pressed. Example:
If
KeyCode=PlungerKey then
Kicker1.CreateBall
Kicker.Kick 0,40
End If
If you need
to match a keycode with a key, add this line to the keydown routine.
Score.text=Keycode
Anyway,
whenever you press that key, it creates a ball and launches it onto the
playfield. You then have practical ball-in-hand power for testing purposes. You
can launch a ball in any direction, at any speed which is good for testing out
ramps and loops.
You can also
set up multiple kickers on the playfield. If (Scared Stiff example) to get
coffin multiball, you need to hit the left ramp, then hit the left loop. Do
that three times, and coffin multiball starts.
Now sure I
could sit there playing the table, and play it for a long time to test that
out, or I could use some kickers to do the entire sequence for me.
One kicker
above the plunger, named Test1, one kicker in front of the left ramp named
Test2, one kicker at the left ramp deposit to the right inlane named Test3, one
kicker in front of the left loop named Test4. The script would be something
like this.
Sub
Test1_Hit()
Test1.DestroyBall
Test2.CreateBall
Test2.Kick 350,30
End Sub
Sub
Test3_Hit()
Test3.DestroyBall
Test4.CreateBall
Test4.Kick 145,30
End Sub
Whenever a
ball is launched, it can't miss kicker Test1, and when I'm finished it's easy
to comment or delete the test script section and the kickers, or just move them
off the table, or disable them
Add
variables to this
dim f 'force
of kick
dim a 'angle of the kick
f = 50
a = 350
Sub
Test1_Hit()
Test1.DestroyBall
Test2.CreateBall
Test2.Kick a,f
f = f + 5 ' adds 5 to the force
if f > 90 then f = 50 ' resets the force to default
End Sub
you can change the angle the same way.
Most of your
size is probably in the graphics or sound. Makes your sounds 8 bit mono with a
maximum sample rate of 11k. In most cases this is more than high enough
quality, and can instantly cut the size of your table by 7/8th!.
As for
graphics, I like to keep the main playfield graphics at 24 bit (while many
argue that 8 or 16 bit depth suffices) but any decals or supplementary graphics
I take down to the lowest bit depth that is suitable...such as a decal on a
light... a 1 bit black and white is usually just as suitable as a higher bit
depth image, and can reduce the file size big time. In Skateball, the playfield
is 24 bit, but all the light decals are 1 bit, and the flashing 'plastics' are
8 bit. In Skyrocket all of the graphics were kept at 24 bit for clarity and
maximization of resolution, but the sounds, all being 8 bit mono 11k, kept the
file down to a reasonable size.
I find that
if your playfield picture is clear enough, you can reduce it to 256 colours
easily without any noticeable loss of quality. Since the bitmap is used as a
texture map, VP will smooth out the pixels and it won't look any different if
the original bitmap is of a high enough resolution. It makes editing and
retouching the playfield graphics that much easier too. All my table
conversions so far have used 256 colour playfields split into lower and upper
levels; the only one causing any problems so far is 4 Million BC, due to a
lower quality image to work from. But a bit of time spent with Photoshop to
tighten up the wall edges a little should sort out any difficulties. :>
start your *original* playfield
art (or any other for that matter) at a huge res.... my jetsons psd file is
1500x3000 as that is all I can do with my avail ram!
Then take that pic when it's ready
to be imprted to VP and scale it down to 512x1024 (width aproximate) But! scale
it down in seval steps.... 1500x 3000 - 1350xxx - 1100xxx - 900 etc til you
arrive at 512x1024
Play at 1280
x 960 for proper alignment.
Default
table Image size should be --- 512 by 1024
Table Measurment Used
Okay, so now
that Wpcmame was nice enough to point out to me that I had the real world ball
size wrong, here's the accurate (6% smaller) figures for sizing your WPC and
WPC95 machines. Note that these are only for these era machines and that the
System1-11 and EMs will be different.
The ball in VP is 50 units which equals 1.0625" or 27mm in the real world.
That means that your VP to real world conversion ratios are:
1" = 47 units
1.85mm = 1 unit
(Note: not nearly as clean as my mis-figure, so if you like the roundness of
the previous figures, you can think in terms of 1"=25mm=50units and then
just scale down your board and all objects by .94 when you're done. Big, big,
BIG thanks to Dorsola for pointing out that you can select all objects on a
playfield and downsize them (other than circle radii), that's a **really**
handy way to adjust a table.)
This means that the actual measurements of real world tables in VP units is:
WPC era VP Playfield Sizes:
Standard - 962x2190
Widebody - 1095x2190
The recommended size for a playfield pic remains unchanged because the ratio is
still the same as before, so to have a playfield pic be as large as possible
and still fit the playfield properly, use these sizes:
VP Playfield Pic Sizes:
Standard - 450x1024
Widebody - 512x1024
That's it for the basics, go wild from there and your ball will 'fit' to a
blueprint from a manual very nicely. Below are some revised details for sizing
of playfield objects, so read on if you're interested.
-------------------------------------
I'm still pretty unsure of how large flippers should be since it appears that
VP is using the flipper with rubber for it's sizing, so my measurements didn't
work out too well. Here's what I came up with when matching up to a blueprint
of the flippers on a properly sized board: Flippers seem to fit the blueprint
when made to be length 128, base radius 23.0 and end radius of 9.5. The secret
to properly emulating Fliptronics-era flippers seems to be in higher speed and
lower speed than the defaults. The figures of 0.11 speed and 2.1 strength that
Dorsola and Metallik suggested in the TZ mods seem to work pretty well. For 80s
and EM pins, the default 0.08 speed and 5.0 power work quite well.
Most rubber rings would be about 12 units (1/4") wide, and even though in
the real world, they actually make contact with the upper part of the ball
before the midpoint, Randy pointed out that the behavior of the ball when it
hits a surface that isn't connect with it's midpoint is currently undefined in
VP, it's a good idea to make sure your rubber rings cross the 25 unit area.
I've been using a rubber height of 24 to 36 units and that seems to look pretty
good in the game.
A standard post would be 50 units high and plastics are sitting about 60 units
off the playfield.
Even though these figures do seem a bit odd, I have to say that they make a
world of difference when laying out the playfield. My previous figures made the
game play much better with my Indy500 table, but downsizing it by 6% to hit
these figures was really cool and just nailed the 'feel' of the table!
Limit Size of Bitmaps in VP
I beleieve
the problem is the actual image size since I've succesfully loaded 500x1000
images that had huge filesizes, yet have been unable to import a playfield with
a similar file size, but larger image size.
The trick
I've used to keep as much detail as possible is to start with an image of
1562x2135x32 @ 300dpi. If an image has to be resampled to get to that size, I
make sure that any anti-aliasing is disabled, and continue not allowing any
anti-aliasing throughout the edit. When that is scaled down to 96 dpi (which
looks much better when rendered than 72 dpi) it becomes a perfect 500x1000.
This downsampling is the first stage where I turn anti-aliasing ON. Using this
method, the smaller resolution image loses very little detail from the
original, and edges of images turn out beautifully smooth.
It's still
not as good as it would be to use the full size image but it at least makes the
downsizing much less "lossy".
Table Graphics
How does
one go about making Sling-shot bumpers like in the older Pinball tables
two walls on
top of each other.
Set the
high wall at 39 - 40
Set the
second one 18-30 and make it a different color. Stretch the control points a
few pixels outside and make it slingshot. Should do the trick.
Draw in
Back really does have a purpose
Using other stuff for moving graphics
You could
use transparent text boxes too if you wanted - since the background has a
graphic - not sure how that would work out for you.
For a ball image though, you'd place a kicker outside the table and create a
ball in it - and with a timer you can change the image so it animates - using a
few kickers you could get the explosion, and the bullet flying across the
table.
Since droppable walls provide similar functionality, those have been popular up
to this point. The new Monster Bash using balls for animation of dracula, and
Indiana Jones redux uses them to simulate drop targets. The temple table uses
custom images for the gems. Pagan Pinball uses a ball image for the bubbling
cauldron. Besides those, I don't think much work or research has been done on
it in the area of animatrion. (Rock Fantasy has nifty animation for the ball,
but that's just for the balls themselves - not trying to animate other stuff)
What does
the pattern property of a light do? |
A pattern is just that, a
pattern. "1\" represents on, and "0" represents off (of
course if you were a computer, everything is represented that way)...so you
have a light and you want it to blink "on,off,on,on,off,off,on,off"
then the pattern would be "10110010", now you may ask why you'd
want that, so consider that you have three lights that you want to blink in
in sequence...the patterns would be: |
Changing colors during game play
You can put
two lights of different colors on top of each other. When you want to change
colors, turn the old light off and the new light on in that order. The light
you last changed the state of will remain visible on top.
Or you
could use droppable walls.
In short,
assign a variable to a group of objects (Lights) and/or their perimeters
(events)? So that Dim A controls Sub
Spinner1_Spin() in order
to light Light1-10 (think Bonus) I used
brackets because parenthesis are confused with an array (that's what the
error message says). |
Sort of. You
have to declare an array of controls first, like so:
code:
Dim A
Dim SpinnerLights(10)
Set SpinnerLights(1) = Light1
Set SpinnerLights(2) = Light2
Set SpinnerLights(3) = Light3
Set SpinnerLights(4) = Light4
'etc.
Sub Spinner1_Spin()
A = A + 1
If A > 10 Then A = 1
Light(A).State = LightStateOn
End Sub
It's tedious if you have a lot of lights, but it works. See just about any table for an example. I think Top Speed (that comes with VP) uses this technique. That's where I learned it.
There are several
ways to do it. The easiest one is to create a collection. Go to the collection
manager and create a collection called "LightsCollection" and put all
your lights in there. Then you can do "LightsCollection(1).State"
etc.
The only drawback is that you can't change the order in the collection so put
them in in the right sequence from the beginning.
If you don't want to
use collections you can create an array in the script.
Dim LightsArray
LightsArray = Array(Light1, Light2,Light3)
xxxxxxxxxxxxxxxx
On my table, I have
a set of lights which light in sequence each time a particular bumper (of which
there is more than one) is hit. When I programmed the bumpers, I put an
"if" for every possible permutation . e.g.:
if x=1 then
light1.state=light.stateon
end if
if x=2 then
light2.state=lightstateon
etc.
I have 12 lights-
and 5 bumpers- and I've copied and pasted the list for each bumper_hit
subroutine. It works fine, but is there a way that you can program the script
so that the application knows automatically what to do if x=N?
So, for example,
input all of the possible states in once only, and point all of the bumper_hit
subroutines at that subroutine.
I think what you need to do is make
arrays of your lights and bumpers. That way you can index them. Define two
arrays:
Dim LightArray(11)
Dim BumperArray(4)
Then in the table's
init-method, make the arrays point at the objects:
Set
LightArray(0)=Light1
Set LightArray(1)=Light2
....
Set LightArray(11)=Light12
And the same for the
bumpers. Note that arrays start at zero, so an array with 12 elements has
indices from 0 to 11.
Now you can call one
bumper subroutine from all bumperX_hit, using the number of the bumper as a
parameter if you need to distinguish them:
Sub Bumper1_Hit
BumperStuff(0) 'numbering the first bumper zero here
End sub
To set a light based
on a your x (if x starts at 1):
LightArray(x-1).state=LightStateOn
I want to write a formula
(possibly polar coordinate orientated)
That uses a kicker to speed the ball up, but maintains the direction.
I'm not such a Math wizard (surely you're understating!)
Does anyone know a good formula for this?
It must look as if the ramp simply isn't that steep.
Just multiply all of .Vel's with the same constant,
say 1.1 or 1.2.
When you preserve the direction, no polar coordinates thing is necessary.
boostFactor = 1.2
With ActiveBall
.VelX = .VelX * boostFactor
.VelY = .VelY * boostFactor
.VelZ = .VelZ * boostFactor
End With
P.S.
You don't need a kicker. A trigger would suffice for this purpose.
Changing Color
You must have the absolute latest Tech beta 4 and then do Kicker.CreateBall.Color
= x Note that
it does not set the colour of the ball, just the tint. |
Plunger.CreateBall.Image =
"YourBallImageNameHere"
Sub Kicker1_Hit()
ActiveBall.Color = RGB(255, 0, 0)
End Sub
The order of the
numbers = same as color control in the Windows "Paint" program.
Seems to work with all Hits; Triggers too.
hmm...Does the wall drop? Can't put a
decal on a droppable wall.
Also JPGs don't make very good decals - I don't like using them that way.
So check the surface property of your decal.
By check, he meant check it for
something (look at it). If you select your decal in the editor and the options
bar is showing you will see an option "surface". By selecting a wall
from the drop down list, the decal is placed at the height of that wall.
A question, though.
Since you weren't familiar with the surface property, did you really do a
decal? It sounds to me that what you might have done is imported your picture,
then set the image property under the options for your wall to that image. The
image property for walls assumes an image the full size of the table, not part
of it. Your picture would have been stretched to fit the whole table, and the
part that would show on the wall would just be that portion of the stretched
image where the wall happens to be located. That would explain why you're
getting only blue fuzz.
So you have two
options (I recommend option#1):
1) Create a blank image the same size as your playfield image (512x1024 or
whatever) and paste your picture onto this in the location where the wall is,
and use that for the image property of your wall.
2) Put a decal on the table with the decal button on the left of the screen (it
should show as a blue square in the editor). In the options for the decal, make
sure the "Type" option says DecalImage, set the Image property to
your picture (the original, not the full table blank), and the Surface property
to the name of the wall you want the decal on. Then make sure Sizing says
ManualSize and adjust the Width and Height to make a rectangle that frames your
wall.
Do decals not show up
on a droppable wall?
Just making sure that
I'm not going insane...
Is there any other way to get an image on a droppable wall besides making the image part of a whole-table image layer and setting the wall to display that full-table image?
You can place a decal
on top of a droppable wall by selecting the wall from the "Surface"
list in the Options for the decal. The only problem is that the decal doesn't
drop with the wall, so it is left floating in air when the wall drops.
So yes, as far as I
know if you want the image on top of a wall to drop with it, you have to use a
full table image.
Decals on Ramps
I'm having
a problem placing a decal on a ramp. Duh. I have a decal
that goes the entire length of an upward-sloping ramp. I've got the decal
sized right and everything. However, only the bottom part of it shows on the
ramp, like this. What am I doing wrong? |
on the decal's
surface property - set it to the ramp. Currently it defaults to table level
which the ramp covers up.
so you set the decal to the ramp
height?
Make a wall as high
as the ramp is, or 1 unit higher then and set the decal surface property to
that wall.
Borrowing some ideas from
Berimon Aghar Truesilver's Transformers table and several other tables that use
the "plastics lighting" trick, I've whipped up a quick demo that
should be of some interest to original table designers. This example shows a
technique that can be employed to create animations on the playfield surface of
a table. This example is of a very simple five-frame animation controlled by a
timer, but the technique being used could be set off by an event trigger just
as easily. I have also illustrated an apparently unintended consequence that I
discovered working on this: bumpers that are invisible except for the shadow.
Depending on your table, this could either be a useful idea, or something to
watch out for.
The .VPT example I have created can be found : here
(Tm_Test1). I didn't bother commenting the example, but it shouldn't be too
difficult to understand. Let me know if you have questions. To adjust the
animation speed, adjust the value of the timer to the left of the table.
Save
as
Mp3-Mpeg layer 3
Wav-windows pcm
To
Soft/Loud
Sometimes, the
volume of a VPinMAME game is too loud or too soft for you tastes. There are two
different ways of changing the volume which depends on what type of game it is.
If it's a Williams/Bally game using the DCS system, then you'll have to open
the coin door (End key), and use the service keys:
7 8 9 0
Escape - + Enter in Menu
Srv. Crdt - + Enter otherwise
Don't enter the menu
(if you did, just hit Escape (7) until you're out of the menu) -- just use the
8/9 keys to adjust the volume. If you set it to maximum, there is the
possibility of distortion.
If the game is not
Williams/Bally DCS, (i.e., every other game), you'll need to use the MAME menu
-- click on the PinMAME window, hit the key beside the 1 (tilde on US
keyboards), and you'll see a little text box shown on the DMD. Use the up/down
arrow keys to pick the various settings, and use left/right to alter the
volume. When you're finished, hit that key again (tilde) to clear the menu, and
click on the VPinball Player window (the pinball table).
Help turning sound off in sub to play
once
To stop a sound that's currently playing use: StopSound
<sound name> |
I only want the sound to play once after the wall is dropped,
but after the wall is dropped each time the ball hits a trigger the
"boing" is played
sub checktriggers
if light1.state=lightstateoff and light2.state=lightstateoff and
light3.state=lightstateoff then
block1.IsDropped = false
if block1.isdropped = false then
playsound "boing"
end if
end if
end sub
I tried lots of stuff but I'm out of ideas
heres the rest of the script that calls checktriggers
Sub trigger1_Hit()
playsound "swoosh"
light1.state=lightstateoff
addscore(25)
checktriggers
end sub
Sub trigger2_Hit()
playsound "swoosh"
light2.state=lightstateoff
addscore(25)
checktriggers
end sub
Sub trigger3_Hit()
playsound "swoosh"
light3.state=lightstateoff
addscore(25)
checktriggers
end sub
I just gave your routines a really quicky glance but you don't
need the second "if then" in your checktrigger routine.
Instead just make it
sub checktriggers()
if light1.state=lightstateoff and light2.state=lightstateoff and
light3.state=lightstateoff then
block1.IsDropped = false
playsound "boing"
end if
end sub
Doing that the "boing" will only play if light1, 2 and
3 are off.
if that's not quite what you want (hard to read a segment out of
context), then adding another variable should work, such as...
sub checktriggers()
if light1.state=lightstateoff and light2.state=lightstateoff and
light3.state=lightstateoff then
block1.IsDropped = false
playit=true
end if
if playit=true
playsound "boing"
end if
end sub
you could include playit=false in each of your trigger_hit
routines. to ensure that the sound only plays if all the lights are off AND the
wall is dropped.
Don't forget to dim playit.
Q:Sound Looping
A:
leave the sound as .wav and loop it via
playsound "music" ,-1
stop it using
stopsound "music"
that´s the only way for nice looping
music right now
0
is infinate sound
LoopCount is optional... 0 is
infinit, i think. 2, i think will play the sound twice... Volume, i don't know
how that works, but it's optional too.
Anyway:
PlaySound TheSound, 0
that may play TheSound until you finish the table or you use StopSound
TheSound.
Save Mp3 in stereo or they play fast 160
Can Music Be Looped USES(to
cut mp3 size down)
You can fake it reasonably well if
you break your mp3s into three parts - intro, loops, ending. Each part is a
separate file, perhaps music-intro.mp3, music-loop.mp3, and music-end.mp3.
When you play your
music, you first play music-intro.mp3, then loop play music-loop.mp3 over and
over again until something forces it to change to music-end.mp3, signalling the
end of the song.
Try this after you have your
PlayMusic"musicfile.mp3" in you code then have this....
Sub Table1_MusicDone()
PlayMusic"musicfile.mp3"
End Sub
Or you could take a look at my Psycho 1.3 and it has this in there for a
reference.
Hope this helps.
I actually got the music working from
the psycho script
but I wasnt sure what the
Sub Table1_MusicDone() was for
Table1 is the name
of your table, it starts as Table1, but many people change it.
When the mp3 stops,
it goes to this sub. So for example by placing the
PlayMusic "filename.mp3"
End Sub
there it would play
filename.mp3 when done playing the other mp3.
To take it one step
further which I did for my table, if you want to add different music to
different things, like attract mode, in game play, high score, multiball etc,
you can set a variable such as
DIM music
then after each
event use
music =
"filename.mp3"
PlayMusic "filename.mp3"
Where filename is the name of the file to play for that portion such as attract
mode, multiball etc.
In the sub for
endmusic, change PlayMusic "filename.mp3" to
PlayMusic music
and it will then
play the current music over and over when its done, but allows you to change
which music to play when the music is done.
When you go to another mode, such as when the game ends, I just
use the EndMusic to stop whatever was playing, and then set music and PlayMusic
to the new music, which again will repeat when done if you have the PlayMusic
music in the endmusic sub.
You can even take
this a step further which I havent yet had to do such as playing from a
selection or rnd selection of music. You would just create a select for what
sets the music variable, this is done at the point of the playmusic. The
endmusic will automatically repeat that one since it will play the music set to
the variable.
This would work well
for example for mario teeshot if he wanted to change to mp3, or a similar
reason where you want to play multiple choices of music or multiple different
music one after another during for example in game play.
Enjoy! My Super
Android table uses this, it should be released very shortly, havent had much
time until now to work on it again.
For TB4, here are some helpful music
tips, from basic to more advanced:
To play a mp3 music
file as background music, you would place the mp3 file in the /music sub
directory, in the script you would call it using in the script:
PlayMusic
"android.mp3" where android.mp3 is the name of the music file to
play, and the .mp3 is needed.
This would play the
file ONCE then stop.
To Stop the Music
File in Mid Play, such as at a game over or ball end you want no music to play
anymore, you use the
Command
EndMusic
You don't need to
enter the song title, only that command using that case exactly. This stops the
music but doesn’t hold
The place it was in the file- if you start this or another song using PlayMusic
again it starts from the beginning.
To Repeat the exact
same music file after the complete music file plays, simply add a subroutine in
the script:
Sub
Table1_MusicDone()
PlayMusic "android.mp3"
End Sub
Where android.mp3 is
the exact same filename as the original. The above is if you use only one
single music file total in the table to play once or repeating. If you want to
play more then one music file in different
Parts of the table or multiple files one after another, see more advanced
below.
More Advanced: How
to play multiple music files, such as one music file that can repeat in attract
mode, a different
One that can repeat in in game music, a different one that can repeat during an
event like multiball etc...
This is NOT for
playing multiple files one after another, this is for playing different files
at different times, repeating the looping of the correct file when its done
playing based on where you currently are in the board (otherwise you'd always
play the wrong file when the current music file ends).
First you dim a
variable, I use Song, so you add:
Dim Song
To the variables at the top of the table.
Next add the
following sub routine:
Sub
Table1_MusicDone()
PlayMusic Song
End Sub
Then, at ANY point
to play whatever music you want for that period of time you would use:
EndMusic
Song = "android.mp3"
PlayMusic "android.mp3"
Where android.mp3 is
the name of the file to play during that part of the table.
For example, I use the above during attract mode, so that it will now play
android.mp3 during attract mode, and
Whenever it finishes it calls the sub Table1_MusicDone, and plays the correct
android.mp3 again since I've set
Song to that filename as well.
When you go into the
in game music, I use:
EndMusic
Song = "android1.mp3"
PlayMusic "android1.mp3"
Now it immediately
stops any current music playing (this is why you can use this at any event
also, as say you JUST hit
Multiball, you can stop the current music and immediately change the music to
play and repeat).
Then starts the new song android1.mp3, and whenever the file stops it will
replay the correct song, in this case android1
And NOT the song used in another mode such as android.mp3 which I was using in
attract mode only. This is very flexible
As you can stop and play different songs at different times, and repeat the
correct music.
This mode is NOT for
playing one after another after another, or random song choices, changing Song
= to another name will play that song after the first is done, but then would
just repeat that 2nd song, it wouldn’t allow a 3rd, 4th etc or even to go back
to the 1st song during that same mode using these routines.
This could be taken further if you
want to play multiple music files one after the other during the same event,
such as playing 3 files one after another during in game play not related to
event changing (which the above advanced routine does that), by setting up a
routine within Table1_MusicDone that would step to another song based on what
played before, then every time its called it should check what played before to
decide what to play next. This is easy coding but I havent had the need to use,
as all my music changes are related to event changes, such as playing an in
game music then you get a multiball or other event reason to change the music,
or going from in game to game over (and therefore attract music) which uses the
above Advanced routine. If anyone uses this, feel free to add to this to give a
code example for someone else.
How do I
loop my tables background music? |
Leave the sound as .wav
and loop it via playsound "music" ,-1 |
Can triggers destroy
balls?
A trigger can not destroy a ball.
CAN TRIGGERS PLAY 3 SOUNDS
You could use timers.
Timers are a little
bit hard to wrap your head around at first but get to know how to use them, and
you can do anything.
The basic concept is
this...
A timer is comprised
of the timer itself, an event subroutine an interval setting, and a state
(enabled true/false). When a timer is first activated(with
"timername.enabled=true", it will wait for the assigned interval to
pass before executing anything in it's subroutine. It will then repeat the
commands in a loop until it is told to stop "timername.enabled=false".
When it disabled "enabled=false" it will stop as soon as the current
interval length expires. Ofcourse the interval length can be set on the fly, so
it can be sped up or slowed down as required.
Every object on your
table has timer built in that you can make use of, the only difference being
that the state is "timerenabled" true/false rather than
"enabled" true/false as it is with an actual timer object.
Timers are best
learned by playing with a few of them, so I suggest you start with a blank
table and try a couple things before using them in the table that you're
working on.
Most VPtables that use kickers use timers for sound and kick timing, so a quick
look at any of these should help you out.
Like anything else
though experimentation is the key.
Then a timer is
exactly what you need...
set the timerinterval for the length of the sound (1000 = 1 second, so if the
sound is 2.5 seconds, the interval would be 2500)
three sounds with a
space (first space 2.5 seconds, 2nd space 1 second) between could be achieved
like this...
sub kicker1_hit()
playsound "1stsound"
c=0
kicker1.timerinterval=2500 (you could have this set in the option screen
instead if it's never going to change)
kicker1.timerenabled=true
...insert anything
you want to happen with the first sound here...
end sub
now you have to have
a routine for your kicker's timer, remeber, nothing in this sub routine will
execute until the interval has passed at least once...
sub kicker1_timer()
kicker1.timerinterval=1000 (changes the interval for the length of the second
sound...this WON'T happen until the original 2.5 seconds have passed)
c=c+1 (count how many times the timer had looped)
if c=1 then (first loop through...actually the second, since only your 1st
sound played during the first)
Playsound "2ndsound"
...insert anything
you want to happen with the second sound here...
else (the timer has
looped, cause "c" has changed value)
kicker1.timerenabled=false (shuts off the timer, so it doesn't repeat again)
Playsound "3nd sound" (your 2nd sound is already over because of the
timer)
...insert whatever
you want to happen with the third sound here...
end if
...insert anything
you want to happen with EVERY timer cycle (play with some lights?)
end sub
Just remember, that
everything else in your script is still running while the timer
executes...since your timer would be for a kicker, there's not much to worry
about, since the ball isn't moving around the table.
Using a few timers
together can accomplish some complex tasks easily, but just make sure you always
do a "timerenabled=false" for any timers you're not using, or any. If
you don't want the timer to repeat more than once, make it the very first line
in the timer routine.
How high of a ramp are
we talking here? The default glass height in VP is 210. If your ramp is too
tall, the ball could be hitting the top glass. You can change the glass height
from the options for the table. Make sure it is at least 50 units above your
tallest ramp.
|
||
|
Either I have done this wrong or the rnd() function is a crock!!!
The user should be getting a random award. I just shot 70 shot and got ZILCH every damn time
if CastleShots > 40 then
dim mystery
mystery = rnd(10)
if mystery >= 0 and mystery < 2 then
Instructions.Text = Instructions.Text + "ZILCH"
end if
if mystery >= 2 and mystery < 3 then
Instructions.Text = Instructions.Text + "20 MILLION"
AddScore(20000000)
end if
if mystery >= 3 and mystery < 4 then
Instructions.Text = Instructions.Text + "10 MILLION"
AddScore(10000000)
end if
if mystery >= 4 and mystery < 4.3 then
Instructions.Text = Instructions.Text + "100 MILLION"
AddScore(100000000)
end if
if mystery >= 4.3 and mystery < 7 then
Instructions.Text = Instructions.Text + "5 MILLION"
AddScore(5000000)
end if
if mystery >= 7 and mystery =< 10 then
Instructions.Text = Instructions.Text + "BONUS AWARDED"
AddScore(Bonus)
end if
end if
TextDisplay.Enabled=True
end sub
same line is in my music selector and it works perfectly for me and plays both of the options for BGM
You need this near
the beginning of your script.
RANDOMIZE
Then to use RND for a
number between 1 and 10, you'd use this.
variable=CINT(RND*(9)+1)
While this works variable=CINT(RND*(9)+1),
is this not the same as CINT(RND * 10)?
This is what I would
have put when programming in VB.
CINT (RND*10) allows
for rounding -- that would give you a possibility of getting 0.
Nope, not the same.
The first case selects a random number between 1 and 10. (Rnd*9 returns a
random floating-point value between 0 and 9, not including 9.0. Then you add 1
to it and round it to the nearest integer.)
The second case picks
a random number between 0 and 10.
Another possibly less
confusing way to write the first statement would be: variable = 1 + CInt(Rnd*9)
Okay, that I under
stand, but SDB's example went from >=0 to =<10, which as far as I can see
is 0 to 10.
I don't consider
myself a wonderful programmer, but that is how I interpreted the request.
Hey, if RND(10) works
for you, go for it. I'd prefer (feel better about the script) if it
was RND*10. I don't trust the parenthesis to work as desired.
For 0-10, just drop
off the +1 on the line.
How do I place a
bumber, or gate, or for that matter anything on a platform not on level zero?
Create a wall at the
height you want the bumper or gate and in the surface property box select the
wall you want the bumper to sit on.
but be careful with
kickers...hehe...unless they are on the actual surface you're using it might
work sometimes, and not work other times....
see attachment.
How do you make a slingshot
Select a control
point, then right click on it. Two choices will pop up smooth and slingshot.
Click on the word slingshot.
How do I
make a slingshot? |
Place a wall on the table.
Shape the wall how you want your slingshot to be. Select the wall, and then
select a control point with the right mouse button. Two choices will pop up
smooth and slingshot. Click on the word slingshot. That will convert the wall
into a slingshot. |
Declare a variable
for it.
Dim CurrentBall
In your
"drain_hit()" section, add one to this, and if it exceeds your
maximum number of desired balls, you'll want to call your end of game routine.
You'd also want to
set this variable to 1 when you start the table.
If you award extra balls,
you'd need to subtract 1 from it before you check to see if the game is over...
If it wasn't way past my non-existent bedtime, I'd write a
longer reply, but here's a few basic guidelines: -For a really
basic multiball (e.g. one where all balls are put into play at the beginning
of the MB, and all extras are drained when the MB ends) Keep a variable that
keeps track of how many balls are currently on the playfield (I usually use
nBallsInPlay for this purpose.) Ensure that every function that can create a
ball increments this count, and every function that destroys a ball (or,
depending on what you're doing, the Drain_Hit() event reduces this count.
When this count reaches zero, you end the current ball and start a new one as
appropriate. -For what
it sounds like you're trying to do (hold balls in kickers to be released when
targets are hit) you'll want to keep two variables: Total balls on the
playfield, and balls in play (which would be one except when a multiball is
active.) In this case, I'll call thse two values nBallsInPlay and
nActiveBalls. When a ball is first put into play, you would increment both
counts by one (note that I'm not writing actual script here, and this is for
illustration purposes:) nBallsInPlay
= nBallsInPlay + 1 = 1 If this
one ball in play drains, both counts would be reduced to zero, at which point
the drain_hit() event would use an if statement to see that no balls are
active on the playfield, end the ball with bonus (or whatever) and start a
new one. But say that ball goes into a lock: nBallsInPlay
= 1 since
there are no active balls on the table, hitting the lock should trigger a
CreateBall on the plunger, which would increment both counts: nBallsInPlay
= nBallsInPlay + 1 = 2 Now we
have one ball in the lock and one ball in play. If the ball in play drains,
nActiveBalls gets reduced to zero again, and the ball ends. But if the
trigger to release the ball is hit, this releases the second ball into play
and increments the nActiveBalls value: nBallsInPlay
= 2 When one
of these balls is drained, both counts drop by one: nBallsInPlay
= nBallsInPlay - 1 = 1 ...Which
puts back to a single active ball on the playfield. In short: -Have the
plunger (or any other item that creates balls and puts them in play)
increment both counts; If none of
this makes sense, feel free to ask questions. Again, I'm writing this at 1:30
in the morning, so coherence isn't exactly my strong point right now. |
but the major one is
that I can't get it to kill the Multiball...the program recognizes the second
ball (the Multiball) as a normal ball and when it goes down the drain even
though I have the "If Multiballs > 0 Then Multiballs = Multiballs -
1" and the DestroyBall thing. Could I possibly put a trigger in front of
the drain that when hit it would destroy the ball if you had a multiball?
Without seeing the
script, this is sort of tough.
Make sure at the
beginning of the script you have Dim Multiball.
Somewhere in your table init you have Multiball = 0, also have this when when
you reset the table for a new ball.
I'm going to assume when you add a ball in multiball, you also added
multiball=multiball +1 to whatever kicker or plunger created the ball?
Check spelling.
Before you have "if multiball>0 then " put multiball=multiball-1
then put your if statement.
You always
want the program to know how many balls are in play on the table. Whenever a
ball is locked, that needs to be known as well. Whenever a ball leaves play.
For multiball, if you have 60-ball multiball (gasp) after 59 balls leave
play, you know multiball has ended. |
In your drain routine does it check
to see ballcount?
If multiball then
subtract one ball otherwise advance ball in play.... (?)
What variable do you
use to keep track of the numberof balls on the table???
Soon we will have
transparent ramps...but until then, like I did on Scared Stiff, setting the
ramp color to the background color will make them barely-visible near the back
of the table.
For the ramp leading from the coffin, that is actually using a wall at 55 units
above the table. The base of the pinball diameter is 12.5 units, and as long as
your wall is 12.5 units or wider, the ball will go over it just fine. The
pinball is approximately 48 units from bottom to top or across in any
direction. So based on this, provided you have a wall on each side of the
bottom wall 'ramp' at about +25 and -25 horizontal distance from the ball
center location, and -24 to -26 units from the top of the ball, this will hold
it in place. The downside to using this which makes it so difficult is if the
ramp is on an incline. Placing walls in layers is very time consuming.
For any ramp,
transparency can be achived by placing a decal about 50 units abobe the top of
the ramp. As long as a wall is not under the decal (between the ramp and the
decal), the ramp will be hidden, and the ball will be drawn on TOP of the decal
image -- thereby pulling off the effect successfully. This is partially
portrayed over the left ramp entrance -- a decal is between the top of the ramp
and the bottom two wires -- the bottom two wires are hidden by the decal while
the top two remain visible.
12.5 is much more accurate than 13.
But for ramps, you want the wall at +24 to +26 -- possibly higher to stop the
ball from flying off the ramp if it does become airborn.
from the
bottom of the pinball to the lowest possible point of contact with a wall
which will impact ball movement, is 12.5 units from table level (0) The
pinball is 48 units high, and 48 units wide. Therefore, the center point of
the ball would be approximately +24 to +26 from the current ramp height. ie - you
have a ramp going from 0 (table level) to 100. At the top of the ramp, a
'sidewall' at bottom height of 124 and top height of 126 will keep the ball
on the ramp. Adjust the top height of the side wall based on how fast the
pinball tends to go up the ramp and the incline of the ramp. This also
prevents slow balls from falling off flat ramps too. |
Today's lesson in VPINMAME scripting: Solenoid Controlled Gates
There are many ways
to handle a solenoid controlled gate, but some ways are better than others. To
understand how to best model such a beast, you must look at what the effect of
it is. If a ball aproaches from the pass-thru side, it always goes through. If
a ball approaches from the other side, it only goes through if the solenoid is
Enabled.
Now since gates
cannot be dropped or lifted, we must use a Wall object instead. But how will
Visual Pinball know if a ball is approaching it? There needs to be a hidden
Trigger next to it. And, since you need to know which side the ball is
approaching from, there should be one on each side.
So we have our gate,
a wall called SolGate1. And we have the inner and outer triggers, InnerTrigger
and OuterTrigger. First, let's write OuterTrigger_Hit. This one is simple.
Sub
OuterTrigger_Hit()
SolGate1.IsDropped=True
End Sub
This drops the wall
whenever a ball approaches from the ouside. Now we have to write
InnerTrigger_Hit. This one is trickier. (note some people may use a Timer
instead of an inner Trigger, but this is a kludge that causes slow moving balls
to bounce off, and really fast ones to bounce out.) What it needs to do is
raise the wall, but only if the solenoid is disabled. So our preliminary
version looks somewhat like this.
Sub
InnerTrigger_Hit()
If Controller.Solenoid(sGate) then
SolGate1.IsDropped=True
Else
SolGate1.IsDropped=False
End If
End Sub
But we can do better.
Notice that with either case, the state of IsDropped is assigned to the same
state at the solenoid itself? This means we can dispense with the If statement
entirely! So our new, optimized code is.
Sub
InnerTrigger_Hit()
SolGate1.IsDropped=Controller.Solenoid(sGate)
End Sub
If the solenoid is
on, the wall is lowered. If the solenoid is Off, the wall is raised. "But
what about the solenoid handler?" I hear you ask. IT IS NOT NEEDED. The
ONLY time Visual Pinball needs to know the state of that solenoid is when a
ball approaches from the inner side, and our subroutine takes care of that. But
if you really want to add the solenoid handler, it's very simple.
Sub
GateSolenoid(Enabled)
SolGate1.Isdropped=Enabled
End Sub
This way, you will
see the gates go up and down before a ball approaches.
So to recap, here's
our code.
Sub
OuterTrigger_Hit()
SolGate1.IsDropped=True
End Sub
Sub
InnerTrigger_Hit()
SolGate1.IsDropped=Controller.Solenoid(sGate)
End Sub
And, optionally.
Sub
GateSolenoid(Enabled)
SolGate1.Isdropped=Enabled
End Sub
Yup, each subroutine
is a one-liner, and NO timers are used. You can't write better code than this.
Every situation that can come up is handled properly by the first two one line
subroutines. If two balls approach, they will either bounce off the wall, or
bounce off each other. Which is the case DOES NOT MATTER because the effect is
the same.
When proper liftable
gates are implemented in VP, you can remove the triggers, and their associated
hit routines, replace the wall with a gate, and just use the solenoid handler
to drop or raise the gate.
What is
the height of the bumper object in VP? |
The height of the bottom
part of the bumper is 40. The top section of the bumper (the overhang) is a
height of 20, making a total height of 60. |
Re:How do you get your bumper lights to stay on?
If you set the bumper
to LightStateOff in the UI, then when you set it to LightStateOn in the script,
it will actually work. Some kinda bug. But not as annoying as the "rename
a new item twice = crash" bug. I lost quite a bit of work at least once
because of that. Now I save every 5 minutes.
Or add a light on top of bumper
RE:Bumper
heights
I'm making sea wolf and i need to build a bumper out of walls so it can drop.
What is the height of the base of the default bumper and the height top and
bottom of the overhang part??
In STTNG I had to put
a ramp over a bumper...the ramp was at 65 units. That's how high a bumper must
be (64 or so). No idea how much room is between that and the overhang.
The height of the
base and bottom of the overhang should be the same, 40. The top of the overhang
is at a height of 60.
& messing with walls, if you don't want a ball popping off the table because of a low wall
make it 13 numbers higher then the wall or table its on
if your table or wall(if wall is a base)bottom height is 0 then the shortest height is 13
ex.
bottom height 0
top height 13
ex.
bottom height 3
top height 16
you can make it higher than 13 but any lower & the ball goes right over it
from the bottom of the pinball to the
lowest possible point of contact with a wall which will impact ball movement,
is 12.5 units from table level (0)
The pinball is 48
units high, and 48 units wide. Therefore, the center point of the ball would be
approximately +24 to +26 from the current ramp height.
ie - you have a ramp
going from 0 (table level) to 100. At the top of the ramp, a 'sidewall' at
bottom height of 124 and top height of 126 will keep the ball on the ramp. Adjust
the top height of the side wall based on how fast the pinball tends to go up
the ramp and the incline of the ramp. This also prevents slow balls from
falling off flat ramps too.
If I have target1
target2 and target3, when I hit these targets they go down and increase score,
however on the next ball thay are still down.
I know I need to
reset the table or the targets somehow, but I cannot figure it out. I have
checked some other scripts but I must be doing something wrong.
For each target:
Sub Target1_Hit
Target1.IsDropped = True
Timer1.Enabled = True
AddScore
End Sub
Then, after all
three target scripts:
Sub Timer1_Timer()
Timer1.Enabled = False
CheckTargets
End Sub
Sub CheckTargets
If Target1.IsDropped And Target2.IsDropped And Target3.IsDropped Then
Target1.IsDropped = False
Target2.IsDropped = False
Target3.IsDropped = False
End If
End Sub
if you only want the drop targets to
come up after the ball drains or whenever the ball drains put the
TargetX.isdropped=false in your Drain_Hit area. (X being the number for your
target)
just put
all objects that need to be reseted for next ball in a sub called for example
sub
Next_Ball_Init() and call
it in Drain_hit(): Sub
Drain_Hit() When you
progress with your table then you will have more objects
(lights,bumpers,targests) that need a reset so u have them all in one place |
Collection
of targets- VB5
Sub TargetCollective_Hit(Index)
' This is triggered when any target in the collective is hit.
' The index starts at zero. (Ex. the third target is index #2)
' If target #2 is hit then the index number equals 1, it drops
' target #2 and plays the sound "Drop Target"
TargetCollective(index).IsDropped=true
PlaySound "DropTarget"
' Now we check to see if all targets in the collective have been dropped.
' If so, we play a "TargetsAllDropped" sound and reset the targets.
' If at any time during this loop that
' TargetCollective.IsDropped not true then we exit the whole subroutine
For Each Target In TargetCollective
If Target.IsDropped <> true Then Exit Sub
Next
'All Targets have been dropped. Play "TargetsAllDropped" and
'reset all targets back to their original state.
PlaySound "TargetsAllDropped"
For Each Target In TargetCollective
Target.IsDropped = False
Next
End Sub
getting scoring to work? -first,
you need a sub routine for any object that has a hit event and score
addition. for example: sub
drop_target_hit() (where "drop_target" is the variable name
assigned to that object) sub
display_score() Make sure
you have include a dim statement for any variable (ie. Dim score) that will
hold a value and that that statement will not be read again while the
variable is being assigned new values - usually the opening lines in your
script. |
How do you reset score when game is over?
I reset score.text back to 0 when last ball is drained, but
when I hit the first scoring target in the next game it resumes with the
score from the previous game. Also just curious,
how hard is it to add 2 player mode? |
Obviously, the
variable you are using for score is not being reset to zero at the end of a
game. This isn't automatic; you'll have to insert a '(score variable)=0' line
in the required place of your code. If you *do* have one in, then it must be in
a place which isn't being accessed at the required point in the game, and
you'll need to move it. Put it in the same place as the code that sets up the
first ball in a new game.
Score How to
first, you need a sub
routine for any object that has a hit event and score addition. for example:
sub drop_target_hit() (where "drop_target" is the variable name
assigned to that object) drop_target.isdropped = true score = score +100
("score" is the variable you've assigned to the score) display_score
("display_score" is the name of a sub routine you've written to
display the score) end sub sub display_score() scorebox.text = score (scorebox
is the name of the text object you've created) end sub Make sure you have include
a dim statement for any variable (ie. Dim score) that will hold a value and
that that statement will not be read again while the variable is being assigned
new values - usually the opening lines in your script.
I reset score.text
back to 0 when last ball is drained, but when I hit the first scoring target in
the next game it resumes with the score from the previous game. Also just
curious, how hard is it to add 2 player mode?Obviously, the variable you are
using for score is not being reset to zero at the end of a game. This isn't
automatic; you'll have to insert a '(score variable)=0' line in the required
place of your code. If you *do* have one in, then it must be in a place which
isn't being accessed at the required point in the game, and you'll need to move
it. Put it in the same place as the code that sets up the first ball in a new
game.
"i want to have
the bonus adding points runing slow/donw and see the score growing by (for ex)
1000 points"
The only way I could manage it was to have a seperate timer for each bonus
level, and give each timer a slightly longer interval. Then call all the timers
in one sub. They will all trigger at the same time, but with different
intervals, they appear to exicute one after the other.
I had the same
problem in my Stingray Table. This is how I solved it. Create a timer that has
the time delay that you want.
For example, for 1
second set the timer to 1000. Be sure to uncheck the enabled box when creating the
timer, otherwise the timer will run as soon as the table is initialized. In the
script where you want the countdown to occur call the timer by enabling it.
Sub BonusScoring
BonusTimer.Enabled = True
End Sub
Then do all of the
scoring inside the BonusTimer Routine. The routine will run over and over again
with a delay of 1 second (or whatever you set the timer to) until the timer is
set back to false.
Sub
BonusTimer_Timer()
If bonuscount > 0 Then
Playsound "Bonus"
AddScore = 1000
bonuscount = bonuscount - 1
Else
Bonus.Timer.Enabled = False
End If
End Sub
In the sxample above
there is a counter called bonuscount that has some value. If the value coming
in is 5 then when the timer is called then the timer routine will run 5 times
playing a bonus sound and scoring 1000 points each time with a 1 second delay
between each event. The next time through the bonuscount counter will equal 0
and the BonusTimer will be Disabled and the script will continue running from
where the BonusTimer was initially Enabled.
Okay.. I've tried and
tried to do this.. and cannot manage to create a delay when scoring my end of
ball bonus..
my variable fh_xTotalBonus holds the total ball bonus value.. I want to
decrease this by 1000, add the points to the Score, and repeat until it hits 0,
and pause 500 ms (1/2 second) between repeats.
I "tried" using what jlang suggested.. and I must be doing something
wrong. I've tried looking at code in other tables.. and they all have hundreds
of lines of code concerning the bonus counts.. I'd think what I want to do is
pretty simple.
Here's what I had.. I am sure it will be glaringly obvious how wrong it is.
Here is the Award Bonus Routine:
Sub AwardEndofBallBonus()
fh_xTotalBonus = fh_xRunningBonus * fh_xMultiplier
Timer1.Enabled = True
bo_AddPoint 1000
AlertBox.Text = "Ball Bonus " & fh_xTotalBonus
End Sub
And the timer timer is here...
Sub Timer1_Timer()
If fh_xTotalBonus > 0 Then
rem Playsound "Bonus" -- IT'S NOT PLAYING SOUND!!!
AddScore = 1000
fh_xTotalBonus = fh_xTotalBonus - 1000
Else
Timer1.Enabled = False
End If
End Sub
What exactly am I doing incorrectly?
just kidding... ok,
you read this far. Your variables must make sense to you. Hopefully ALL your
bonus additions are in 1000 flat increments or this script will have problems.
As long as the bonus
addition is correct, to the addscore routine when you test it, you might want
to increase the timer delay just for testing purposes, and have it write to a
textbox after each bonus addition in the timer subroutine so you can see what
it's doing. If you are 1000 points off on your bonus (which it looks like you
are because of the >0 qualifier, put a second If statement in there to say
like if it =0 then addscore 1000 and disable the timer. That way your other
variables can't drop into negative numbers
Open vpmkeys.vbs with notepad, and
look for the follwing line:
keyHiScoreReset = 7 '(6) Reset Hiscores
Just set 7 blank or change to the desired AscII number for the key wanting to
use.
Remember to save the file on exit...
i want to have the
bonus adding points runing slow/donw and see the score growing by (for ex) 1000
points
The only way I could
manage it was to have a seperate timer for each bonus level, and give each
timer a slightly longer interval. Then call all the timers in one sub. They
will all trigger at the same time, but with different intervals, they appear to
exicute one after the other.
I had the same
problem in my Stingray Table. This is how I solved it. Create a timer that has
the time delay that you want.
For example, for 1
second set the timer to 1000. Be sure to uncheck the enabled box when creating
the timer, otherwise the timer will run as soon as the table is initialized. In
the script where you want the countdown to occur call the timer by enabling it.
Sub BonusScoring
BonusTimer.Enabled = True
End Sub
Then do all of the
scoring inside the BonusTimer Routine. The routine will run over and over again
with a delay of 1 second (or whatever you set the timer to) until the timer is
set back to false.
Sub
BonusTimer_Timer()
If bonuscount > 0 Then
Playsound "Bonus"
AddScore = 1000
bonuscount = bonuscount - 1
Else
Bonus.Timer.Enabled = False
End If
End Sub
In the sxample above
there is a counter called bonuscount that has some value. If the value coming
in is 5 then when the timer is called then the timer routine will run 5 times
playing a bonus sound and scoring 1000 points each time with a 1 second delay between
each event. The next time through the bonuscount counter will equal 0 and the
BonusTimer will be Disabled and the script will continue running from where the
BonusTimer was initially Enabled.
Okay.. I've tried and
tried to do this.. and cannot manage to create a delay when scoring my end of
ball bonus..
my variable
fh_xTotalBonus holds the total ball bonus value.. I want to decrease this by
1000, add the points to the Score, and repeat until it hits 0, and pause 500 ms
(1/2 second) between repeats.
I "tried"
using what jlang suggested.. and I must be doing something wrong. I've tried
looking at code in other tables.. and they all have hundreds of lines of code
concerning the bonus counts.. I'd think what I want to do is pretty simple.
Here's what I had.. I
am sure it will be glaringly obvious how wrong it is.
Here is the Award
Bonus Routine:
Sub
AwardEndofBallBonus()
fh_xTotalBonus = fh_xRunningBonus * fh_xMultiplier
Timer1.Enabled = True
bo_AddPoint 1000
AlertBox.Text = "Ball Bonus " & fh_xTotalBonus
End Sub
And the timer timer
is here...
Sub Timer1_Timer()
If fh_xTotalBonus > 0 Then
rem Playsound "Bonus" -- IT'S NOT PLAYING SOUND!!!
AddScore = 1000
fh_xTotalBonus = fh_xTotalBonus - 1000
Else
Timer1.Enabled = False
End If
End Sub
What exactly am I
doing incorrectly?
just kidding... ok,
you read this far. Your variables must make sense to you. Hopefully ALL your
bonus additions are in 1000 flat increments or this script will have problems.
As long as the bonus addition is correct, to the addscore routine when you test
it, you might want to increase the timer delay just for testing purposes, and
have it write to a textbox after each bonus addition in the timer subroutine so
you can see what it's doing. If you are 1000 points off on your bonus (which it
looks like you are because of the >0 qualifier, put a second If statement in
there to say like if it =0 then addscore 1000 and disable the timer. That way
your other variables can't drop into negative numbers.
++++++++++++++++++++++
Bonus(0) = Whatever bonus you're
using *remember to dim Bonus so that Bonus exists either
Dim Bonus (4) If you
use it for a 4 player game
or
Bonus = Array
(0,0,0,0,0)
Of course you could
replace Bonus(0)
and then this line
CollectBonus.Enabled=True
So for example
Bonus(0)=Bonus(CurrentPlayer)
CollectBonus.Enabled=True
I took what you'd posted before.. (after
I posted) and played with it and it DOES count down the bonus..
Here's the problem I
have.. it's still counting the bonus when the next ball gets sent into play.
::chuckle:: Any way to totally stop advancement table action when the timer is
running.. instead of the timer running while the subroutines after it continue
to be ran by the system? The new ball shouldn't be able to come into play til
after the bonus is done.
I sat up the delay
to eject a new ball into play.. but still at times it's not long enough. Is
this what I have to do, or is there a way to totally stop the routines from
executing at the same time as that timer?
Here's what I would do if I
understand you problem right. Instead of having a separate timer for the ball,
have the ball be ejected in the same timer as the bonus. Whatever your variable
for bonus is (lets call it bonus), say something like this in the bonus script
part:
Put this at the
begining, so it won't still try to take points away from bonus and make it
negative where it won't be zero, and the ball won't fire.
if bonus = 0 then
plunger.createball
bonustimer.enabled = false
...
(other stuff that needs to happen)
end if
+++++++++++++++
My table
is working well but I need to know how to set a bonus multiplier for a kicker
,adding say 200 points after the score reached sAY 1000 ,and 500 after
3000,Would I also add a percentage of the Total Score? |
Sub Kicker_Hit
If nScore > 1000 then
addBonus 500
ElseIf nScore > 500 then
addBonus 300
Else
addBonus 100
End If
End-of-ball bonuses.
-First, it'll save you a lot of headaches if you make the bonus lights an array
or collection. In fact, I don't know how you'd do it without an array, and I've
never bothered figuring it out.
-The way I do an end-of-ball bonus usually involves three subs: AdvanceBonus,
SetBonusLightState and AwardBonus. Their respective purposes should be pretty
obvious.
-For the sake of this example, I'll stick to a bonus done in a simple, EM-like
fashion (Max bonus 10,000, 10 lights. In fact, I'm going to cut and paste this
example with some minor modifications from my script for Nip-It.) Whenever a
target that advances the bonus is hit, it would call the AdvanceBonus sub. This
sub would look something like this, with dims added to show what kind of
variables it takes:
code:
dim nBonus
dim naBonusLights(10) 'the ten bonus lights are mapped to this array
dim nBonusMult 'if you have a multiplier
Sub AdvanceBonus()
If nBonus < 10 then
nBonus = nBonus + 1
SetBonusLightState
Else
Exit Sub
End If
End Sub
Sub SetBonusLightState()
For a = 1 to 10
If nBonus >= a then
aBonusLights(a).State = LightStateOn
Else
aBonusLights(a).State = LightStateOff
End If
Next
End Sub
The AdvanceBonus should be pretty self-explanitory. The
AdvanceBonusLightState() is a quick check that turns on all lights that are
less than or equal to the current nBonus value. I will admit that this is a
slightly "lazy" way to handle the bonus, but it should do the job in
a situation where execution speed of the script isn't an issue, as is the case
with VP.
As for the AwardBonus() sub, it would be called by the end-of-ball or any other
sub that would award the bonus. The real work in this one is handled by a timer
called BonusTimer, and the actual AwardBonus() sub is just a convenient way to
activate it. Here's what it would look like:
code:
Sub AwardBonus()
BonusTimer.Enabled = true
End Sub
Sub BonusTimer_Timer()
If nBonus = 0 then
BonusTimer.Enabled = false
NewBall ' a call to the sub that starts the next ball
Exit Sub
Else
Score 1000 'a call to whatever score function is being used
aBonusLights(nBonus).State = LightStateOff
nBonus = nBonus - 1
End If
End Sub
Set BonusTimer's interval to be what you want the delay between bonus counts to
be. This BonusTimer function will behave how you'd expect a simple EM-style
bonus countdown to act. You can also add whatever sounds you need to, or modify
it to handle more complex bonus counts.
I want to either weaken or disable
(preferably) the slam tilt on a certain System 11 William's table. I can't find
code for this in the script. How do you do this?
Slam tilt is just a
switch which is either on or off.
If the table uses
the s11.vbs the normal tilt is simulated and be controlled with
vpmNudge.Sensitivity
= x
Where x is 0-10
While x can be from 0 - 10 (0 = less sensitive,
10 = most sensitive), if you set it a negative number, you can effectively
disable slam tilt (unless you *really* bang back it a lot!).
E.g., if you want to
see how to get bored easily, set it to -100 or so...
Whats the correct way
to make a message text only appear for 15 secs?
Set a timer for 15000
milliseconds. When the text is put into the messagebox, enable the timer. When
the timer expires, disable the timer and write "" to the messagebox.
three options.
When renaming objects, after chaning the name, press enter, select something
else, press tab...etc. the name doesn't always change -- small vp bug.
2) save the table and reload the table. this sometimes works.
3) for timers, it makes no difference where they are on the table -- so just
delete the old timer and make a new one.
Remember, if you
changed the timer's name to MessageTimer, first I wouldn't recomment using
spaces in names if you can avoid it. Anywayz, the script would use Sub
MessageTimer_Timer, and you would use MessageTimer.Enabled and
MessageTimer.disabled.
If you named it Message, it's easier to remember (for me anyway) -- that way it
would be Message_Timer, and Message.enabled/Message.disabled
Short form
Change the name of your timer with no spaces.
use Exactly what you renamed it to in your script.
Change every instance of the old timername to the new one.
That's all there is to it.
(edit/find at the top will save you hours of time -- F3 moves ahead to the next
occurance)
Anyone know how to cause a delay between
the drain and the plunger?
Sub Drain_Hit()
Drain.DestroyBall
Drain.TimerEnabled=True
End Sub
Sub Drain_Timer()
Drain.TimerEnabled=False
Plunger.CreateBall
PlaySound "Plunger"
End Sub
Adjust the Timer Interval on the dran kicker to change the length of the delay.
Timer For A
shot-check
out breakshot
Here is one way,
first place a timer called "Countdown" on the table, uncheck Enabled
and set the interval to 1000 (1 second)
Add this line to set up a var
Dim count
When you want to fire the timer add this in the script wherever you want
count=60 'count down 1 minute (or any amount you want)
Countdown.Enabled=True 'start timer
Sub Countdown_Timer()
If count > 0 Then
ScoreText.Text="TimeLeft = "&count
Count=count-1
Else
Countdown.Enabled=False
ScoreText.Text="Finished"
End If
End Sub
*********
Create a timer,
uncheck the enabled box, and set the interval to be 1000. At the beginning of
the script, put this in:-
Public featuretime
This allows the variable "featuretime" to be used between subs. When
you want the timer kicking in, put these lines in the sub (where timer1
appears, replace with whatever you call the timer):-
timer1.enabled = true 'this starts the timer
featuretime = 60 'change this to how many seconds you want the feature to go on
for
Somewhere else in the script, create a sub like this:-
Sub timer1_timer()
featuretime = featuretime - 1
if featuretime >= 0 then
timer1.enabled = false 'this disables the timer
'before this comment, enter any variables you want changing relating to the
feature, ie. dropping off walls, removing targets, changing score etc.
End If
End Sub
I
am having trouble scripting a routine which will use a Sub to write different
messages on a textbox. IE - I'd like the textbox to handle messages, as in:
"Press Start"
"Activated"
and so on...
I am trying to use a variable, but either I did it wrong, or VP will just not
recognize it (I'm banking on #1).
I have the following:
In the Init part of the code: Dim Message
In the "hit" event(Sub): Message = "Activated"
In the "read" event (Sub): Textbox2.Text = Message
It doesn't work as stated above. I can't "Dim Message as String". I'm
wading through VB boooks looking for a clue, but no dice.
Why not in the hiot event
just say Textbox2.Text="Activated" or whatever? The problem is
probably that DIM is in the table_init routine, which makes it a local
variable. Try putting the dim line at the top of the script, outside any sub
routines.
*************
Message=Array("","Press
Start","Activated","message 3","message
4"...)
Sub UpdateMessage(messageno)
Textbox2.Text = Message(messageno)
End Sub
In this way you could define the messages presuming that you can fit in one one
line and call a routine with the messagenumber to be displayed...
The first "" indiactes message(0), you can add a message there, just
remember it'd be message(0) *game over might be nice?*
On Paratech's reply: it
looks doable! Instead of writing the message on all hit events, I'd just have
to write it in one place, and then assign messageno a value in the hit event,
and send it to Sub Update Message?
For example: let's display "Hurry Up Activated" in two texboxes.
Would this be OK?
Message1=Array("","Hurry Up","Lock Is Lit",...)
'Textbox 1
Message2=Array("","Bonus X","Activated",...)
'Textbox 2
Sub LeftSwitch_Hit()
Messageno1 = 1
Messageno2 = 2
UpdateMessage1
Updatemessage2
End Sub
Sub UpdateMessage1(Messageno1)
If TextBusy = True Then
Exit Sub
End If
Textbox1.Text = Message1(messageno1)
End Sub
Sub UpdateMessage2(Messageno2)
If TextBusy = True Then
Exit Sub
End If
Textbox2.Text = Message2(messageno2)
End Sub
Also, where in the code would I insert Message=Array... ?
Messages
|
||
|
three options.
When renaming
objects, after chaning the name, press enter, select something else, press
tab...etc. the name doesn't always change -- small vp bug.
2) save the table and
reload the table. this sometimes works.
3) for timers, it
makes no difference where they are on the table -- so just delete the old timer
and make a new one.
Remember, if you
changed the timer's name to MessageTimer, first I wouldn't recomment using
spaces in names if you can avoid it. Anywayz, the script would use Sub
MessageTimer_Timer, and you would use MessageTimer.Enabled and
MessageTimer.disabled.
If you named it
Message, it's easier to remember (for me anyway) -- that way it would be
Message_Timer, and Message.enabled/Message.disabled
Short form
Change the name of your timer with no spaces.
use Exactly what you renamed it to in your script.
Change every instance of the old timername to the new one.
That's all there is
to it.
(edit/find at the top will save you hours of time -- F3 moves ahead to the next
occurance)
Animate Text
To animate text effectively you have
to layer text boxes...there could be other ways, but it's the best solution
I've found so far...
By making text boxes
different sizes, you can achieve all kinds of growth, wipes and assorted
dissolves. Just remember that the most recent text box written to at a given
x/y will be the top box, and therefore the one that is displayed. It's also
good to keep in mind that a font size that is too big for the box, will simply
make PART of the text disappear...you can use this to great effect.
The table I'm
currently working on currently has 10 layers of text at a single x/y, and that
number will likely quadruple by the time I'm done. BUT, it does allow me to
some near DMD quality effects.
Well, a really simple solution to
doing things like scrolling text (text that scrolls from right to left or vice
versa), text wipes, etc. would be to first of all set up your text box with a
mono-spaced font, such as Courier New. Determine the maximum number of
characters you can display in the box at the font size you've selected, then
write a few functions to display the effects as you want them to appear. You'd
run the effects on a timer - that's the best way I can think of to do it.
I'm too tired at the
moment to write up code samples, but I'll experiment with some text effects as
a VPT file and post up the result when I get a chance. Here's what I'll attempt
to tackle:
* Marquee from right
to left
* Marquee from left to right
* Wipe in from left
* Wipe in from right
* Wipe out from left
* Wipe out from right
* Wipe in from center
* Wipe out from center
* Blank, then asterisks from center, then text from center
* Text, then asterisks from center, then blank
I came up with pretty much the same
idea as Dorsola, but I was writing while he was posting (I'm a morning person,
and it's morning here! ). Here's some quick code I wrote up for a
simple scroll that goes from right to left. I added a timer called ScrollTimer
and a text box called ScrollingText with a monospaced font to my backdrop
(proportional fonts would be hard, since there's no text width function in
VBScript).
code:
dim scrollPosition
scrollPosition = 0
'Text has 16 spaces after it so it will go off the edge of the screen
const ScrollText = "I AM SCROLLING TEXT! BOW DOWN BEFORE ME! "
const ScrollTextLength = 16
Sub ScrollTimer_Timer()
'Scroll horizontally based on current position
dim s
if scrollPosition = 0 then
s = ""
elseif scrollPosition <
ScrollTextLength + 1 then
s = Left(scrollText,
scrollPosition)
else
s = Mid(scrollText,
scrollPosition - ScrollTextLength, _
ScrollTextLength)
end if
ScrollingText.Text = s
scrollPosition = scrollPosition + 1
if scrollPosition > Len(scrollText)
then scrollPosition = 0
End Sub
Going left to right,
doing wipes, etc., are all pretty much variations on this theme. As Dorsola
says, having a bunch of subs to handle different effects is the way to go.
Vertical scrolling is
a little different. Since you can't control any attributes of the text box, you
can only scroll one full line at a time. Your best bet is to either do as PeBo
does and have multiple boxes for different vertical positions or have a really
tall text box.
Yup, it's messy, but
the advantage is that you can change fonts, font colour, text size, position
and angle on the fly with no more that 10-15 lines of code. This means you can
have a string appear at a barely readable 6-8 point, have it grow to 36 point,
start flashing, and then use the other suggestions for single box manipulation
in this thread to have it scroll off to the side. It also means that using a
custom font, you can animate virtually anything from a full DMD style multiball
announcement to a dancing baby (if you're not sick of them yet). Additionally
if you create an array for all your text boxes, accessing any one of them is
very simple and can be a variable value triggered event. You can easily scroll
text in a single text box, but if you want any other type of effect, I can't
see how it would be possible without using layers.
Okay, I've come up with a sort of
library for text effects in a single box. Check out this VPT file ( http://www.descent2.com/dorsola/files/vpt_texteff.zip
) - it is just a text effect demonstration, so it does nothing else. You can
direct the animation using the keys shown in the Instructions box. Examine the
Table1_Init() and Table1_KeyDown() subs to see how easy it is to use this
system.
This system is
fairly preliminary - it'll currently only work with one text box, one string,
and assumes that you want to go either from or to a blank text box in the
effect. IMPORTANT: It will also only work properly with an EVEN TextBoxSize
value! I plan on revising it so these effects will scroll, wipe and otherwise
replace existing text, so the whole system will be simpler when it's finished.
In this example,
I've set up a text box that can hold 40 characters, and the string you're
working with is "THE FUN HOUSE CLOSES IN 15 MINUTES" (34 chars). If
your string is larger than the text box size, some effects will truncate the
string, while others will allow the whole thing to appear.
There are 16 effects
to choose from:
* Scroll in from
right
* Scroll out to left
* Scroll across from right to left
* Scroll in from left
* Scroll out to right
* Scroll across from left to right
* Wipe in from right
* Wipe out to left
* Wipe in from left
* Wipe out to right
* Wipe in from center outwards
* Wipe out from center outwards
* Wipe in from edges inwards
* Wipe out from edges inwards
* Blank to asterisks to text from center outwards
* Text to asterisks to blank from center outwards
The last two effects
are coded separately from the rest, but are essentially combinations of other
effects. They'll be coded as such in the next revision.
Is there
any way to make the flippers feel more realistic? |
Some people find these
settings help: |
|
||
|
How can I increase
the strengh of the flippers in the Indy Tables or others?
Just start VPinmame
and open the IJ table.
After it is open click the options tab to the left of the table.
Then click on one of the flippers on the table.
A new menu will appear on the right of the table.
One of the options in that menu is "Speed".
I believe it is set to 0.135 on Indy.
Just increase it to 0.2 0.3 0.4 0.5 and on up until you find a speed you like.
You will see a "strength" option below the "Speed" option
but it will not do as much for you as the speed option will.
You will then need to repeat this process for the other flipper and save the
table.
Hope this helps some.
. One of the most
common "complaints" I see (besides the usual bugs of balls
dissappearing, being stuck in walls, etc) is that the particular user doesn't
like the flipper physics. Well, you can change them. I know that most know how
to modify the flipper physics, but apparently some of the new user's don't, so
I'm writing this for people who are new to the program. Here's how to change
flipper physics, and it's quite easy..
After loading the particular table, go into the edit screen (the screen that
looks like a blueprint with the icons on the left side). Now carefuly click on
one of the flippers so it's highlighted (be careful not to move it). Now go to
the menu at the top and click "edit", then click "options".
A interface should appear on the right side of the screen. Near the bottom is 2
fields labeled "speed" and "strength". These are the 2
fields that you can change. Experiment with different numbers to find something
you like. An easier and safer way however is to find a table that has physics
to your particular liking and get the flipper settings on that table and place
them onto the table you wish to change. If anyone's interested, I used the
settings from Ian's tables (which were input by metallik, if I remember
correctly). Attack from Mars and Theater of Magic had physics that I can play
well with. I hope this helps anyone who can't make shots that were normally
made in real world pins to get more enjoyment out of the tables
I have been experimenting with flipper angles on all of my
tables. |
Yea. I did not
mention the speed value because it seems to require a different one for each
table. For some a speed of 0.135 is just to fast. I have found that a speed
range of 0.05 to 0.07 works good for most tables.
The strength value does not seem to affect the shot very much.
I could be wrong on that but the speed seems to be more important.
Also keep in mind
that flipper radius, particurally the base radius, is really important to
propper flipper operation. If the base radius is too large, that can also cause
the flipper to seem sluggish. Seems that anything under 21 or so works fine.
Just start
VP/VPinMAME and open a table.
After it is open click the options tab to the left of the table.
Then click on one of the flippers on the table.
A new menu will appear on the right of the table.
One of the options in that menu is "Speed".
I believe it is set to 0.135 on Indy.
Just increase it to 0.2 0.3 0.4 0.5 and on up until you find a speed you like.
You will see a "strength" option below the "Speed" option
but it will not do as much for you as the speed option will.
You will then need to repeat this process for the other flipper and save the
table.
Q
Changing keys for flippers
to keys "3" and "4"...
How can this be done? I have all the newest files... It worked for a while, but then just
stopped... I unistalled and reinstalled
everything and still can't get them to stick!
Is there a permanent solution to this, to get the 3 and 4 keys to be the
main flipper keys for ALL games?A:
A:
All keyboard handling is
done in two sub:s inside the script called <TableName>_KeyUp(...) and
<TableName>_KeyDown(...)
(search for keyup or keydown
in the script)
If the tables are using the
WPC.VBS, S11.VBS etc the keyUp and keyDown subs only calls the keyboard
functions in the *.VBS file.
Near the end in the *:VBS
file you will find a lot of "Const" declarations.
Private Const keyShowOpts =
59 '(F1) Show options
Private Const keyShowKeys = 60 '(F2) Show Keys
Private Const KeyReset = 61 '(F3) Reset Emulation
Private Const KeyFrame = 62 '(F4) Toggle Window Lock
Private Const KeyBangBack = 20 '(T) Bang Back
Private Const keyInsertCoin1 = 4 '(3) Inser coin in slot 1
Private Const keyInsertCoin2 = 5 '(4) Inser coin in slot 2
Private Const keyInsertCoin3 = 6 '(5) Inser coin in slot 3
Private Const keyInsertCoin4 = 7 '(6) Inser coin in slot 4
Private Const keyStartButton = 2 '(1) Start button
You can find keycodes in the
helpfile supplied with Visual Pinball
Sub kicker1_hit()
kicker1.kick -45,10
end sub
Use above or
Sub kicker1_hit()
kicker1.kick 305,10
end sub
The angles are 0 to
359 technically though negtives appear to work as well. Pinman's will give you
the same result..
Think of the
directions as a clock face that goes
-------------- 0
---------305-------45
--------270---------90
---------225-------135
--------------180
For the direction
you want to kick it.
|
|||
|
Please could someone tell me what line
is needed for a kicker to kick out in a random direction?,with all directions
enabled.Is it possible to have the ball kicked out at a random speed?.For
example,between the speeds of say 30 - 80.If so,how do you do that?.Many thanks
in advance for any help given.
This is just a guess (works in other
basic-style languages, unsure about VP though) try it anyway.
Kickerdirection =
Int(Rnd * 360) + 1 [angle at which the ball is kicked]
Kickerspeed = (Int(Rnd * 50) +1) + 30 [speed at which the ball is kicked]
Kicker1[name of
kicker] = Kickerdirection, Kickerspeed
However, you may
like to modify it, and delete square brackets bit. But that is the basic code.
I would do it this way:
Kicker.Kick 360 *
Rnd, 30 + 50 * Rnd
I would also put a Randomize
in your table_init sub so you don't get the same series of numbers every time.
Kicker1.Kick int(rnd(1)*359),
int(rnd(1)*10)
Replace the 10 with
whatever you want the max to be, and if you want it say a minimum of 10 use
int(rnd(1)*10 + 10) which will make it between 10 and 20.
Make sure you have
RANDOMIZE in your script somewhere. You can also use CInt instead of Int.
Can someone tell me what the middle 2 variables on my kicker means?
Kicker1.kick 270, 1 +
rnd (1) * 40
1 + rnd (1) ?
Also when I enter my
kickerhole it seems to lose its kick about the 5th time its entered. Should I
just add Kicker1.kick 270, 1 + rnd (1) * 40 to each if statement?
----------------------------
The first parameter
is direction, with 0 being due north.
The second parameter
is strength of kick.
1+rnd(1)*40 generates
a number from 1 to 40. The rnd function generates a number from 0 to .9999.
Multiply that by 40, you get 0 to 39.99999. Add one, you get 1 to 40.9999. The decimals
are truncated if the kicker function requires an integer parameter.
If you want a kick of
strength 20 to 40 instead of 1 to 40 try:
20+rnd(1)*20.
1.
Kicker shoot along Z-Axis - YES, working!!!
Hi folks,
everybody says that
Kickers don't have the ability to shoot along the Z-Axis,
but then you all should take a closer look to the VP Documantation as there
are some properties of the objects not visible in the editor!
Like this one from
VPReference.chm):
Kicker.Kick(Angle As
Single, Speed As Single, [Inclination As Single])
You notice -
INCLINATION!!!
Ok, I built an example-table with some stairs - now, let's play ball....
Attachment: UpKicker.vpt |
I just figured out,
how the "inclination" parameter has to be set:
as default, the kicker
kicks horizontal (0 deg.), a 90 deg. kick (almost straight vertical)
would be something like 1.45 and everything between them is the corresponding
angle
(ie. 0.75 is almost 45 deg.)
You have to play a little with the value to find out the needed angle, but it's
great.
Don't forget to set the glass-height and a suitable shoot-strength
Oh, btw: ever tried
to set the table-inclination to values between 90 and 180 degrees?
Nice look from below the table upwards
what line / lines
need to be added to kicker script to make the kicker keep hold of the ball for
about 5 seconds before releasing it
sub kicker1_hit
kicker1.enabled=false
holdtimer.enabled=true
end sub
sub holdtimer_timer
kicker1.kick 180,20
kicker1.enabled=true
holdtimer.enabled=false
end sub
Then set the
holdtimer interval to 5000 (for 5 seconds).
Spinning Lamp Totan
- Sim Tech Sample
After spending about 6
hours straight working on it, I figured out a reasonably code-simple way to
simulate the spinning lamp in TOTAN. I've attached a VPT that contains a mockup
of the lamp object and the simulator I designed for it.
This thing is far
from perfect - the object can be fooled into turning the wrong direction; it
can't tell the difference between a dead-on hit and a glancing blow (one where
the ball is deflected off at an angle); and I don't have the rotation down very
well - friction is poorly simulated.
But, this is a start,
and it *might* be the best we can do until we're able to get the ball's
direction and speed values from (or during) a hit event.
Unlike captive balls,
I think getting the free-spinning lamp in TOTAN to work satisfactorily with the
current VisPin release is just a bit out of reach. If the person working on
TOTAN is satisfied with this, though, or has a better solution, it'll still
make the machine plenty playable. =)
Feel free to play
around with this thing, guys - I'd be interested in seeing if what I started
evolves. =)
WARNING: Heavy math involved! If you want to piece through the math in the script, I included some notes, but there's some complicated trig stuff to sort through. Be careful if you modify the math routines.
How do i
move the display and make it stay there next time i play a table? |
The last position is saved
but the script can override it. Look for a line in the script like |
|||
|
How do I
reduce the size of the DMD on games like Baywatch? |
|
|
Hit F1 while vpinmame is
running. Make sure to use the COMPACT DMD option. Also, remove the Double
Size option if it's selected. |
|||
|
|||
Is there
any way to make the vPinMAME games sound better? |
|
||
Some people report success
by altering the DirectX sound configuration. |
||
Are there
any bugs/issues with vPinMAME v1.10? |
|
|
#1) Some of the BSMT games
have volume issues. Either too loud or too soft. Nothing much can be done to
fix it for now. You should be able to use the 8,9 keys to adjust volume for
the SEGA games. If not, we might just need a new sega.vbs to handle support
for it, so sit tight.. |
Just a couple of
questions about script....
1) I am having problems defining variables:sometimes
they dont seem to register at all! do you have to DIM them all?.....and what
about the program
order?....does it make a difference
2) My version of VPinball seems ill, it crashes left
right and centre
550p3,25M6,16MrivaTNT,Norton,Network card,USB
MIDI interface,Win98,SoundBlaster1024
sometimes use soft FSB, PC Accellerator to overclock.?any ideas?
3)What is the routine to determine if a
has run out?....ie I am in a subroutine for a
skillshot, if the
timer runs out then skillshot has finished....but ive already done loads of
code....do i have to repeat it
under the SkillshotTimer_Timer() routine?
4)Is there an endsound command?
5)Anyone got any VB script info or tutorials yet?
Any variable should
be DIMed whith the exception of local variables used to pass parameters to a
subroutine.
Their order doesn't
matter (I like to put single value variables first, followed by single
dimension and multi-dimension arrays after, but that's a personal preference).
Best place though is in a place that won't be read more than once...like the
top opf your script
A temporary variable
(used for stuff like for/next loops) can be placed within the sub routine that
uses it, but remember that everytime the Dim statement is read, the variable is
going to be re-set.
As far as a
skill-shot timer is concerned, you can have it start as soon as the ball is
shot (or when it hit's a launch alley gate). Set the time for the correct duration
(1000=1 second), and simply include a x.timerenabled = false (where x is the
timer's name) within the timer subroutine. If it is an actual timer object
you're using, then it would just be x.enabled =false. If you include the
"=false" within the timer routine itself, the timer will end as soon
as the duration has passed.
So for your skillshot
it would be something like...
sub start()
Light_ss.state=lightstateon
x.timerenabled=true
end sub
sub x_timer()
x.timerenabled=false
light_ss.state=lightstateoff
end sub
You can check if the
timer is still active with a simple "if x.timerenabled" statement
("if" will always return a 0 for false and a 1 for true, so you don't
need any "= false" or "=true")
One suggestion, rather than using a gazillion timer objects, use some of your
table elements instead. Every object has it's own timer that you can use. So
for your skillshot, if you use an alley gate as the hit event that starts the
time, why not use the gate's timer. ie...
sub gate_hit()
gate.timerenabled=true
end sub
The endsound command
is a good question...I have no idea.
Actually be careful
of how much you follow the above...I'm self taught myself, so I could be full
of shit. If no one points out any errors in my suggestions, you can try them,
but don't take em to the bank!
You only have to DIM
variables if you've put "option explicit" at the start of your
script.
(at least one person
has told me that he thought "option explicit" activated some kind of
adult content lock! <grin>)
However, if you skip
the "option explicit", your programs will run fine, but the variables
will only be scoped for the subroutine in which they're used... so if you want
a variable to be globally available, you'll need to refer to it somewhere
within the "initialisation" code at the top of the script (i.e. the
stuff at the top of the script).... otherwise, the variable will reset to zero
whenever you move out of a routine where it's scoped - if you have variables
that don't seem to hold their values, then this is almost certainly the
problem.
To be honest, there
probably isn't any good reason to not use "option explicit" - it
forces you to explicitly declare all your variables upfront, and catches out
loads of typos and syntax errors that you'll otherwise miss. Which makes me
wonder why I forgot to use it in dragons castle or star race..... maybe I like
a challenge...
(disclaimer: I've
been VB coding for even less time than Pebo. And I'm so stupid that I don't
even use "option explicit" in my programs. I wouldn't listen to a
word I say if I was you...)
Mod’s
Well, really i
doesn't need to be dimmed at all, but I always have option explicit in my code
so I don't have variable naming problems. But even so, I could declare i as a
global, but nothing about i required global scope. It's a local variable used
by subs, so I declare it every time. Of course, you're free to commit whatever
travesty of coding style you want...
Mod is the modulus
operator, which does an integer division and returns the remainder. So, 9 mod 7
= 2, 21 mod 7 = 0, etc. I use it because with my 4 light sequence, there are 7
possible states (1 - 2 - 3 - 4 - all off - all on - all off - 1 - etc.). That
way, I can just keep adding to my counter and not have the annoying if counter
>= 7 then counter = 0 code. In this case, it's just personal preference, but
in some of my games the attract sequence can get quite complicated (I believe
Frontier has a sequence that is 90 or 100 lights long) and different lights go
at different speeds. So I can have this sequence going fast and another 10
light sequence going slower with (attractCounter \ 4) mod 10 to kind of break
things up a bit (\ is the integer division operator). So that's why I use mod.
|
How do I
generate a random number? |
To produce a random
number, use the rnd function. |
this is a part of my match
section... I'm trying to make my random number not repeat itself.
just to be clear, if
the last number was 10 the next random number must not be 10, but instead go
back and 'reroll' untill the number has changed.
Sub RunMatch()
MatchResult = Int(Rnd(1)*10) * 10
If MatchResult = 0 Then
BallText.Text = "00"
Else
BallText.Text = MatchResult
End If
MatchCount = MatchCount + 1
MatchTimer.Enabled = True
What is the range of
numbers you want to choose from?
You could use
recursion, but it's a bit dangerous as your program could litraly loop itself
to death.
Um try the following,
this is off the top of my head so forgive any small mistakes.
This script assumes
that you want a range from 1 to 10.
At the top of the
table
Dim LastRandomNumber
'Var to hold the last number
In the Table_init
routine
LastRandomNumber = 0
Now the routine to call to get the random number.
function GetRndNumber
(lastnum)
dim RandomNumber
randomize (timer)
RandomNumber =
int(rnd * 10) + 1
if RandomNumber = LastRandomNumber
then RandomNumber = GetRndNumber(lastnum)
GetRndNumber =
RandomNumber
LastRandomNumber = RandomNumber
End Function
To get the RandomNumber use the following
GetRndNumber
(lastRandomNumber)
the random number I'm
trying to produce is for the match,
Int(Rnd(1)*10) * 10
1 through 10 times ten...
your solution looks
better than any of the ones I was trying but I still fail to make it work. it
keeps generating 0 for some reason... it's probly me, I'll take another look at
it tmrw and see if it makes any more sense then. I think I'm just burnin out
for today
I'm pretty sure that if you're using Int(Rnd *10) * 10 to
generate your numbers, you're going to get numbers ranging from 0 to 90. Rnd
generates numbers in the range 0 <= Rnd < 1, so you'll never get 100.
You need to adopt MrRalphMan's approach: (Int(Rnd*10)+1) * 10. |
damn, never had a
chance to do much of anything today till just now, and I'm sure you got up long
ago here is my whole match section of my script
as it is...
If you needed/want
more than that I can just send you a wip of my whole table, not a problem.
BTW Joe, I belive
you're right, my code as is WILL generate from 0 - 9, I know I said 1 - 10
earlier, I was wrong. I had previously figured all that out when I first put
that code together, I was being forgetfull and lazy in my last post, very tired,
too much VP! Anyhow... for a match routine 0 - 9 works perfectly 0 = 00 and 9 =
90 it's all just double digits, so in this case it works perfectly
Sub RunMatch()
MatchResult = Int(Rnd(1)*10) * 10
If MatchResult = 0 Then
BallText.Text = "00"
Else
BallText.Text = MatchResult
End If
MatchCount = MatchCount + 1
MatchTimer.Enabled = True
End Sub
Sub
MatchTimer_Timer()
MatchTimer.Enabled = False
If MatchCount = 20 Then
MatchCount = 0
EndMatch
Else
RunMatch
End If
End Sub
Sub EndMatch()
If MatchResult =(Score-Round(Score/100)*100) Then
AddCreditAward
End If
GameOver
End Sub
Sub GameOver()
GameOn = False
Attract.Start
End Sub
Taking Camera Shots of a real table
Well.. Ideally you
want to have your camera at the highest resolution and lowest compression
settings possible. You'll want to take the playfield glass off and get that
pinball in a lot of light (outside is best but otherwise a lot of nice
diffuse(SP?) light).
If you have enough light (only the pics will tell) Then position yourself or
the camera to be directly overhead of the table and line up the camera
lengthwise with the table (so cropping will be less and you'll get a better and
bigger overall pic).
Then shoot the following shots until you get at least one really good one of
each.
1 full Playfield shot
1 shot with 60% of the lower half of the table
1 shot with 60% of the upper half of the table.
You can also take the above sequence with flash as well and see if it might
come in handy later for something. With flash you'll have the flash bounce so
I'd recommend the other for less cleanup.
Take a lower light pic of the table as well with all lights on for color
matching.
Then take straight on closeups (watch the focus.. you can be a distance away
just try to fill the shot with the zoomed plastic) of each and every individual
plastic and drop target type on the machine.
Then take a shot of a lit and unlit backglass pic. This is a tough one because
of the glare that most BGs give.
That should be a good start. Check how the pics came out when viewed full size
on your computer and reshoot any that were too dark or blurry or had some other
problem.
Creator of Visual Pinball . If it wasn’t for Randy I’d be playing Mame
Shiva The best pinball site on the net
http://www.hippie.net/shivasite/UltraBoard/UltraBoard.cgi
AJ’s Table Site Good selection
http://www.thefew.com/vptables/
IR Pinball , Table Downloads, Table Creators and they acquired the talented Leo
http://www.hippie.net/shivasite/irpinball//nonirptables.html
Thanks to Randy, Shiva, (Shiva Site Maintainers) for getting it going again and everyone who made a table.
My next release of Knock My Fn Teeth out will be the Final………….when? soon as its finished
I’m slower with this stuff but like getting it to work, It’s all greek to me.
I need brown balls for my next table “Eat Poop & Die” J
Keep up the good work & keep them tables coming.
Cold1