Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Marquee Utility / Demo for Screen 0
#1
Here is a little marquee utility / demo.

Lt and Rt Arrow Keys: Change direction.
Up and Down Arrow Keys: Speed.
+ and - Keys: Widen or shorten window width.
Tab Key: Toggle between text and object.
B Key: Rebound effect. Text or object reverses when it hits a margin. Key must be pressed when entire text or object is visible on the screen.
W Key: Toggle wraps / unwraps object.
T Key: Write your own text.
Esc Key: End.

Code: (Select All)
Width 60, 20
Do
_Font 16: Cls
Dim Object As String
If Object = "" Then
Object = "ÎÃÒåўÒÐÃËÃÌÂÍÓÑžÀÓÒžÑÒÃÔåўÈÓÑÒž¿Ë¿ØÇÌÅ"
new$ = "": For i = 1 To Len(Object): x$ = Mid$(Object, i, 1): new$ = new$ + Chr$(Asc(x$) - 126): Next
Object = new$
End If
LtMargin = 1: RtMargin = _Width: x = 0: y = 3: If speed = 0 Then speed = .075
GoSub info
Do
_Limit 60
If Abs(z - Timer) > speed Then
z = Timer
MarqueeLIB Object, LtMargin, RtMargin, way, y, x, wrapper, rebound, AllowOffScrn, OffScrn
If OffScrn = 1 Then Sound 700, .5: Sleep
End If
GoSub keyboard: If OffScrn = -1 Then Exit Do
Loop
Loop

keyboard:
b$ = InKey$
If Len(b$) Then
Select Case b$
Case Chr$(0) + "M": way = 1
Case Chr$(0) + "K": way = -1
Case Chr$(0) + "H": If speed > 0 Then i = speed * 1000: speed = (i - 10) / 1000
Case Chr$(0) + "P": If speed < .2 Then i = speed * 1000: speed = (i + 10) / 1000
Case "b", "B": If cnt = j And x + j <= RtMargin Then rebound = 1 - rebound Else Sound 100, 1
Case Chr$(9): OffScrn = -1: If Object <> "-é-" Then Object = "-é-": OffScrn = -1: Else Object = ""
Case "+", "=": If RtMargin < 150 Then OffScrn = -1: RtMargin = RtMargin + 1: Width RtMargin, 20
Case "-", "_": If RtMargin > 1 Then OffScrn = -1: RtMargin = RtMargin - 1: Width RtMargin, 20
Case "t", "T": Cls: Line Input "Text Line: "; Object: OffScrn = -1
Case "w", "W": wrapper = 1 - wrapper
Case "a", "A": AllowOffScrn = 1 - AllowOffScrn
Case Chr$(27): _Delay 1.5: System
Case Else: Return
End Select
GoSub info
End If
Return

info:
If _Width > 59 Then
View Print _Height - 1 To _Height: Cls 2: View Print
Locate _Height - 1: Print " Way:"; way; " Delay: "; LTrim$(Str$(speed)); " Wrap:"; wrapper; " Rebound:"; rebound; " Pause OffScrn"; AllowOffScrn;
End If
Return

