Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pinball Molly
#6
Towards 3D Molly v1-2
Code: (Select All)
Option _Explicit
_Title "Pinball Molly v1-2: left ctrl for left flipper, right ctrl for right" 'b+ 2024-11-16
' Thanks to Rod Bird at JB Forum for inspiring this Pinball Game with his from which
' I used sound effects.

' 2024-11-23 moved Weird Filpper code into here and dumped previous  code I had.

' 2024-11-24 dont let bs go below zero better yet below gravity.
' Moved baseX of flippers closer to walls so ball isn't stuck in the corner.
' Increased power down line of flipper contact from i/200 to i/50 because
' gravity was increased to roll ball down flipper faster from dead stop.
' More deadening of bs when hitting walls or flippers not moving.

' 2024-11-25 now add a Circle Board BackGround numbers tweaked  a bit

' 2024-11-26 add  kickers now, tweak add bonus rounds I name it Molly v1.0

' 2024-11-27 mouth score v1.1
' 2024-11-27 v1-2 FullScreen add some 3d effects

Const XMax = 740, YMax = 740
Const ScR = 370, Gravity = .5

Type FlipperType
    As Single baseX, baseY ' DrawFlipper needs these
    As Single tipX, tipY ' need to track collisions on ends of flipper
    As Single UpA, DownA, CurA
    As Long LeftFlipTF, TargetUpTF ' true false boolean
End Type

Type CircleType
    As Single x, y, r
End Type

Dim As FlipperType leftFlip, rightFlip
' some parts of Type are constant declare now
leftFlip.LeftFlipTF = -1
leftFlip.baseX = ScR - 300
leftFlip.baseY = YMax - 140
leftFlip.UpA = -_Pi(1 / 6) ' 315 degrees NE
leftFlip.DownA = _Pi(1 / 6)
leftFlip.TargetUpTF = 0 ' test a key press OK
leftFlip.CurA = leftFlip.DownA ' flipper at rest in down position

rightFlip.LeftFlipTF = 0
rightFlip.baseX = ScR + 300
rightFlip.baseY = YMax - 140
rightFlip.UpA = _Pi(7 / 6) ' 180 + 45 = 225 degrees NE
rightFlip.DownA = _Pi(5 / 6)
rightFlip.TargetUpTF = 0 ' flipper at rest in down position
rightFlip.CurA = rightFlip.DownA

Dim Shared FLen, BaseR, TipR ' finish flipper setup
FLen = 250: BaseR = 30: TipR = 12
Dim Shared LFC(FLen) As CircleType, RFC(FLen) As CircleType
SetFlipperRadii
Dim Shared br ' for making image
Dim ball, bx, by, bs, ba, bdx, bdy ' ball stuff
Dim lffirstI, lflastI, rffirsti, rflasti ' ball collision flipper stuff
Dim As Long i, score, bell, fall, balls, bonus, f
Dim k$, s$

Dim Shared As CircleType k(2)
k(0).x = ScR: k(0).y = .5 * YMax + 25: k(0).r = 30
k(1).x = .33 * XMax: k(1).y = .25 * YMax + 25: k(1).r = 30
k(2).x = .67 * XMax: k(2).y = .25 * YMax + 25: k(2).r = 30

Dim Shared As CircleType plus(7)
For i = 0 To 7
    plus(i).x = ScR + (ScR - 50) * Cos(i * _Pi(1 / 6) + _Pi(11 / 12))
    plus(i).y = ScR + (ScR - 50) * Sin(i * _Pi(1 / 6) + _Pi(11 / 12))
    plus(i).r = 20
Next

Screen _NewImage(XMax, YMax, 32) ': _ScreenMove 320, 0
_FullScreen
bell = _SndOpen("bell.wav")
fall = _SndOpen("fall.wav")
bonus = _SndOpen("digit.wav")
f = _LoadFont("arial.ttf", 24)
_Font f

