Tvaders
#11
James,

So 'that' is what the beastie is supposed to look like? Could I impose upon you for yet another favour and provide an "in game" screen shot? I have been experimenting with different 'characters'... My characters put the "ug" in ugly... lol

By the way... am I permitted to add a little colour? (I like the 'green' / 'light gray' text of the old monitors)

Please correct me if I am wrong... would not 'inkey' provide a quicker response than 'inkey$'? Reason: When changing directions, there is a momentary pause, before the ship moves... unless 'that' is the desired effect... If so, just ignore the suggestion... Now... Let us talk about sound... Nah. Kidding. "Text" sound effects are great!

Looking forward to your next creation... Do you take requests? If so, I think a Text Version of Doom, would be awesome... But Donkey Kong or a Lunar Lander may be slightly easier... lol
May your journey be free of incident. Live long and prosper.
Reply
#12
Colorize away !   I tried to keep it as simple as I could, so I didn't do much that was fancy with the code. I've still got the shield feature to add. Here's a screen shot from level 5.  
[Image: image.png]
Reply
#13
(09-27-2022, 07:54 PM)johnno56 Wrote: Please correct me if I am wrong... would not 'inkey' provide a quicker response than 'inkey$'? Reason: When changing directions, there is a momentary pause, before the ship moves... unless 'that' is the desired effect... If so, just ignore the suggestion... Now... Let us talk about sound... Nah. Kidding. "Text" sound effects are great!
Perhaps you meant "_KEYDOWN()" instead of the first "inkey"? Response to user input is difficult to get right in a game, and in a programming tool for hobbyists this is noticed most easily. In QB64PE is because "_DELAY" or "_LIMIT" must be used to free CPU cycles and to wait a little bit to give the user some time to react to the bad guys. The "FOR... NEXT" loops that had to be used in ancient BASIC's also held up keyboard input.
I've tried to set up a loop of, say 10 iterations doing "_DELAY 0.01" and polling for a key each time but the response was a bit less sluggish than the "simple" method of only one "_DELAY", or a "_LIMIT" controlling the main loop of the program. I created a game that I will post on these forums in the near future, which illustrates the problem with reacting to user input quickly. I almost forgot to mention that the time has to be taken into account processing how the bad guys move and, in addition, if the game board is to react to what the user does (for example going from one room to another in a dungeon). M$QB had the "KEY() ON/OFF/STOP" crew but that was a dangerous way to program and, for an EXE file, it required a compiler switch which added overhead. "Dangerous" because if the screen was drawn slowly and it had to update everytime the characters moved in the game, pressing a key would have revealed a visual glitch or else worse.
The OS has to cooperate for "delay" requests 20ms or even smaller, which is another thing to try to beat.
Another thing is that I noticed the QB64PE IDE is sadder on Linux than on Windows with user input, especially holding down a key for a few seconds. Sometimes on Linux (doesn't matter which distro) the input is late. It must be the reliance on the ancient terminal and graphics code borrowed from Unix and the difficulty of providing an input method which is more efficient, for the fear that it makes things incompatible. I don't know how is it with you guys able to spend thousands of USD on quad-core CPU with 8GB+ RAM and so on.
On Ubuntu for example it might be better to disable key-repeat globally in the OS, only for the sake of keeping some sanity using the QB64PE IDE. But some people don't like punching the same key more than 20 times if not the space bar in a first-person shooter...

(09-27-2022, 07:54 PM)johnno56 Wrote: By the way... am I permitted to add a little colour? (I like the 'green' / 'light gray' text of the old monitors)
I agree with you as long as the background is green and the ALL UPPERCASE text is black, like my Color Computer. Heart
https://colorcomputerarchive.com/xroar-online/
Reply
#14
INKEY$ will move fast enough for this game. INP(96) is faster, but harder to control. I seldom use the QB64 key input methods. You can also make routines to clear the keyboard buffer and control the repeat rate, if needed.

Pete
Reply
#15
Thanks for the images (time to remove the ugly bits... lol) and the 'key' tips... Much appreciated.

Pete,

TRS80 CoCo... Nice... Perhaps Black text of green background for 'daytime' coding and reversed for 'night' coding? Oh... How about a routine that will modify background and text based on system time? I digress. Thank you for the suggestion... Cool...
May your journey be free of incident. Live long and prosper.
Reply
#16
Added shields. Not 100% thrilled with them but they mostly work.


Code: (Select All)
'Tvaders  1b
'by James D. Jarvis   ,   you are of course free to modiyt and share this code as you like
'
'a text-mode qb64 retro-shooter
'
'$dynamic
Screen _NewImage(100, 35, 0)
_Title "Tvaders 1"
Type spritetype
    s As String
    w As Integer 'i wanted to make this a byte but i want to be a tiny bit backwards compatible for folks with different versions
    sx As Integer
    sy As Integer
    hdg As Integer
End Type
Dim Shared a(16) As spritetype
Dim Shared ps As spritetype
Dim Shared ss(10) As spritetype
Dim Shared b(100) As spritetype
Dim Shared aspace(100, 35)
Dim Shared shieldrow(100)
Dim Shared a$, gflag$
Dim Shared shotmax, shotspeed, shottimer, aliencount, aliendelay, alientimer, alive, level, score
Dim Shared boltmax, bolttimer, boltspeed, alienfire, shields, shieldy, shieldcounter
_ControlChr Off
Randomize Timer
Read a$
Read ship$
Read bolt$
Read shot$
ps.s = ship$
ps.w = 8
ps.sx = 32
ps.sy = 31
a(1).s = a$
a(1).w = 8
a(1).sx = 1
a(1).sy = 3
a(1).hdg = 1
For n = 1 To 100
    b(n).s = bolt$
    b(n).w = 1
    b(n).sx = 0
    b(n).sy = 0
Next n
For n = 1 To 10
    ss(n).s = shot$
    ss(n).w = 2
    ss(n).sx = 0
    ss(n).sy = 0
Next n
For n = 1 To 100
    shieldrow(n) = 0
Next n
gflag$ = "GAMEON"
shotmax = 3
shotspeed = 10
shottimer = 0
aliencount = 1
aliendelay = 20
alientimer = 0
alive = aliencounter
level = 1
boltmax = 100
bolttimer = 0
boltspeed = 9
shieldy = 29


startlevel level
Do
    _Limit 60
    handleshots
    handlealiens
    handlezaps
    handleshields
    Cls
    Locate 1, 1
    Print "LEVEL : "; level
    Locate 1, 40
    Print "Shields : "; shields
    Locate 1, 70
    Print "SCORE : "; score
    Locate 2, 1
    Print "ALive "; alive
    If gflag$ = "BOOM" Then doboom
    For bc = 1 To 100
        If b(bc).sx > 0 Then splat b(bc).s, b(bc).w, b(bc).sx, b(bc).sy
    Next bc
    For sr = 1 To 100

        If shieldrow(sr) > 0 Then
            _PrintString (sr, shieldy), "*"
        End If
    Next sr
    For ac = 1 To aliencount
        If a(ac).sx > 0 Then
            splat a(ac).s, a(ac).w, a(ac).sx, a(ac).sy

        End If
    Next ac

    splat ps.s, ps.w, ps.sx, ps.sy
    For s = 1 To shotmax
        If ss(s).sx <> 0 Then splat ss(s).s, ss(s).w, ss(s).sx, ss(s).sy
    Next s

    kk$ = InKey$
    If LCase$(kk$) = "a" Or kk$ = "," Or kk$ = "<" Then ps.sx = ps.sx - 1
    If LCase$(kk$) = "d" Or kk$ = "." Or kk$ = ">" Then ps.sx = ps.sx + 1
    If LCase$(kk$) = "s" Then shieldon ps.sx
    If kk$ = " " Then fire ps.sx + 3
    If ps.sx < 1 Then ps.sx = 1
    If ps.sx > 92 Then ps.sx = 92
    If alive < 1 Then nextlevel level
    _Display
Loop Until kk$ = Chr$(27) Or gflag$ = "GAMEOVER"

System

'sprites were orignally drawn in ascii tilemaker and stripped out of the data file without the color data for use here
Data "ÛÛÛÛÛÛÛÛ Û0  0Û ÛÛÛÛÛÛÛÛ ^ ^^ ^ "
Data "   ²²      ÎΠ    ²²²²  ²²^²²^²²"
Data "/\/"
Data "##^^"


Sub fire (fx)
    shotfound = 0
    noshots = 0
    If shieldrow(fx) <= 0 Or shieldrow(fx + 2) <= 0 Then
        Do
            noshots = noshots + 1
            If ss(noshots).sx = 0 Then shotfound = noshots
        Loop Until shotfound > 0 Or noshots = shotmax
        If shotfound > 0 Then
            ss(shotfound).sx = fx
            ss(shotfound).sy = ps.sy - 2
        End If
    End If
End Sub
Sub shieldon (sxx)
    If shields > 0 Then
        shields = shields - 1
        For so = sxx To sxx + 7
            shieldrow(so) = shieldrow(so) + 3
        Next so
    End If
End Sub
Sub zap (zx, zy)
    zapfound = 0
    zapcount = 0
    Do
        zapcount = zapcount + 1
        If b(zapcount).sx = 0 Then zapfound = zapcount
    Loop Until zapfound > 1 Or zapcount = boltmax
    If zapcount > 0 Then
        b(zapcount).sx = zx + 4
        b(zapcount).sy = zy + 3
    End If

End Sub

Sub handleshields
    shieldcounter = shieldcounter + 1

    For sr = 1 To 100
        If shieldrow(sr) < 0 Then shieldrow(sr) = 0
        If shieldcounter = 200 Then
            shieldrow(sr) = shieldrow(sr) - 1

        End If
    Next sr
    If shieldcounter = 200 Then shieldcounter = 0
End Sub

Sub handlezaps
    bolttimer = bolttimer + 1
    If bolttimer = boltspeed Then
        bolttimer = 0
        For n = 1 To 100
            If b(n).sx > 0 Then
                b(n).sy = b(n).sy + 1
                If b(n).sy = 33 Then
                    b(n).sx = 0
                    b(n).sy = 0
                End If
                If b(n).sy = 27 And shieldrow(b(n).sx) > 0 Then
                    b(n).sy = 0: b(n).sx = 0
                    shieldrow(b(n).sx) = shieldrow(b(n).sx) - 1
                End If

                If b(n).sy = 31 Then
                    For xx = ps.sx To ps.sx + 7
                        If b(n).sx = xx Then playerhit$ = "BOOM"
                        If playerhit$ = "BOOM" Then
                            For rr = 1 To 20
                                _Limit 150
                                For d = 1 To 300
                                    _PrintString (2 + Int(Rnd * 98), 5 + Int(Rnd * 30)), "*"
                                Next d
                                _PrintString (b(n).sx + Int(Rnd * 3), b(n).sy + Int(Rnd * 3)), "BOOM!"
                                gflag$ = "BOOM"
                                _Display

                            Next rr
                        End If
                    Next xx
                End If
            End If
        Next n
    End If
End Sub


Sub handleshots
    shottimer = shottimer + 1
    If shottimer = shotspeed Then
        hittag$ = "miss"
        For s = 1 To shotmax
            For aa = 1 To aliencount
                If a(aa).sx > 0 Then
                    sl = Len(a(aa).s)
                    sh = sl / a(aa).w
                    For y = 1 To sh
                        For x = 1 To a(aa).w
                            If a(aa).sx + x - 1 = ss(s).sx And a(aa).sy + y - 1 = ss(s).sy And hittag$ = "miss" Then hittag$ = "hit"
                        Next x
                    Next
                End If

                If hittag$ = "hit" Then
                    ss(s).sx = 0
                    a(aa).sx = 0
                    alive = alive - 1
                    hittag$ = "miss"
                    score = score + 100
                    Beep
                End If
            Next aa


            ss(s).sy = ss(s).sy - 2
            If ss(s).sy < 1 Then
                ss(s).sx = 0
                ss(s).sy = 0
            End If
        Next s
        shottimer = 0
    End If
End Sub

Sub handlealiens
    alientimer = alientimer + 1
    If alientimer > 32000 Then alientimer = 1
    For n = 1 To aliencount
        If a(n).sx > 0 And (alientimer Mod aliendelay = 0) Then

            a(n).sx = a(n).sx + a(n).hdg
            If a(n).sx > 92 Then
                a(n).sx = 92
                a(n).sy = a(n).sy + 2
                a(n).hdg = a(n).hdg * -1
            End If
            If a(n).sx < 1 Then
                a(n).sx = 1
                a(n).sy = a(n).sy + 2
                a(n).hdg = a(n).hdg * -1
            End If
            If 1 + Int(Rnd * 100) <= alienfire Then zap a(n).sx, a(n).sy

            If a(n).sy = 31 Then

                For xx = ps.sx To ps.sx + 7
                    If a(n).sx = xx Then playerhit$ = "BOOM"
                    If playerhit$ = "BOOM" Then
                        For rr = 1 To 20
                            _Limit 150
                            For d = 1 To 300
                                _PrintString (2 + Int(Rnd * 98), 5 + Int(Rnd * 30)), "*"
                            Next d
                            _PrintString (a(n).sx + Int(Rnd * 3), a(n).sy + Int(Rnd * 3)), "BOOM!"
                            gflag$ = "BOOM"
                            _Display

                        Next rr
                    End If
                Next xx


            End If

        End If
    Next
End Sub




Sub splat (SA$, ww As Integer, sx As Integer, sy As Integer)
    sl = Len(SA$)
    sh = sl / ww
    For y = 1 To sh
        _PrintString (sx, sy - 1 + y), Mid$(SA$, (y - 1) * ww + 1, ww)
    Next
End Sub

Sub startlevel (level)
    For bb = 1 To 100
        b(bb).sx = 0
        b(bb).sy = 0
    Next bb
    For n = 1 To 10
        ss(n).sx = 0
        ss(n).sy = 0
    Next n
    For sr = 1 To 100
        shieldrow(sr) = 0
    Next sr
    shieldcounter = 0
    Select Case level
        Case 1
            aliencount = 1
            alive = 1
            aliendelay = 20
            a(1).s = a$
            a(1).w = 8
            a(1).sx = 46
            a(1).sy = 3
            a(1).hdg = 1
            shields = 0
            score = 0
            alienfire = 0
        Case 2
            aliencount = 3
            alive = 3
            aliendelay = 20
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).sx = n * 12 + 30
                a(n).sy = 3
                a(n).hdg = 1
            Next n
            shields = 3
            alienfire = 2
        Case 3
            aliencount = 5
            alive = 5
            aliendelay = 19
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).sx = n * 11 + 20
                a(n).sy = 4
                a(n).hdg = 1
            Next n
            shields = shields + 2
            alienfire = 4
        Case 4
            aliencount = 6
            alive = 6
            aliendelay = 19
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).sx = n * 15
                a(n).sy = 5
                a(n).hdg = 1
            Next n
            shields = shields + 2
            alienfire = 6
        Case 5
            aliencount = 7
            alive = 7
            aliendelay = 18
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = 1
            Next n
            For n = 1 To 5
                a(n).sx = n * 15
                a(n).sy = 1
            Next n
            For n = 6 To 7
                a(n).sx = (n - 5) * 35
                a(n).sy = 5
            Next n

            shields = shields + 2
            alienfire = 6
        Case 6
            aliencount = 8
            alive = 8
            aliendelay = 18
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = 1
            Next n
            For n = 1 To 3
                a(n).sx = n * 25
                a(n).sy = 3
            Next n
            For n = 4 To aliencount
                a(n).sx = (n - 3) * 12
                a(n).sy = 7
            Next n

            shields = shields + 2
            alienfire = 8
        Case 7
            aliencount = 9
            alive = 9
            aliendelay = 17
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = 1
            Next n
            For n = 1 To 3
                a(n).sx = n * 12
                a(n).sy = 3
            Next n
            For n = 4 To 6
                a(n).sx = (n - 3) * 12 + 30
                a(n).sy = 7
                a(n).hdg = -1
            Next n
            For n = 7 To 9
                a(n).sx = (n - 6) * 12
                a(n).sy = 11
            Next n


            shields = shields + 2
            alienfire = 8
        Case 8
            aliencount = 10
            alive = 10
            aliendelay = 17
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = Int(Rnd * 2) - 1
                If a(n).hdg = 0 Then a(n).hdg = 1
                a(n).sx = 12 + Int(Rnd * 8) * 8
                a(n).sy = 1 + Int(Rnd * 3) * 4
            Next n

            shields = shields + 2
            alienfire = 9
        Case 9
            aliencount = 11
            alive = 11
            aliendelay = 16
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = -2
            Next n
            For n = 1 To 5
                a(n).sx = n * 12 + 12
                a(n).sy = 3

            Next n
            For n = 6 To aliencount
                a(n).sx = (n - 5) * 8
                a(n).sy = 7
            Next n
            shields = shields + 2
            alienfire = 9
        Case 10
            aliencount = 12
            alive = 12
            aliendelay = 16
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = Int(Rnd * 4) - 2
                If a(n).hdg = 0 Then a(n).hdg = 1
                a(n).sx = 12 + Int(Rnd * 8) * 8
                a(n).sy = 1 + Int(Rnd * 3) * 4
            Next n


            shields = shields + 1
            alienfire = 10
        Case 11
            aliencount = 13
            alive = 13
            aliendelay = 15
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = -2
            Next n

            For n = 1 To 7
                a(n).sx = n * 12
                a(n).sy = 1 + Int(Rnd * 3) * 4
            Next n

            For n = 8 To aliencount
                a(n).sx = (n - 7) * 12
                a(n).sy = 13
            Next n


            shields = shields + 1
            alienfire = 1
        Case 12
            aliencount = 14
            alive = 14
            aliendelay = 14


            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
            Next n

            For n = 1 To 7
                a(n).sx = n * 9
                a(n).sy = 1
                a(n).hdg = -2
            Next n

            For n = 8 To aliencount
                a(n).sx = (n - 7) * 9
                a(n).sy = 11
                a(n).hdg = 2
            Next n



            shields = shields + 1
            alienfire = 11
        Case 13
            aliencount = 15

            alive = 15
            aliendelay = 13
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
            Next n

            For n = 1 To 10
                a(n).sx = (n * 9) - 8
                a(n).sy = 2
                a(n).hdg = -2
            Next n

            For n = 11 To aliencount
                a(n).sx = (n - 10) * 9
                a(n).sy = 9
                a(n).hdg = 3
            Next n


            shields = shields + 1
            alienfire = 12
        Case 14
            aliencount = 16
            alive = 16
            aliendelay = 12
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
            Next n

            For n = 1 To 8
                a(n).sx = (n * 9) - 8
                a(n).sy = 2
                a(n).hdg = -3
            Next n

            For n = 9 To aliencount
                a(n).sx = (n - 8) * 9
                a(n).sy = 11
                a(n).hdg = 3
            Next n

            shields = shields + 1
            alienfire = 13
        Case 15
            aliencount = 16
            alive = 16
            aliendelay = 10
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
            Next n

            For n = 1 To 9
                a(n).sx = (n * 9) - 8
                a(n).sy = 4
                a(n).hdg = -3
            Next n

            For n = 10 To 14
                a(n).sx = (n - 9) * 9 + 4
                a(n).sy = 9
                a(n).hdg = 3
            Next n
            For n = 15 To aliencount
                a(n).sx = (n - 14) * 20 + 40
                a(n).sy = 13
                a(n).hdg = 4
            Next n



            shields = shields + 1
            alienfire = 14
        Case 16
            aliencount = 16
            alive = 16
            aliendelay = 8
            For n = 1 To aliencount
                a(n).s = a$
                a(n).w = 8
                a(n).hdg = Int(Rnd * 8) - 4
                If a(n).hdg = 0 Then a(n).hdg = 4
            Next n

            For x = 0 To 3
                For y = 1 To 4
                    a(x * 4 + y).sx = x * 20
                    a(x * 4 + y).sy = y * 5
                Next y
            Next x



            shields = shields + 1
            alienfire = 15

    End Select