Sub MarqueeLIB (Object As String, LtMargin, RtMargin, way, y, x, wrapper, rebound, AllowOffScrn, OffScrn)
Static cnt, j, k, wmaskx, wmasklen
If way = 0 Then way = 1
If OffScrn Then OffScrn = 0: cnt = 0: j = 0: k = 0: x = 0 ' Clears static variables and resets x.
If j = 0 Then
j = Len(Object): k = 0: wmaskx = 0: wmasklen = 0: x = (RtMargin - RtMargin * way) \ 2
If way = -1 Then cnt = j Else cnt = 0
End If
If wrapper Then If RtMargin - LtMargin + 1 < j Then Cls: Print "Object too long.": End
If x > 0 And x <= RtMargin Then Locate y, x: Print Space$(k);
If way < 0 And wrapper <> 0 And x = RtMargin And cnt = j Then x = RtMargin + 1 - j
If way < 0 And cnt = 1 And wrapper = 0 Then cnt = j: x = RtMargin + 1: If AllowOffScrn Then OffScrn = 1 ' Exit left enter right.
If way > 0 And cnt = j And x = RtMargin Then ' Exit right enter left.
x = LtMargin - 1: If wrapper = 0 Then cnt = 0: If AllowOffScrn Then OffScrn = 1
End If
If OffScrn = 1 Then Exit Sub Else OffScrn = 0
If cnt < j And way > 0 Then ' Left to right text is still developing.
x = LtMargin
Else ' Either direction but left to right is at or past 1st column.
If x < RtMargin Or way < 0 Then ' Left to right but not at right margin or all right to left.
If x + way > LtMargin - 1 Then ' Right to left once entire object is visable and Left to right until object begins going off left side.
x = x + way
Else
If way > 0 Then
x = LtMargin
Else ' Left to right decreasing off left margin.
If rebound = 0 Then
cnt = cnt + way
Else ' Rebound changes direction to right.
way = 1: x = x + way
End If
End If
End If
End If
End If
If way > 0 And cnt < j Then cnt = cnt + way
If rebound And way > 0 And x + j > RtMargin Then way = -1
k = RtMargin - x + 1: If cnt < k Then k = cnt
x$ = Mid$(Object, j + 1 - cnt, k)
If wmasklen Then Locate y, wmaskx: Print Space$(wmasklen);
wmaskx = 0: wmasklen = 0
Locate y, x: Print x$;
If wrapper Then
If way < 0 Then
If j = cnt And k < j Then
wmaskx = LtMargin: wmasklen = j - k
If wmasklen Then Locate y, wmaskx: Print Mid$(Object, k + 1);
If cnt = 0 Then x = RtMargin: cnt = j: k = 1 ' For mask only. See wrapper statement after mask to reposition x.
Else
If cnt < j Then
wmaskx = RtMargin + 1 - (j - cnt): wmasklen = j - cnt
Locate y, wmaskx: Print Mid$(Object, 1, j - cnt);
If cnt = 0 Then x = RtMargin: cnt = j: k = 1
End If
End If
Else ' way > 0
If cnt < j Then
wmaskx = RtMargin + 1 - (j - cnt): wmasklen = (j - cnt)
Locate y, wmaskx: Print Mid$(Object, 1, wmasklen);
Else
If k < j Then
wmaskx = LtMargin: wmasklen = j - k
Locate y, wmaskx: Print Mid$(Object, k + 1);
End If
End If
End If
End If
End Sub

I was thinking about adding a saucer to my Mini Space Invaders WIP, but put this together as a routine that could also be used in other applications.

Pete
Reply
#2
Here is another example using this utility as a flow-through library to control the movements of a space invaders type saucer...

Saucer appears at random intervals.
Code: (Select All)
Width 60, 20
Dim Obj As String: Obj = "-é-"
lm = 1: rm = _Width: spd = .05
Do
If Abs(z4 - Timer) > .15 Then
z4 = Timer: If SaucerAttack = 0 Then i = Int(Rnd * 20): If i = 7 Then SaucerAttack = 1
End If
If SaucerAttack Then
If Abs(z - Timer) > spd Then saucer Obj, z, lm, rm, xsaucer, OffScrn
If OffScrn Then OffScrn = 0: SaucerAttack = 0: xsaucer = 0
End If
Loop

Sub saucer (obj As String, z, lm, rm, xsaucer, OffScrn)
Static way, oldway, rebound, nodc
If xsaucer = 0 Then way = 1: nodc = 0
If way < 0 Then rebound = 1 Else rebound = 0
MarqueeLIB obj, lm, rm, way, 3, xsaucer, wrapper, rebound, 1, OffScrn: z = Timer
Sound 1000, .1, .8, 1: Sound 300, .2, .5, 1, 7
If nodc < 4 And xsaucer > lm + 5 And xsaucer <= rm - Len(obj) Then
i = Int(Rnd * 30): If i = 1 Then way = -way
End If
If way <> oldway Then oldway = way: nodc = nodc + 1
End Sub