br = 25 ' ball radius
ball = makeSkinnyBall& ' after br !!!
restart:
bx = ScR: by = br: bs = 10 ' ball loacation and speed

' shoot ball out towards one of the flippers randomly
If Rnd < .5 Then ba = _Pi((8 + 2 * Rnd) / 12) Else ba = _Pi((4 - 2 * Rnd) / 12)
bdx = bs * Cos(ba): bdy = bs * Sin(ba) '
Color , &HFF220044
Do
    If bs > 30 Then bs = 30
    Cls
    FC3 ScR, ScR, ScR + 3, &HFFBB8800 'back circle
    FC3 ScR, ScR, ScR, &HFF888888
    If _KeyDown(100306) Then leftFlip.TargetUpTF = -1 ' left side ctrl
    If _KeyDown(100305) Then rightFlip.TargetUpTF = -1 ' right side ctrl

    For i = 0 To 7 ' draw under the ball stuff
        DrawBonus i
    Next
    For i = 0 To 2
        DrawKickerBottom i
    Next
    ' here's the ball image
    _PutImage (bx - br * 1.7786 - 1, by - br * 1.7786 - 1), ball, 0
    DrawFlipper leftFlip
    DrawFlipper rightFlip
    For i = 0 To 2 ' Kicker tops over the ball
        DrawKicker i
    Next
    s$ = _Trim$(Str$(score))
    Color &HFFFFFFFF, &HFFFF0000
    _PrintString ((XMax - _PrintWidth(s$)) / 2, ScR + 150), s$
    Color &HFFFFFFFF, &HFF220044

    'update ball
    bdy = bdy + Gravity
    ba = _Atan2(bdy, bdx)
    bx = bx + bdx
    by = by + bdy
    If bs < Gravity Then bs = Gravity ' limit lowest speed
    If by > YMax - 1.25 * br Then Exit Do ' drain
    'keep ball inside board radius
    If _Hypot(by - ScR, bx - ScR) + br > ScR Then ' move back ball
        ba = _Atan2(by - ScR, bx - ScR) ' angle ball to center
        bx = ScR + (ScR - br) * Cos(ba): by = ScR + (ScR - br) * Sin(ba)
        ba = ba - _Pi
        bs = bs - 5 * Gravity
        If bs < Gravity Then bs = Gravity
        bdx = bs * Cos(ba): bdy = bs * Sin(ba)
        bx = bx + bdx: by = by + bdy
    End If

    'update flippers
    lffirstI = -1: rffirsti = -1: lflastI = -1: rflasti = -1
    For i = 0 To FLen
        If _Hypot(by - LFC(i).y, bx - LFC(i).x) < br + LFC(i).r Then ' collision
            If lffirstI < 0 Then lffirstI = i Else lflastI = i
        End If
        If _Hypot(by - RFC(i).y, bx - RFC(i).x) < br + RFC(i).r Then ' collision
            If rffirsti < 0 Then rffirsti = i Else rflasti = i
        End If
    Next
    If lffirstI >= 0 Then ' handle left flipper collisions
        If lflastI > 0 Then
            i = (lffirstI + lflastI) / 2
        Else
            i = lffirstI
        End If

        If leftFlip.TargetUpTF And leftFlip.CurA <> leftFlip.UpA Then
            bs = bs + i / 25
        Else
            bs = bs - 3 * Gravity
            If bs < Gravity Then bs = Gravity
        End If
        ba = _Atan2(by - LFC(i).y, bx - LFC(i).x)
        bx = LFC(i).x + (br + LFC(i).r) * Cos(ba): by = LFC(i).y + (br + LFC(i).r) * Sin(ba) ' move ball back above flipper
        bdx = bs * Cos(ba): bdy = bs * Sin(ba)
        bx = bx + bdx: by = by + bdy
    ElseIf rffirsti >= 0 Then ' handle right flipper collisions
        If rflasti > 0 Then
            i = (rffirsti + rflasti) / 2
        Else
            i = rffirsti
        End If
        If rightFlip.TargetUpTF And rightFlip.CurA <> rightFlip.UpA Then
            bs = bs + i / 25
        Else
            bs = bs - 3 * Gravity
            If bs < Gravity Then bs = Gravity
        End If
        ba = _Atan2(by - RFC(i).y, bx - RFC(i).x)
        bx = RFC(i).x + (br + RFC(i).r) * Cos(ba): by = RFC(i).y + (br + RFC(i).r) * Sin(ba) ' move ball back above flipper
        bdx = bs * Cos(ba): bdy = bs * Sin(ba)
        bx = bx + bdx: by = by + bdy
    End If

    ' collision Kickers
    For i = 0 To 2
        If _Hypot(by - k(i).y, bx - k(i).x) <= k(i).r + br Then ' left kick
            FC3 k(i).x, k(i).y, k(i).r + 15, &HFFFFFFFF
            _SndPlay bell
            score = score + 100
            ba = _Atan2(by - k(i).y, bx - k(i).x) + Rnd - .5 ' avoid infinite loops
            bx = k(i).x + (br + k(i).r) * Cos(ba)
            by = k(i).y + (br + k(i).r) * Sin(ba)
            bs = bs * 1.3
            bdx = bs * Cos(ba): bdy = bs * Sin(ba)
        End If
    Next

    ' ball over Bonus round
    For i = 0 To 7
        If _Hypot(by - plus(i).y, bx - plus(i).x) <= plus(i).r Then ' bonus
            FC3 plus(i).x, plus(i).y, plus(i).r, &HFFFFFFFF
            _SndPlay bonus
            score = score + 50
        End If
    Next

    _Display
    _Limit 30