End Sub

Sub nextlevel (level)
    If level < 17 Then
        score = score + level * 1000
        Locate 10, 10
        Cls
        _KeyClear
        Print "*********************************************************"
        Print "*                                                       *"
        Print "*                 COMPLETED LEVEL                       *"
        Print "*                                                       *"
        Print "*                 PRESS ANY KEY                         *"
        Print "*                                                       *"
        Print "*               TO START NEXT LEVEL                     *"
        Print "*                                                       *"
        Print "*                                                       *"
        Print "*********************************************************"
        _Display
        any$ = Input$(1)
        level = level + 1
        If level < 17 Then startlevel level
        If level = 17 Then gameflag$ = "GAMEOVER"

    End If
    If level = 17 Or gameflag$ = "GAMEOVER" Then
        Cls
        Locate 10, 10
        _KeyClear
        Print "*********************************************************"
        Print "*                                                       *"
        Print "                    CONGRATULATIONS !                    "
        Print "*                                                       *"
        Print "              You Have Defeated the ALIENs!              "
        Print "*                                                       *"
        Print
        Print "           FINAL SCORE : "; score
        Print
        Print "*                 PRESS Y to Play again                 *"
        Print "                                                         "
        Print "*                                                       *"
        Print "*********************************************************"
        _Display
        any$ = Input$(1)
        If any$ = "y" Or any$ = "Y" Then
            gfla$ = "GAMEON"
            startlevel 1

        Else
            Cls

            gflag$ = "GAMEOVER"
        End If

    End If