Sub MarqueeLIB (Object As String, LtMargin, RtMargin, way, y, x, wrapper, rebound, AllowOffScrn, OffScrn)
Static cnt, j, k, wmaskx, wmasklen
If way = 0 Then way = 1
If OffScrn Then OffScrn = 0: cnt = 0: j = 0: k = 0: x = 0 ' Clears static variables and resets x.
If j = 0 Then
j = Len(Object): k = 0: wmaskx = 0: wmasklen = 0: x = (RtMargin - RtMargin * way) \ 2
If way = -1 Then cnt = j Else cnt = 0
End If
If wrapper Then If RtMargin - LtMargin + 1 < j Then Cls: Print "Object too long.": End
If x > 0 And x <= RtMargin Then Locate y, x: Print Space$(k);
If way < 0 And wrapper <> 0 And x = RtMargin And cnt = j Then x = RtMargin + 1 - j
If way < 0 And cnt = 1 And wrapper = 0 Then cnt = j: x = RtMargin + 1: If AllowOffScrn Then OffScrn = 1 ' Exit left enter right.
If way > 0 And cnt = j And x = RtMargin Then ' Exit right enter left.
x = LtMargin - 1: If wrapper = 0 Then cnt = 0: If AllowOffScrn Then OffScrn = 1
End If
If OffScrn = 1 Then Exit Sub Else OffScrn = 0
If cnt < j And way > 0 Then ' Left to right text is still developing.
x = LtMargin
Else ' Either direction but left to right is at or past 1st column.
If x < RtMargin Or way < 0 Then ' Left to right but not at right margin or all right to left.
If x + way > LtMargin - 1 Then ' Right to left once entire object is visable and Left to right until object begins going off left side.
x = x + way
Else
If way > 0 Then
x = LtMargin
Else ' Left to right decreasing off left margin.
If rebound = 0 Then
cnt = cnt + way
Else ' Rebound changes direction to right.
way = 1: x = x + way
End If
End If
End If
End If
End If
If way > 0 And cnt < j Then cnt = cnt + way
If rebound And way > 0 And x + j > RtMargin Then way = -1
k = RtMargin - x + 1: If cnt < k Then k = cnt
x$ = Mid$(Object, j + 1 - cnt, k)
If wmasklen Then Locate y, wmaskx: Print Space$(wmasklen);
wmaskx = 0: wmasklen = 0
Locate y, x: Print x$;
If wrapper Then
If way < 0 Then
If j = cnt And k < j Then
wmaskx = LtMargin: wmasklen = j - k
If wmasklen Then Locate y, wmaskx: Print Mid$(Object, k + 1);
If cnt = 0 Then x = RtMargin: cnt = j: k = 1 ' For mask only. See wrapper statement after mask to reposition x.
Else
If cnt < j Then
wmaskx = RtMargin + 1 - (j - cnt): wmasklen = j - cnt
Locate y, wmaskx: Print Mid$(Object, 1, j - cnt);
If cnt = 0 Then x = RtMargin: cnt = j: k = 1
End If
End If
Else ' way > 0
If cnt < j Then
wmaskx = RtMargin + 1 - (j - cnt): wmasklen = (j - cnt)
Locate y, wmaskx: Print Mid$(Object, 1, wmasklen);
Else
If k < j Then
wmaskx = LtMargin: wmasklen = j - k
Locate y, wmaskx: Print Mid$(Object, k + 1);
End If
End If
End If
End If
End Sub

Pete
Shoot first and shoot people who ask questions, later.
Reply
#3
I Updated both posts. Added a way to wrap the text around the screen as an option.

The second one demonstrates how a space invader ship can be manipulated with the library.

Pete
Reply
#4
This stuff just never gets old... well, at least not to me!

A fun alternate method that self-masks and makes use of the fact we can put negative values in mid$().

a$ = "Six five four three two one..."
x$ = Mid$(a$, -7, 11) ' Prints Six
Print x$

A lot of languages are not so nearly forgiving and usable when manipulating strings. In most, you'd get a negative 7, 11 experience, just like the crappy hot dogs at those other 7 11s!

This is also less code. Check out MarqueeLIB, only 34 lines of code for all the special effects.
Code: (Select All)
Width 60, 20: _Font 16
Do
    Dim Object As String
    If Object = "" Then
        Object = "ÎÃÒåўÒÐÃËÃÌÂÍÓÑžÀÓÒžÑÒÃÔåўÈÓÑÒž¿Ë¿ØÇÌÅ"
        new$ = "": For i = 1 To Len(Object): x$ = Mid$(Object, i, 1): new$ = new$ + Chr$(Asc(x$) - 126): Next
        Object = new$
    End If
    LtMargin = 1: RtMargin = _Width: x = 0: y = 3: If speed = 0 Then speed = .075: GoSub info
    Do
        _Limit 60
        GoSub keyboard
        If Abs(z - Timer) > speed Then
            z = Timer
            MarqueeLIB Object, LtMargin, RtMargin, way, y, x, wrapper, rebound, AllowOffScrn, OffScrn
            If OffScrn = 1 Then Sound 700, .5: Sleep
        End If
        If OffScrn = -1 Then Exit Do
    Loop