Loop Until _KeyDown(27)
If _KeyDown(27) = 0 Then
    _SndPlay fall
    balls = balls + 1
    Color &HFFFFFFFF, &HFFFF0000
    If balls >= 5 Then
        s$ = "5 balls played, Game Over!"
        _PrintString ((XMax - _PrintWidth(s$)) / 2, ScR + 127), s$
        _Display
        k$ = "" ' for some reason sleep is not working right after first time it doesn't
        While k$ = ""
            k$ = InKey$
            _Limit 30
        Wend
        End
    Else
        s$ = "Press any for ball:" + Str$(balls + 1)
        _PrintString ((XMax - _PrintWidth(s$)) / 2, ScR + 127), s$
        Color &HFFFFFFFF, &HFF220044
        _Display
        k$ = "" ' for some reason sleep is not working right after first time it doesn't
        While k$ = ""
            k$ = InKey$
            _Limit 30
        Wend
        GoTo restart
    End If
End If

Function FlipAngle (f As FlipperType)
    Dim da
    da = _Pi(1 / 48)
    If f.LeftFlipTF Then ' left flipper
        If f.TargetUpTF Then ' move CCW subtract
            If f.CurA - da < f.UpA Then
                f.CurA = f.UpA
                f.TargetUpTF = 0 'target hit
            Else
                f.CurA = f.CurA - da
            End If
        Else ' move CW
            If f.CurA + da > f.DownA Then f.CurA = f.DownA Else f.CurA = f.CurA + da
        End If
    Else ' right flip
        If f.TargetUpTF Then ' move CW
            If f.CurA + da > f.UpA Then
                f.CurA = f.UpA
                f.TargetUpTF = 0
            Else
                f.CurA = f.CurA + da
            End If
        Else ' move CCW
            If f.CurA - da < f.DownA Then f.CurA = f.DownA Else f.CurA = f.CurA - da
        End If
    End If
    FlipAngle = f.CurA
End Function

Sub SetFlipperRadii
    Dim i, f
    f = (BaseR - TipR) / FLen
    For i = 0 To FLen
        LFC(i).r = BaseR - i * f
        RFC(i).r = LFC(i).r
    Next