End Sub
Sub doboom


    _KeyClear
    Locate 10, 10: Print "*********************************************************"
    Locate 11, 10: Print "* ÛÛÛÛÛÛÛÛ                                              *"
    Locate 12, 10: Print "   Û0  0Û          B O O M !                             "
    Locate 13, 10: Print "* ÛÛÛÛÛÛÛÛ                                              *"
    Locate 14, 10: Print "   ^ ^^ ^    You Were Defeated by the ALIENs!              "
    Locate 15, 10: Print "*                                                       *"
    Locate 16, 10: Print
    Locate 17, 10: Print "           FINAL SCORE : "; score
    Locate 18, 10: Print
    Locate 19, 10: Print "*                 PRESS Y to Play again       ÛÛÛÛÛÛÛÛ  *"
    Locate 20, 10: Print "       ÛÛÛÛÛÛÛÛ                                Û0  0Û    "
    Locate 21, 10: Print "*       Û0  0Û                                ÛÛÛÛÛÛÛÛ   *"
    Locate 22, 10: Print "*********************************************************"
    _Display
    any$ = Input$(1)
    If any$ = "y" Or any$ = "Y" Then
        gflag$ = "GAMEON"
        startlevel 1

    Else
        Cls

        gflag$ = "GAMEOVER"
    End If

End Sub
Reply




Users browsing this thread: 7 Guest(s)