Pascal's Triangle Pinball Demo - Magdha - 11-28-2025
Pascal's Triangle is a construction to give the binomial coefficients. Machines have been constructed to show a physical analogue of this (see Wikipedia Bean Machine for details of this). This program is a simulation of a triangular pinball table which demonstrates (closely) the same thing.
Ball's fall through the pin board under a constant force (gravity) and bounce off the pins through the array and exit at the bottom. The program uses full bouncing mechanics at each pin, with friction and non-ideal elastics collisions. At each pin there is a 50% chance of the ball leaving to the left or right, which is the condition required to obtain the Pascal's Triangle numbers.
In the real constructed machines, a large number of balls simultaneously fall through the pin array and accumulate in columns at the bottom. In this simulation, balls fall through one-at-a-time and are counted at the exits at the bottom. The numbers through each exit are displayed in a histogram. Beneath the histogram, figures are given in ratio to the expected binomial coefficients, scaled to the central column: if each pin collision were perfectly 50% left-right, each of the displayed figures would be exactly 1.
Because only one ball at a time travels through the pinboard, the histogram accumulation is rather slow and if you are interested to get to reasonable numbers, you'll have to allow the program to run for some time.
I had thought that I would need to place additional pins to the left and right of the triangle to prevent any ball exiting the triangle after an appropriate bounce. However, I have never seen such a problem and the balls always stay within the triangle (it'll be interesting if anybody ever finds such an event - the program is likely to crash if this did happen).
Unzip the folder into your QB64 directory (Run Option “Save EXE in source folder” checked).
Pascal's Triangle.zip (Size: 6.16 MB / Downloads: 17)
The screenshot shows the situation after a run of 5000 balls. All the expected frequencies per column are reasonably close to 1, a pleasing result. The program is another one from my .org days. That Qwerkey seemed to know a thing or two, apparently.
Code: (Select All)
'Pascal's Triangle Simulation by Magdha 2025-11-27 ex Qwerkey
CONST True = -1, False = 0
CONST FrameRate% = 60, CalcRate% = 600
CONST BallDiam%% = 60, PinRad%% = 7, Separation%% = (BallDiam%% / 2) + PinRad%%, Spacing%% = BallDiam%% + (2 * PinRad%%) + 6
CONST H! = Spacing%% * SQR(0.75) 'H0! = SQR(0.75),
CONST XScreen% = 980, YScreen% = 820, SmallBit! = 0.2, CornRad%% = 50, NoBallsLess1%% = 4
CONST A1%% = 16 + BallDiam%% + CornRad%%, A2%% = 8 + BallDiam%% / 2, A3%% = CornRad%% + 8 + BallDiam%% / 2
CONST A4%% = 16 + BallDiam%%, A5%% = 8 + BallDiam%%
CONST HistBase% = 380, HistHeight% = 340, HistWidth%% = 22, HistSepn%% = 5, HistBlock%% = 20
CONST G! = 0.2, F! = 0.97, W! = 0.8, Z! = 0.05, Bagatelle! = 0.8, Omega! = Bagatelle! / A3%%, SpeedLimit! = 3.5
DIM Pascal%(1, 8), Nos&(10), Pins!(1, 53), Vect!(NoBallsLess1%%, 4), DoPascal%%(NoBallsLess1%%, 6)
_TITLE "Pascal's Triangle - Esc to Quit"
$EXEICON:'.\blaise2.ico'
RANDOMIZE (TIMER)
DATA 1,8,28,56,70,56,28,8,1
FOR N%% = 0 TO 8
READ Pascal%(0, N%%)
NEXT N%%
'Images
TempImg& = _NEWIMAGE(BallDiam%%, BallDiam%%, 32)
_DEST TempImg&
_PUTIMAGE (0, 0)-(BallDiam%% - 1, BallDiam%% - 1), _LOADIMAGE("whiteball.png", 32)
Ball& = MakeHardware&(TempImg&)
Pin& = _NEWIMAGE(PinRad%% * 2 + 1, PinRad%% * 2 + 1, 32)
_DEST Pin&
FOR N%% = PinRad%% TO 1 STEP -1
CIRCLE (PinRad%%, PinRad%%), N%%, _RGB32(CINT(181 * (N%% + 5) / (PinRad%% + 5)), CINT(166 * (N%% + 5) / (PinRad%% + 5)), CINT(66 * (N%% + 5) / (PinRad%% + 5)))
PAINT (PinRad%%, PinRad%%), _RGB32(CINT(181 * (N%% + 5) / (PinRad%% + 5)), CINT(166 * (N%% + 5) / (PinRad%% + 5)), CINT(66 * (N%% + 5) / (PinRad%% + 5)))
NEXT N%%
B& = _NEWIMAGE(128, 128, 32)
_DEST B&
COLOR _RGB32(100, 100, 100), _RGB32(230, 230, 20)
CLS
Corn& = _NEWIMAGE(A1%%, A1%%, 32)
_DEST Corn&
COLOR _RGB32(229, 170, 112)
CIRCLE (0, 0), CornRad%%
CIRCLE (0, 0), A1%% - 1
PAINT (CornRad%% + 1, 1)
COLOR _RGB32(193, 117, 46)
CIRCLE (0, 0), CornRad%%
CIRCLE (0, 0), CornRad%% + 8
PAINT (CornRad%% + 1, 1)
CIRCLE (0, 0), A1%% - 1 - 8
CIRCLE (0, 0), A1%% - 1
PAINT (A1%% - 8, 1)
TempImg& = _NEWIMAGE(XScreen%, YScreen%, 32)
_DEST TempImg&
T% = 0
FOR N%% = 0 TO 8
FOR M%% = -(N%% + 1) TO (N%% + 1) STEP 2
_PUTIMAGE ((XScreen% / 2) + CINT(M%% * Spacing%% / 2) - PinRad%%, A1%% + 30 - PinRad%% + CINT(H! * N%%)), Pin&
Pins!(0, T%) = (XScreen% / 2) + (M%% * Spacing%% / 2)
Pins!(1, T%) = A1%% + 30 + (H! * N%%)
T% = T% + 1
NEXT M%%
NEXT N%%
L% = 700
T% = 130
_MAPTRIANGLE (0, 127)-(63, 127)-(63, 16), B& TO(L% + 0, T% + 127)-(L% + 63, T% + 127)-(L% + 63, T% + 16)
_MAPTRIANGLE (127, 127)-(63, 127)-(63, 16), B& TO(L% + 127, T% + 127)-(L% + 63, T% + 127)-(L% + 63, T% + 16)
COLOR _RGB32(0, 0, 0), _RGB32(230, 230, 20)
font& = _LOADFONT("cyberbit.ttf", 30, "bold")
_FONT font&
_PRINTSTRING (L% + 54, T% + 32), "P"
_PRINTSTRING (L% + 38, T% + 63), "A"
_PRINTSTRING (L% + 68, T% + 63), "S"
_PRINTSTRING (L% + 22, T% + 94), "C"
_PRINTSTRING (L% + 52, T% + 94), "A"
_PRINTSTRING (L% + 82, T% + 94), "L"
_FONT 16
_FREEFONT font&
LINE (90, YScreen% - 1)-(XScreen% - 1 - A1%%, YScreen% - 1 - A4%%), _RGB32(229, 170, 112), BF
LINE (90, YScreen% - 1)-(XScreen% - 1 - A1%%, YScreen% - 1 - 8), _RGB32(193, 117, 46), BF
LINE (90, YScreen% - 1 - A4%%)-(120, YScreen% - 1 - A5%%), _RGB32(193, 117, 46), BF
LINE (90, YScreen% - 1 - A4%%)-(98, YScreen% - 1), _RGB32(193, 117, 46), BF
LINE (121, YScreen% - 1 - A4%%)-(XScreen% - 1 - A1%%, YScreen% - 1 - A5%%), _RGBA32(193, 117, 46, 80), BF
LINE (XScreen% - 1 - A4%%, A1%%)-(XScreen% - 1, YScreen% - 1 - A1%%), _RGB32(229, 170, 112), BF
LINE (XScreen% - 1 - 8, A1%%)-(XScreen% - 1, YScreen% - 1 - A1%%), _RGB32(193, 117, 46), BF
LINE (XScreen% - 1 - A5%%, A1%%)-(XScreen% - 1 - A5%% - 8, YScreen% - 1 - A1%%), _RGB32(193, 117, 46), BF
LINE (XScreen% / 2 + BallDiam%% / 2 + CornRad%%, 0)-(XScreen% - 1 - A1%%, A4%%), _RGB32(229, 170, 112), BF
LINE (XScreen% / 2 + BallDiam%% / 2 + CornRad%%, 0)-(XScreen% - 1 - A1%%, 8), _RGB32(193, 117, 46), BF
LINE (XScreen% / 2 + BallDiam%% / 2 + CornRad%%, A4%% - 8)-(XScreen% - 1 - A1%%, A4%%), _RGB32(193, 117, 46), BF
_PUTIMAGE (XScreen% - 1 - A1%%, YScreen% - 1 - A1%%), Corn&
_MAPTRIANGLE (0, 0)-(A1%% - 1, 0)-(A1%% - 1, A1%% - 1), Corn& TO(XScreen% - 1 - A1%%, A1%%)-(XScreen% - 1 - A1%%, 0)-(XScreen% - 1, 0)
_MAPTRIANGLE (A1%% - 1, A1%% - 1)-(0, A1%% - 1)-(0, 0), Corn& TO(XScreen% - 1, 0)-(XScreen% - 1, A1%%)-(XScreen% - 1 - A1%%, A1%%)
_MAPTRIANGLE (0, 0)-(A1%% - 1, 0)-(A1%% - 1, A1%% - 1), Corn& TO(XScreen% / 2 + A3%%, A1%%)-(XScreen% / 2 - A2%%, A1%%)-(XScreen% / 2 - A2%%, 0)
_MAPTRIANGLE (A1%% - 1, A1%% - 1)-(0, A1%% - 1)-(0, 0), Corn& TO(XScreen% / 2 - A2%%, 0)-(XScreen% / 2 + A3%%, 0)-(XScreen% / 2 + A3%%, A1%%)
Background& = MakeHardware&(TempImg&)
_FREEIMAGE Pin&
_FREEIMAGE B&
_FREEIMAGE Corn&
TempImg& = _NEWIMAGE(20, 240, 32)
_DEST TempImg&
COLOR _RGB32(100, 100, 100), _RGB32(80, 240, 40)
CLS
Histo& = MakeHardware&(TempImg&)
FOR N%% = 0 TO 9
No& = _NEWIMAGE(8, 14, 32)
_DEST No&
COLOR _RGB32(255, 30, 80)
_PRINTSTRING (0, 0), LTRIM$(STR$(N%%))
Nos&(N%%) = _NEWIMAGE(14, 8, 32)
_DEST Nos&(N%%)
_MAPTRIANGLE (0, 0)-(7, 0)-(0, 13), No& TO(13, 0)-(13, 7)-(0, 0)
_MAPTRIANGLE (7, 13)-(0, 13)-(7, 0), No& TO(0, 7)-(0, 0)-(13, 7)
_FREEIMAGE No&
NEXT N%%
No& = _NEWIMAGE(8, 14, 32)
_DEST No&
COLOR _RGB32(255, 30, 80)
_PRINTSTRING (0, 0), "."
Nos&(10) = _NEWIMAGE(14, 8, 32)
_DEST Nos&(10)
_MAPTRIANGLE (0, 0)-(7, 0)-(0, 13), No& TO(13, 0)-(13, 7)-(0, 0)
_MAPTRIANGLE (7, 13)-(0, 13)-(7, 0), No& TO(0, 7)-(0, 0)-(13, 7)
_FREEIMAGE No&
'Initialise
MaxBar% = 0
C%% = False
DoPascal%%(0, 0) = True
DoPascal%%(0, 1) = False
DoPascal%%(0, 2) = False
DoPascal%%(0, 3) = False
DoPascal%%(0, 4) = False
DoPascal%%(0, 5) = False
DoPascal%%(0, 6) = False
Vect!(0, 0) = XScreen% / 2
Vect!(0, 1) = A1%% + 10
Vect!(0, 2) = Z! * (0.5 - RND)
Vect!(0, 3) = 0.3 + (0.2 * RND)
DoPascal%%(1, 0) = False
DoPascal%%(1, 1) = False
DoPascal%%(1, 2) = False
DoPascal%%(1, 3) = True
DoPascal%%(1, 4) = False
DoPascal%%(1, 5) = False
DoPascal%%(1, 6) = False
Vect!(1, 0) = XScreen% - A1%%
Vect!(1, 1) = A2%%
Vect!(1, 2) = -Bagatelle!
Vect!(1, 3) = 0
DoPascal%%(2, 0) = False
DoPascal%%(2, 1) = False
DoPascal%%(2, 2) = True
DoPascal%%(2, 3) = False
DoPascal%%(2, 4) = False
DoPascal%%(2, 5) = False
DoPascal%%(2, 6) = False
Vect!(2, 0) = XScreen% - A2%%
Vect!(2, 1) = A1%% + 10
Vect!(2, 2) = 0
Vect!(2, 3) = -Bagatelle!
DoPascal%%(3, 0) = False
DoPascal%%(3, 1) = False
DoPascal%%(3, 2) = True
DoPascal%%(3, 3) = False
DoPascal%%(3, 4) = False
DoPascal%%(3, 5) = False
DoPascal%%(3, 6) = False
Vect!(3, 0) = XScreen% - A2%%
Vect!(3, 1) = YScreen% - 1 - A1%% - 10
Vect!(3, 2) = 0
Vect!(3, 3) = -Bagatelle!
DoPascal%%(4, 0) = False
DoPascal%%(4, 1) = True
DoPascal%%(4, 2) = False
DoPascal%%(4, 3) = False
DoPascal%%(4, 4) = False
DoPascal%%(4, 5) = False
DoPascal%%(4, 6) = False
Vect!(4, 0) = XScreen% / 2
Vect!(4, 1) = YScreen% - A2%%
Vect!(4, 2) = 1.8 * Bagatelle!
Vect!(4, 3) = 0
SCREEN _NEWIMAGE(XScreen%, YScreen%, 32)
_SCREENMOVE 50, 0
_DEST 0
WHILE INKEY$ = ""
_LIMIT CalcRate%
DispCount% = DispCount% + 1
'Display Images
IF DispCount% = CINT(CalcRate% / FrameRate%) THEN
'CLS
_PUTIMAGE (0, 0), Background&
FOR N%% = 0 TO NoBallsLess1%%
_PUTIMAGE (CINT(Vect!(N%%, 0) - (BallDiam%% / 2)), CINT(Vect!(N%%, 1) - (BallDiam%% / 2))), Ball&
NEXT N%%
FOR N%% = 0 TO 8
IF Pascal%(1, N%%) > MaxBar% THEN MaxBar% = Pascal%(1, N%%)
NEXT N%%
FOR N%% = 0 TO 8
IF MaxBar% > HistBlock%% THEN
IF Pascal%(1, N%%) = 0 THEN
_PUTIMAGE (20 + (HistWidth%% + HistSepn%%) * N%%, HistBase%)-(20 + HistWidth%% + (HistWidth%% + HistSepn%%) * N%%, HistBase%), Histo&, , (0, 0)-(19, 0)
ELSE
_PUTIMAGE (20 + (HistWidth%% + HistSepn%%) * N%%, HistBase%)-(20 + HistWidth%% + (HistWidth%% + HistSepn%%) * N%%, HistBase% - CINT(Pascal%(1, N%%) * HistHeight% / MaxBar%)), Histo&, , (0, 0)-(19, CINT(Pascal%(1, N%%) * HistHeight% / MaxBar%) - 1)
END IF
ELSE
IF Pascal%(1, N%%) = 0 THEN
_PUTIMAGE (20 + (HistWidth%% + HistSepn%%) * N%%, HistBase%)-(20 + HistWidth%% + (HistWidth%% + HistSepn%%) * N%%, HistBase%), Histo&, , (0, 0)-(19, 0)
ELSE
_PUTIMAGE (20 + (HistWidth%% + HistSepn%%) * N%%, HistBase%)-(20 + HistWidth%% + (HistWidth%% + HistSepn%%) * N%%, HistBase% - CINT(Pascal%(1, N%%) * HistHeight% / HistBlock%%)), Histo&, , (0, 0)-(19, CINT(Pascal%(1, N%%) * HistHeight% / MaxBar%) - 1)
END IF
END IF
NEXT N%%
IF Pascal%(1, 4) > 0 THEN
FOR N%% = 0 TO 8
S! = Pascal%(1, N%%) / (Pascal%(0, N%%) * (Pascal%(1, 4) / Pascal%(0, 4)))
IF S! > 9.99 THEN S! = 9.99
IF INT(S!) = S! THEN
_PUTIMAGE (24 + (HistWidth%% + HistSepn%%) * N%%, HistBase% + 10), Nos&(INT(S!))
ELSE
I1%% = INT(S!)
XS! = 10 * (S! - I1%%)
I3%% = INT(XS!)
XS! = 10 * (XS! - I3%%)
I4%% = INT(XS!)
XS! = 10 * (XS! - I4%%)
IF XS! >= 0.5 THEN I4%% = I4%% + 1
IF I4%% > 9 THEN
I3%% = I3%% + 1
I4%% = 0
END IF
IF I3%% > 9 THEN
I1%% = I1%% + 1
I3%% = 0
END IF
_PUTIMAGE (24 + (HistWidth%% + HistSepn%%) * N%%, HistBase% + 10 + 7), Nos&(10)
_PUTIMAGE (24 + (HistWidth%% + HistSepn%%) * N%%, HistBase% + 10), Nos&(I1%%)
_PUTIMAGE (24 + (HistWidth%% + HistSepn%%) * N%%, HistBase% + 10 + 16), Nos&(I3%%)
_PUTIMAGE (24 + (HistWidth%% + HistSepn%%) * N%%, HistBase% + 10 + 25), Nos&(I4%%)
END IF
NEXT N%%
END IF
LOCATE 1, 1: PRINT Count&
_DISPLAY
DispCount% = 0
END IF
'Calculate
FOR BallNo%% = 0 TO NoBallsLess1%%
PreviousBall%% = BallNo%% - 1
IF PreviousBall%% < 0 THEN PreviousBall%% = NoBallsLess1%%
IF (Vect!(BallNo%%, 0) - Vect!(PreviousBall%%, 0)) * (Vect!(BallNo%%, 0) - Vect!(PreviousBall%%, 0)) + (Vect!(BallNo%%, 1) - Vect!(PreviousBall%%, 1)) * (Vect!(BallNo%%, 1) - Vect!(PreviousBall%%, 1)) > BallDiam%% * BallDiam%% THEN
IF DoPascal%%(BallNo%%, 0) AND (Vect!(BallNo%%, 1) <= A1%% + 30 + 8 * H! OR NOT DoPascal%%(PreviousBall%%, 1)) THEN
Vect!(BallNo%%, 0) = Vect!(BallNo%%, 0) + Vect!(BallNo%%, 2)
Vect!(BallNo%%, 1) = Vect!(BallNo%%, 1) + Vect!(BallNo%%, 3)
Vect!(BallNo%%, 3) = (F! * Vect!(BallNo%%, 3)) + G!
Bounce%% = False
N%% = 0
WHILE NOT Bounce%% AND N%% <= 53 'FIO Doesn't seem to require external pins
IF SQR((Vect!(BallNo%%, 1) - Pins!(1, N%%)) * (Vect!(BallNo%%, 1) - Pins!(1, N%%)) + (Vect!(BallNo%%, 0) - Pins!(0, N%%)) * (Vect!(BallNo%%, 0) - Pins!(0, N%%))) < Separation%% THEN
Bounce%% = True
CALL Axes((Pins!(1, N%%)), Dum!, YPin1!, Dum1!)
CALL Axes(Vect!(BallNo%%, 1), Vect!(BallNo%%, 3), YPosn1!, YVel1!)
V! = SQR(Vect!(BallNo%%, 2) * Vect!(BallNo%%, 2) + YVel1! * YVel1!)
Theta! = _ATAN2(YVel1!, Vect!(BallNo%%, 2))
Beta! = _ATAN2(YPin1! - YPosn1!, Pins!(0, N%%) - Vect!(BallNo%%, 0))
Vect!(BallNo%%, 2) = -V! * COS(2 * Beta! - Theta!)
YVel1! = -V! * SIN(2 * Beta! - Theta!)
Vect!(BallNo%%, 0) = Pins!(0, N%%) - (Separation%% + SmallBit!) * COS(Beta!)
YPosn1! = YPin1! - (Separation%% + SmallBit!) * SIN(Beta!)
CALL Axes(YPosn1!, YVel1!, Vect!(BallNo%%, 1), Vect!(BallNo%%, 3))
Vect!(BallNo%%, 2) = W! * Vect!(BallNo%%, 2) + (0.5 - RND) * Z! 'FIO Not perfectly elastic (with some randomness) TBF
Vect!(BallNo%%, 3) = W! * Vect!(BallNo%%, 3)
END IF
N%% = N%% + 1
WEND
IF Vect!(BallNo%%, 3) < -SpeedLimit! THEN Vect!(BallNo%%, 3) = -SpeedLimit! 'FIO Gives reasonable coefficients with only -ve Vect!(BallNo%%, 3)
IF Vect!(BallNo%%, 1) > A1%% + 30 + 8 * H! AND NOT C%% THEN
Count& = Count& + 1
Slot%% = CINT(4 + (Vect!(BallNo%%, 0) - (XScreen% / 2)) / Spacing%%)
Vect!(BallNo%%, 2) = 0
Pascal%(1, Slot%%) = Pascal%(1, Slot%%) + 1
C%% = True
ELSEIF Vect!(BallNo%%, 1) >= YScreen% - 1 - 8 THEN
RANDOMIZE (TIMER)
Vect!(BallNo%%, 1) = YScreen% - 1 - A2%%
Vect!(BallNo%%, 2) = Bagatelle! * (1 + (8 - Slot%%) / 6)
Vect!(BallNo%%, 3) = 0
C%% = False
DoPascal%%(BallNo%%, 1) = True
DoPascal%%(BallNo%%, 0) = False
END IF
ELSEIF DoPascal%%(BallNo%%, 1) OR DoPascal%%(BallNo%%, 2) OR DoPascal%%(BallNo%%, 3) THEN
Vect!(BallNo%%, 0) = Vect!(BallNo%%, 0) + Vect!(BallNo%%, 2)
Vect!(BallNo%%, 1) = Vect!(BallNo%%, 1) + Vect!(BallNo%%, 3)
IF DoPascal%%(BallNo%%, 1) THEN
IF Vect!(BallNo%%, 0) >= XScreen% - 1 - A1%% THEN
Vect!(BallNo%%, 0) = XScreen% - 1 - A1%%
DoPascal%%(BallNo%%, 1) = False
DoPascal%%(BallNo%%, 4) = True
Vect!(BallNo%%, 4) = 0
END IF
ELSEIF DoPascal%%(BallNo%%, 2) THEN
IF Vect!(BallNo%%, 1) < A1%% THEN
Vect!(BallNo%%, 0) = XScreen% - 1 - A2%%
Vect!(BallNo%%, 4) = 0
DoPascal%%(BallNo%%, 2) = False
DoPascal%%(BallNo%%, 5) = True
END IF
ELSE
IF Vect!(BallNo%%, 0) <= XScreen% / 2 + A3%% THEN
Vect!(BallNo%%, 0) = XScreen% / 2 + A3%%
Vect!(BallNo%%, 4) = 0
DoPascal%%(BallNo%%, 3) = False
DoPascal%%(BallNo%%, 6) = True
END IF
END IF
ELSEIF DoPascal%%(BallNo%%, 4) OR DoPascal%%(BallNo%%, 5) OR DoPascal%%(BallNo%%, 6) THEN
IF DoPascal%%(BallNo%%, 4) THEN
Vect!(BallNo%%, 4) = Vect!(BallNo%%, 4) + Omega!
Vect!(BallNo%%, 0) = XScreen% - 1 - A1%% + (A3%% * SIN(Vect!(BallNo%%, 4)))
Vect!(BallNo%%, 1) = YScreen% - 1 - A1%% + (A3%% * COS(Vect!(BallNo%%, 4)))
IF Vect!(BallNo%%, 1) <= YScreen% - 1 - A1%% THEN
Vect!(BallNo%%, 0) = XScreen% - 1 - A2%%
Vect!(BallNo%%, 1) = YScreen% - 1 - A1%%
Vect!(BallNo%%, 2) = 0
Vect!(BallNo%%, 3) = -Bagatelle!
DoPascal%%(BallNo%%, 4) = False
DoPascal%%(BallNo%%, 2) = True
END IF
ELSEIF DoPascal%%(BallNo%%, 5) THEN
Vect!(BallNo%%, 4) = Vect!(BallNo%%, 4) + Omega!
Vect!(BallNo%%, 0) = XScreen% - 1 - A1%% + (A3%% * COS(Vect!(BallNo%%, 4)))
Vect!(BallNo%%, 1) = A1%% - (A3%% * SIN(Vect!(BallNo%%, 4)))
IF Vect!(BallNo%%, 0) < XScreen% - 1 - A1%% THEN
Vect!(BallNo%%, 0) = XScreen% - 1 - A1%%
Vect!(BallNo%%, 1) = A2%%
Vect!(BallNo%%, 2) = -Bagatelle!
Vect!(BallNo%%, 3) = 0
DoPascal%%(BallNo%%, 5) = False
DoPascal%%(BallNo%%, 3) = True
END IF
ELSE
IF Vect!(BallNo%%, 1) <= A1%% THEN
Vect!(BallNo%%, 4) = Vect!(BallNo%%, 4) + Omega!
Vect!(BallNo%%, 0) = XScreen% / 2 + A3%% - (A3%% * SIN(Vect!(BallNo%%, 4)))
Vect!(BallNo%%, 1) = A1%% - (A3%% * COS(Vect!(BallNo%%, 4)))
ELSEIF NOT DoPascal%%(PreviousBall%%, 0) THEN
Vect!(BallNo%%, 0) = XScreen% / 2
Vect!(BallNo%%, 1) = A1%%
Vect!(BallNo%%, 2) = Z! * (0.5 - RND)
Vect!(BallNo%%, 3) = 0.3 + (0.2 * RND)
DoPascal%%(BallNo%%, 6) = False
DoPascal%%(BallNo%%, 0) = True
END IF
END IF
END IF
END IF
NEXT BallNo%%
WEND
SYSTEM
FUNCTION MakeHardware& (Img&)
MakeHardware& = _COPYIMAGE(Img&, 33)
_FREEIMAGE Img&
END FUNCTION
SUB Axes (YIn, VYIn, YOut, VYOut)
YOut = -YIn
VYOut = -VYIn
END SUB
|