End Sub

Sub DrawFlipper (f As FlipperType)
    ' setup to drawLink
    Dim ang, i
    ang = FlipAngle(f)
    For i = 0 To FLen
        If f.LeftFlipTF Then
            LFC(i).x = f.baseX + i * Cos(ang)
            LFC(i).y = f.baseY + i * Sin(ang)
            FC3 LFC(i).x, LFC(i).y + 10, LFC(i).r, &HFFFF4400
        Else
            RFC(i).x = f.baseX + i * Cos(ang)
            RFC(i).y = f.baseY + i * Sin(ang)
            FC3 RFC(i).x, RFC(i).y + 10, RFC(i).r, &HFFFF4400
        End If
    Next

    For i = 0 To FLen
        If f.LeftFlipTF Then
            'LFC(i).x = f.baseX + i * Cos(ang)
            'LFC(i).y = f.baseY + i * Sin(ang)
            FC3 LFC(i).x, LFC(i).y, LFC(i).r, &HFFFFFFFF
        Else
            'RFC(i).x = f.baseX + i * Cos(ang)
            'RFC(i).y = f.baseY + i * Sin(ang)
            FC3 RFC(i).x, RFC(i).y, RFC(i).r, &HFFFFFFFF
        End If
    Next
End Sub

Sub DrawKickerBottom (kNum)
    FC3 k(kNum).x, k(kNum).y + 40, k(kNum).r + 20, &HFF990000
    FC3 k(kNum).x, k(kNum).y + 40, k(kNum).r + 18, &HFF555555
End Sub

Sub DrawKicker (kNum)
    FC3 k(kNum).x, k(kNum).y, k(kNum).r + 20, &HFFFF0000
    FC3 k(kNum).x, k(kNum).y, k(kNum).r + 18, &HFFFFFFFF
    star k(kNum).x, k(kNum).y, k(kNum).r, k(kNum).r + 15, 24, 0, &HFFFF0000
End Sub

Sub DrawBonus (Num)
    FC3 plus(Num).x, plus(Num).y, plus(Num).r, &HFFFF0000
    FC3 plus(Num).x, plus(Num).y, plus(Num).r - 2, &HFFFFFFFF
    star plus(Num).x, plus(Num).y, 5, plus(Num).r - 5, 7, 0, &HFFFF0000
End Sub

Sub FC3 (cx As Long, cy As Long, r As Long, clr~&) ' no suffix punctuation use the Global Default Type as Long or Single or Double
    Dim As Long r2, x, y ' for Option _Explicit
    If r < 1 Then Exit Sub
    Line (cx - r, cy)-(cx + r, cy), clr~&, BF
    r2 = r * r
    Do
        y = y + 1
        x = Sqr(r2 - y * y)
        Line (cx - x, cy + y)-(cx + x, cy + y), clr~&, BF
        Line (cx - x, cy - y)-(cx + x, cy - y), clr~&, BF
    Loop Until y = r
End Sub

Sub star (x, y, rInner, rOuter, nPoints, angleOffset, K As _Unsigned Long)
    ' x, y are same as for circle,
    ' rInner is center circle radius
    ' rOuter is the outer most point of star
    ' nPoints is the number of points,
    ' angleOffset = angle offset IN DEGREES, it will be converted to radians in sub
    ' this is to allow us to spin the polygon of n sides
    Dim pAngle, radAngleOffset, x1, y1, x2, y2, x3, y3, i As Long

    pAngle = _D2R(360 / nPoints): radAngleOffset = _D2R(angleOffset)
    x1 = x + rInner * Cos(radAngleOffset)
    y1 = y + rInner * Sin(radAngleOffset)
    For i = 0 To nPoints - 1
        x2 = x + rOuter * Cos(i * pAngle + radAngleOffset + .5 * pAngle)
        y2 = y + rOuter * Sin(i * pAngle + radAngleOffset + .5 * pAngle)
        x3 = x + rInner * Cos((i + 1) * pAngle + radAngleOffset)
        y3 = y + rInner * Sin((i + 1) * pAngle + radAngleOffset)
        ftri x1, y1, x2, y2, x3, y3, K
        'triangles leaked
        Line (x1, y1)-(x2, y2), K
        Line (x2, y2)-(x3, y3), K
        Line (x3, y3)-(x1, y1), K
        x1 = x3: y1 = y3
    Next
    Paint (x, y), K, K