Loop

keyboard:
b$ = InKey$
If Len(b$) Then
    Select Case b$
        Case Chr$(0) + "M": way = 1
        Case Chr$(0) + "K": way = -1
        Case Chr$(0) + "H": If speed > 0 Then i = speed * 1000: speed = (i - 10) / 1000
        Case Chr$(0) + "P": If speed < .2 Then i = speed * 1000: speed = (i + 10) / 1000
        Case "b", "B": rebound = 1 - rebound
        Case Chr$(9): OffScrn = -1: If Object <> "-é-" Then Object = "-é-": OffScrn = -1: Else Object = ""
        Case "+", "=": If RtMargin < 150 Then OffScrn = -1: RtMargin = RtMargin + 1: Width RtMargin, 20: _Font 16
        Case "-", "_": If RtMargin > 1 Then OffScrn = -1: RtMargin = RtMargin - 1: Width RtMargin, 20: _Font 16
        Case "t", "T": Cls: Line Input "Text Line: "; Object: OffScrn = -1: CLS
        Case "w", "W": wrapper = 1 - wrapper
        Case "a", "A": AllowOffScrn = 1 - AllowOffScrn
        Case Chr$(27): _Delay 1.5: System
        Case Else: Return
    End Select
    GoSub info
End If
Return

info:
If _Width > 59 Then
    View Print _Height - 1 To _Height: Cls 2: View Print
    Locate _Height - 1: Print " Way:"; way; " Delay: "; LTrim$(Str$(speed)); "  Wrap:"; wrapper; " Rebound:"; rebound; " Pause OffScrn"; AllowOffScrn;
End If
Return

Sub MarqueeLIB (Object As String, LtMargin, RtMargin, way, y, x, wrapper, rebound, AllowOffScrn, OffScrn)
    Static j, k, oldway
    If wrapper Then AllowOffScrn = 0: rebound = 0
    Dim a As String
    If j = 0 Or OffScrn = -1 Then
        j = Len(Object): oldway = 0: oldwrapper = wrapper
        If way = 0 Then way = 1
        If way > 0 Then x = LtMargin Else x = RtMargin
    End If
    If oldway And way <> oldway Then
        If way < 0 Then If x = 1 Or x = 2 Then x = k - (2 - x) Else x = x - j - 1
        If way > 0 Then If x = k Or x = k - 1 Then x = 2 - (k - x) Else x = x + j + 1
    End If
    oldway = way: OffScrn = 0
    k = RtMargin + 1 - LtMargin
    a = Space$(RtMargin + 1 - LtMargin)
    If way > 0 Then
        i = x - j + 1: If i < 1 Then i = 1
        Mid$(a, i) = Mid$(Object, j + 1 - x)
        If wrapper Then If x > k Then Mid$(a, 1) = Mid$(Object, j - (x - 1 - k)) Else Mid$(a, k - Len(Object) + x + 1) = Mid$(Object, 1, Len(Object) - x)
    End If
    If way < 0 Then
        Mid$(a, x) = Mid$(Object, 1)
        If wrapper Then If x < 0 Then Mid$(a, k + x) = Mid$(Object, 1, -x + 1) Else Mid$(a, 1) = Mid$(Object, k + 2 - x)
    End If
    Locate y, LtMargin: Print a;
    If way > 0 Then
        x = x + 1: If x > k + j Then If wrapper Then x = j Else x = LtMargin
    Else
        x = x - 1: If j + x = 1 Then If wrapper Then x = k + 1 - j Else x = k
    End If
    If rebound Then If x = 0 Or x > k Then way = -way
    If AllowOffScrn Then If way > 0 And x = 1 Or way < 0 And x = k Then OffScrn = 1: Locate y, LtMargin: Print Space$(k);
End Sub

Pete
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Simple Finances Utility ASCIIhole 6 435 02-02-2026, 06:21 PM
Last Post: ASCIIhole
  Screen fonts in SCREEN 0 BDS107 14 3,576 07-08-2025, 08:05 PM
Last Post: madscijr
  Keymapper Utility eoredson 0 506 05-31-2025, 01:38 AM
Last Post: eoredson
  Another Directory Tree Utility eoredson 0 484 04-18-2025, 02:52 AM
Last Post: eoredson
  The Copyit Utility eoredson 4 1,267 04-17-2025, 04:11 AM
Last Post: eoredson

Forum Jump:


Users browsing this thread: 1 Guest(s)