End Sub

Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
    Dim D As Long
    Static a&
    D = _Dest
    If a& = 0 Then a& = _NewImage(1, 1, 32)
    _Dest a&
    _DontBlend a& '  '<<<< new 2019-12-16 fix
    PSet (0, 0), K
    _Blend a& '<<<< new 2019-12-16 fix
    _Dest D
    _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
End Sub

'Sub drawBall (x, y, r, c As _Unsigned Long)
'    Dim rred As Long, grn As Long, blu As Long, rr As Long, f
'    rred = _Red32(c): grn = _Green32(c): blu = _Blue32(c)
'    For rr = r To 0 Step -1
'        f = 1 - Sin(rr / r) ' thank OldMoses for Sin ;-))
'        FC3 x, y, rr, _RGB32(rred * f, grn * f, blu * f)
'    Next
'End Sub

Function makeSkinnyBall& ' for this game
    Dim As Long im, g, rr
    Dim f
    g = 200
    im = _NewImage(2 * br * 1.7786 + 2, 2 * br * 1.7786 + 2, 32)
    _Dest im
    For rr = br To 0 Step -1
        f = 1 - Sin(rr / (br + 5)) ' thank OldMoses for Sin ;-))
        FEllipse br * 1.7786 + 1, br * 1.7786 + 1, rr, rr * 1.7786, _RGB32(g * f)
    Next
    _Dest 0
    makeSkinnyBall& = im
End Function

Sub FEllipse (CX As Long, CY As Long, xr As Long, yr As Long, C As _Unsigned Long)
    If xr = 0 Or yr = 0 Then Exit Sub
    Dim h2 As _Integer64, w2 As _Integer64, h2w2 As _Integer64
    Dim x As Long, y As Long
    w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
    Line (CX - xr, CY)-(CX + xr, CY), C, BF
    Do While y < yr
        y = y + 1
        x = Sqr((h2w2 - y * y * w2) \ h2)
        Line (CX - x, CY + y)-(CX + x, CY + y), C, BF
        Line (CX - x, CY - y)-(CX + x, CY - y), C, BF
    Loop
End Sub

Well the round ball will probabably only work on my screen but here's what it looks like for me:
   

EDIT: 3D Flippers a little bit too! Smile

OK I think I can make it look like this on anyones screen, stay tuned... (The roundness of ball is what I fear will be off.)
b = b + ...
Reply


Messages In This Thread
Pinball Molly - by bplus - 11-26-2024, 10:47 PM
RE: Pinball Molly - by Pete - 11-26-2024, 11:05 PM
RE: Pinball Molly - by bplus - 11-27-2024, 07:38 PM
RE: Pinball Molly - by Pete - 11-27-2024, 08:22 PM
RE: Pinball Molly - by bplus - 11-27-2024, 08:51 PM
RE: Pinball Molly - by bplus - 11-27-2024, 10:16 PM
RE: Pinball Molly - by SierraKen - 11-27-2024, 10:53 PM
RE: Pinball Molly - by bplus - 11-27-2024, 11:42 PM
RE: Pinball Molly - by SierraKen - 11-28-2024, 03:02 AM
RE: Pinball Molly - by bplus - Yesterday, 11:42 PM
RE: Pinball Molly - by PhilOfPerth - 6 hours ago
RE: Pinball Molly - by bplus - 2 hours ago



Users browsing this thread: NakedApe, 8 Guest(s)