Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 483
» Latest member: aplus
» Forum threads: 2,799
» Forum posts: 26,392

Full Statistics

Latest Threads
New QBJS Samples Site
Forum: QBJS, BAM, and Other BASICs
Last Post: DANILIN
41 minutes ago
» Replies: 24
» Views: 823
School themes from USSR a...
Forum: Programs
Last Post: DANILIN
51 minutes ago
» Replies: 24
» Views: 1,929
fast file find with wildc...
Forum: Help Me!
Last Post: SpriggsySpriggs
1 hour ago
» Replies: 8
» Views: 101
Raspberry OS
Forum: Help Me!
Last Post: RhoSigma
2 hours ago
» Replies: 4
» Views: 72
Merry Christmas Globes!
Forum: Programs
Last Post: SpriggsySpriggs
2 hours ago
» Replies: 5
» Views: 56
Need help capturng unicod...
Forum: General Discussion
Last Post: SpriggsySpriggs
4 hours ago
» Replies: 25
» Views: 344
List of file sound extens...
Forum: Help Me!
Last Post: SMcNeill
11 hours ago
» Replies: 13
» Views: 215
Merry Christmas Globes!
Forum: Christmas Code
Last Post: SierraKen
Today, 02:59 AM
» Replies: 1
» Views: 28
Tenary operator in QB64 w...
Forum: Utilities
Last Post: Pete
Today, 12:24 AM
» Replies: 6
» Views: 94
Video Renamer
Forum: Works in Progress
Last Post: Pete
Yesterday, 11:52 PM
» Replies: 3
» Views: 66

 
  Minor Issue with Audio
Posted by: justsomeguy - 08-11-2024, 05:46 PM - Forum: GitHub Discussion - Replies (8)

Hello

I sorry to keep bothering you guys with issues. I'm writing a game that has background music that is looping. I fade the music in and fade it out, so that it doesn't sound abrupt when starting to play or when I want it to end. So, this somewhat depends on the length of the sound clip.

So, I use _SNDLEN (handle) get the length of the sound clip. With version 3.14, _SNDLEN() no longer reports the length of a sound file that has the *.ogg extention. It returns 0 length. It has a handle and it will play it, just _SNDLEN() returns 0. 

I checked with *.mp3 and they report the correct length.

Version 3.13 works correctly with either extension .

Sample code and couple of .ogg files.

I'm running Linux.

Code: (Select All)

DIM AS STRING sndFile
DIM AS LONG sndH
DIM AS DOUBLE sndL

sndFile = _OPENFILEDIALOG$("Open Sound File", "", "*.mp3|*.ogg|*.wav|*.flac", "Audio files", -1)

IF sndFile <> "" THEN
sndH = _SNDOPEN(sndFile)
IF sndH > 0 THEN
  _SNDVOL sndH, .25
  sndL = _SNDLEN(sndH)
  _SNDPLAY sndH
  PRINT "File:"; sndFile
  PRINT "Sound Handle:"; sndH
  PRINT "Sound Length:"; sndL
END IF
END IF

END IF


.ogg   fx_drop_004.ogg (Size: 9.09 KB / Downloads: 35)

.ogg   fx_question_003.ogg (Size: 10.09 KB / Downloads: 44)

Print this item

  Tech Invaders 5
Posted by: SierraKen - 08-11-2024, 12:41 AM - Forum: Programs - Replies (5)

Hi all,

It feels great to be programming again. Some of you might remember this Space Invaders / Galaga type game I made a few years ago called Tech Invaders. Today I decided to spruce it up and make it go faster, therefore more fun to play. I added one or two other tweaks also to make it more enjoyable. As with before, there's 5 boss aliens and I'm pretty sure that if you beat all 5 bosses, it starts over again, with no end to the game. And like before, it makes the "toptentech.txt" file for the Top Ten scores. Enjoy!

-Ken

Code: (Select All)

'Tech Invaders 5 Warp Edition
'Game made on July 1, 2022
'Version 5 made on August 10, 2024.
'By SierraKen
'Freeware
'-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'Additions: Made the game a lot faster.
'------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_ScreenMove _Middle
begin:
_Limit 1000
Dim name$(50), nm$(50), score(50), sccc(50)
Dim x As Single, y As Single, x2 As Single, y2 As Single, x5 As Single, y5 As Single, x6 As Single, y6 As Single, x7 As Single, y7 As Single, xt As Single, yt As Single
Dim enemy As Single, e1 As Single, e2 As Single, e3 As Single, e4 As Single
Dim lives As Single, level As Single, ushoot As Single, points As Single, level2 As Single, DD As Single, start As Single, b As Single, boss As Single
Dim xx As Single, yy As Single, xx2 As Single, yy2 As Single, xx3 As Single, yy3 As Single, xx4 As Single, yy4 As Single
Dim c1 As Single, c2 As Single, c3 As Single, c4 As Single, c5 As Single, c6 As Single
Dim x3 As Single, y3 As Single, x4 As Single, y4 As Single
Dim csaucer1 As Single, csaucer2 As Single, csaucer3 As Single
Dim sz As Single, s As Single, sec As Single, mo As Single, mouth As Single, mo2 As Single, mouth2 As Single, t As Single
Dim sx As Single, sy As Single, sx2 As Single, sy2 As Single, sx3 As Single, sy3 As Single, sx4 As Single, sy4 As Single, sx5 As Single, sy5 As Single
Dim starx(1000), stary(1000)
Dim ddx(1000), ddy(1000)
Dim sz10(1000)
Dim speed(1000)
Dim cx As Integer, cy As Integer, r As Integer, c As _Unsigned Long

_Title "Tech Invaders 5 Warp Edition - by SierraKen"
Cls
Screen _NewImage(800, 600, 32)
Print: Print: Print
For tt = 79 To 34 Step -2
    Locate 3, tt + 2: Print " "
    Locate 3, tt: Print "T"
    _Delay .03
Next tt
For ee = 79 To 36 Step -2
    Locate 3, ee + 2: Print " "
    Locate 3, ee: Print "E"
    _Delay .03
Next ee
For cc = 79 To 38 Step -2
    Locate 3, cc + 2: Print " "
    Locate 3, cc: Print "C"
    _Delay .03
Next cc
For hh = 79 To 40 Step -2
    Locate 3, hh + 2: Print " "
    Locate 3, hh: Print "H"
    _Delay .03
Next hh
For II = 79 To 54 Step -2
    Locate 3, II + 2: Print " "
    Locate 3, II: Print "I"
    _Delay .03
Next II
For NN = 79 To 56 Step -2
    Locate 3, NN + 2: Print " "
    Locate 3, NN: Print "N"
    _Delay .03
Next NN
For VV = 79 To 58 Step -2
    Locate 3, VV + 2: Print " "
    Locate 3, VV: Print "V"
    _Delay .03
Next VV
For AA = 79 To 60 Step -2
    Locate 3, AA + 2: Print " "
    Locate 3, AA: Print "A"
    _Delay .03
Next AA
For DD = 79 To 62 Step -2
    Locate 3, DD + 2: Print " "
    Locate 3, DD: Print "D"
    _Delay .03
Next DD
For EE2 = 79 To 64 Step -2
    Locate 3, EE2 + 2: Print " "
    Locate 3, EE2: Print "E"
    _Delay .03
Next EE2
For RR = 79 To 66 Step -2
    Locate 3, RR + 2: Print " "
    Locate 3, RR: Print "R"
    _Delay .03
Next RR
For ss = 79 To 68 Step -2
    Locate 3, ss + 2: Print " "
    Locate 3, ss: Print "S"
    _Delay .03
Next ss
DD = 0
Print: Print: Print
Print "                                            F I V E"
Print: Print
Print "                                    W a r p  E d i t i o n"
Print: Print: Print
Print "                                          by SierraKen"
Print: Print: Print
Print "                          Use the Mouse to steer your shooter left and right."
Print "                                    Use left Mouse Button to fire."
Print "                                      Esc to end anytime."
Print: Print: Print
Print "                                  Press Mouse Button To Start."
Do
    If _MouseInput Then
        If _MouseButton(1) Then GoTo startgame:
    End If
Loop
startgame:
Cls
e1 = 0
e2 = 0
e3 = 0
e4 = 0
lives = 5
points = 0
ushoot = 0
shooting = 0
level = 1
level2 = 1
start = 0
s = 0
xt = 400
yt = 560
b = 0
boss = 0
bosses = 1
sx2 = 0
sy2 = 0
tim = 4000
'Draw your shooter.
For sz = .25 To 10 Step .25
    Line (xt - 10 - sz, yt + 10)-(xt - sz, yt - 10), _RGB32(0, 255, 128)
    Line (xt + 10 + sz, yt + 10)-(xt + sz, yt - 10), _RGB32(0, 255, 128)
Next sz

OPENINGSOUND

Randomize Timer
'This is the start of the main loop.
go:
'Choose a random place for the enemy.
If e1 = 0 And e2 = 0 And e3 = 0 And e4 = 0 Then
    xx = Int(Rnd * 200) + 100
    yy = Int(Rnd * 100) + 40
    xx2 = Int(Rnd * 200) + 200
    yy2 = Int(Rnd * 100) + 40
    xx3 = Int(Rnd * 200) + 250
    yy3 = Int(Rnd * 100) + 40
    xx4 = Int(Rnd * 200) + 300
    yy4 = Int(Rnd * 100) + 40
End If

'Each level has its own loop so it can set a different equation and speed of the enemy.

If level = 1 Then
    c1 = 128: c2 = 127: c3 = 255
    csaucer1 = 0: csaucer2 = 0: csaucer3 = 0
    one:
    'sec is not time, it's related to the coordinate of the enemy and speed it goes related to the loop speed.
    sec = sec + .02
    s = (60 - sec) * 6 + 180
    x = Int(Sin(s / 360 * 3.141592) * 180) + 125
    y = Int(Cos(s / 25 * 3.141592) * 180) + 225
    x3 = Int(Sin(s / 360 * 3.141592) * 180) + 125
    y3 = Int(Cos(s / 25 * 3.141592) * 180) + 225
    x4 = Int(Sin(s / 360 * 3.141592) * 180) + 125
    y4 = Int(Cos(s / 25 * 3.141592) * 180) + 225
    x7 = Int(Sin(s / 360 * 3.141592) * 180) + 125
    y7 = Int(Cos(s / 25 * 3.141592) * 180) + 225

    'GOSUB to drawing draws the enemy robot.
    If e1 <> 1 Then GoSub drawing:
    If e2 <> 1 Then GoSub drawing3:
    If e3 <> 1 Then GoSub drawing4:
    If e4 <> 1 Then GoSub drawing5:
    If sec > 180 Then
        sec = 0
        GoTo onedone:
    End If

    'GOSUB's go to keyboard control and enemy shooting.
    GoSub mouse:
    If tim < 0 Then GoSub shoot:
    GoSub youshoot2:
    GoTo one:
    onedone:
End If

'This level uses the spiral equation so it's a bit different than the others.
If level = 2 Then
    c1 = 127: c2 = 216: c3 = 127
    csaucer1 = 127: csaucer2 = 216: csaucer3 = 127
    xx = 400: yy = 300
    xx2 = 100: yy2 = 300
    xx3 = 600: yy3 = 300
    For d = 160 To 0 Step -.125
        s = s + .2
        x = Cos(s * 3.141592 / 180) * d
        y = Sin(s * 3.151492 / 180) * d
        x3 = Cos(s * 3.141592 / 180) * d
        y3 = Sin(s * 3.151492 / 180) * d
        x4 = Cos(s * 3.141592 / 180) * d
        y4 = Sin(s * 3.151492 / 180) * d
        x7 = Cos(s * 3.141592 / 180) * d
        y7 = Sin(s * 3.151492 / 180) * d
        If e1 <> 1 Then GoSub drawing:
        If e2 <> 1 Then GoSub drawing3:
        If e3 <> 1 Then GoSub drawing4:
        If e4 <> 1 Then GoSub drawing5:
        GoSub mouse:
        If tim < 0 Then GoSub shoot:
        GoSub youshoot2:
    Next d
    For d = 0 To 160 Step .125
        s = s - .2
        x = Cos(s * 3.141592 / 180) * d
        y = Sin(s * 3.151492 / 180) * d
        x3 = Cos(s * 3.141592 / 180) * d
        y3 = Sin(s * 3.151492 / 180) * d
        x4 = Cos(s * 3.141592 / 180) * d
        y4 = Sin(s * 3.151492 / 180) * d
        x7 = Cos(s * 3.141592 / 180) * d
        y7 = Sin(s * 3.151492 / 180) * d
        If e1 <> 1 Then GoSub drawing:
        If e2 <> 1 Then GoSub drawing3:
        If e3 <> 1 Then GoSub drawing4:
        If e4 <> 1 Then GoSub drawing5:
        GoSub mouse:
        If tim < 0 Then GoSub shoot:
        GoSub youshoot2:
    Next d
End If

If level = 3 Then
    c1 = 255: c2 = 0: c3 = 0
    csaucer1 = 255: csaucer2 = 0: csaucer3 = 0
    three:
    sec = sec + .02
    s = (60 - sec) * 6 + 180
    x = Int(Sin(s / 360 * 3.141592) * 180) + 25
    y = Int(Cos(s / 65 * 3.141592) * 180) + 225
    x3 = Int(Sin(s / 360 * 3.141592) * 180) + 25
    y3 = Int(Cos(s / 65 * 3.141592) * 180) + 225
    x4 = Int(Sin(s / 360 * 3.141592) * 180) + 25
    y4 = Int(Cos(s / 65 * 3.141592) * 180) + 225
    x7 = Int(Sin(s / 360 * 3.141592) * 180) + 25
    y7 = Int(Cos(s / 65 * 3.141592) * 180) + 225
    If e1 <> 1 Then GoSub drawing:
    If e2 <> 1 Then GoSub drawing3:
    If e3 <> 1 Then GoSub drawing4:
    If e4 <> 1 Then GoSub drawing5:
    If sec > 60 Then
        sec = 0
        GoTo threedone:
    End If
    GoSub mouse:
    If tim < 0 Then GoSub shoot:
    GoSub youshoot2:
    GoTo three:
    threedone:
End If

If level = 4 Then
    c1 = 255: c2 = 255: c3 = 127
    csaucer1 = 255: csaucer2 = 255: csaucer3 = 127
    four:
    sec = sec + .02
    s = (60 - sec) * 6 + 180
    x = Int(Sin(s / 120 * 3.141592) * 180) + 25
    y = Int(Cos(s / 200 * 3.141592) * 180) + 225
    x3 = Int(Sin(s / 120 * 3.141592) * 180) + 75
    y3 = Int(Cos(s / 200 * 3.141592) * 180) + 225
    x4 = Int(Sin(s / 120 * 3.141592) * 180) + 125
    y4 = Int(Cos(s / 200 * 3.141592) * 180) + 225
    x7 = Int(Sin(s / 120 * 3.141592) * 180) + 325
    y7 = Int(Cos(s / 200 * 3.141592) * 180) + 225
    If e1 <> 1 Then GoSub drawing:
    If e2 <> 1 Then GoSub drawing3:
    If e3 <> 1 Then GoSub drawing4:
    If e4 <> 1 Then GoSub drawing5:
    If sec > 60 Then
        sec = 0
        GoTo fourdone:
    End If
    GoSub mouse:
    If tim < 0 Then GoSub shoot:
    GoSub youshoot2:
    GoTo four:
    fourdone:
End If
If level = 5 Then
    c1 = 133: c2 = 28: c3 = 255
    csaucer1 = 133: csaucer2 = 28: csaucer3 = 255
    five:
    sec = sec + .02
    s = (60 - sec) * 6 + 180
    x = Int(Sin(s / 45 * 3.141592) * 180) + 25
    y = Int(Cos(s / 360 * 3.141592) * 180) + 225
    x3 = Int(Sin(s / 45 * 3.141592) * 180) + 75
    y3 = Int(Cos(s / 360 * 3.141592) * 180) + 225
    x4 = Int(Sin(s / 45 * 3.141592) * 180) + 125
    y4 = Int(Cos(s / 360 * 3.141592) * 180) + 225
    x7 = Int(Sin(s / 45 * 3.141592) * 180) + 200
    y7 = Int(Cos(s / 360 * 3.141592) * 180) + 225
    If e1 <> 1 Then GoSub drawing:
    If e2 <> 1 Then GoSub drawing3:
    If e3 <> 1 Then GoSub drawing4:
    If e4 <> 1 Then GoSub drawing5:
    If sec > 60 Then
        sec = 0
        GoTo fivedone:
    End If
    GoSub mouse:
    If tim < 0 Then GoSub shoot:
    GoSub youshoot2:
    GoTo five:
    fivedone:
End If

If level = 6 Then
    e1 = 0: e2 = 1: e3 = 1: e4 = 1
    boss = 1
    c1 = 255: c2 = 0: c3 = 0
    six:
    sec = sec + .02
    s = (60 - sec) * 6 + 180
    x = Int(Sin(s / 135 * 3.141592) * 180) + 325
    y = Int(Cos(s / 33.75 * 3.141592) * 180) + 225
    GoSub drawing2:
    If sec > 120 Then
        sec = 0
        GoTo sixdone:
    End If
    GoSub mouse:
    If tim < 0 Then GoSub shoot:
    GoSub youshoot2:
    GoTo six:
    sixdone:
End If
If level = 7 Then bosses = bosses + 1: level = 1
GoTo go:
'GOTO goes back to the start of the main loop.

'Draws enemy ship #1.
drawing:
x2 = x + xx: y2 = y + yy
If x2 > 775 Then x2 = 775
If x2 < 25 Then x2 = 25
For t = 15 To 20 Step .25
    Circle (x2, y2), t, _RGB32(csaucer1, csaucer2, csaucer3), , , .5
Next t
c1 = c1 + 1: c2 = c2 + 1: c3 = c3 + 1
If c1 > 255 Then c1 = 80
If c2 > 255 Then c2 = 80
If c3 > 255 Then c3 = 80
For t = .25 To 8 Step .25
    Circle (x2, y2), t, _RGB32(c1, c2, c3), , , .5
Next t
For t = .25 To 3 Step .25
    Circle (x2 - 10, y2 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x2 + 10, y2 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x2, y2 + 10), t, _RGB32(255, 127, 0), , , .5
Next t
Return

'Draws the Boss Robot.
drawing2:
x2 = x + xx: y2 = y + yy
If x2 > 775 Then x2 = 775
If x2 < 25 Then x2 = 25
If bosses > 5 Then bosses = 1
If bosses = 1 Then
    If mouth2 > 1.8 Then mo2 = 1
    If mouth2 < .2 Then mo2 = 0
    If mo2 = 0 Then mouth2 = mouth2 + .025
    If mo2 = 1 Then mouth2 = mouth2 - .025
    c4 = 75: c5 = 75: c6 = 75
    For t = 15 To .25 Step -.25
        c4 = c4 + t / 3: c5 = c5 + t / 3: c6 = c6 + t / 3
        Circle (x2, y2), t, _RGB32(c4, c5, c6)
        Line (x2 - 14, y2 + t + 15)-(x2 + 14, y2 + t + 15), _RGB32(c4, c5, c6), BF
    Next t
    For t = .25 To 2 Step .25
        Circle (x2 - 10, y2 - 5), t, _RGB32(255, 0, 0)
        Circle (x2 + 10, y2 - 5), t, _RGB32(255, 0, 0)
    Next t
    For t = .25 To 6 Step .25
        Circle (x2, y2 + 5), t, _RGB32(255, 0, 0), _Pi, 0, mouth2
    Next t
End If
If bosses = 2 Then
    If mouth2 > 1.8 Then mo2 = 1
    If mouth2 < .2 Then mo2 = 0
    If mo2 = 0 Then mouth2 = mouth2 + .025
    If mo2 = 1 Then mouth2 = mouth2 - .025
    c4 = 75: c5 = 75: c6 = 75
    For t = 29 To .25 Step -.25
        c4 = c4 + t / 4: c5 = c5 + t / 4: c6 = c6 + t / 4
        Circle (x2, y2), t, _RGB32(c4, c5, c6), , , .5
    Next t
    For t = .25 To 2 Step .25
        Circle (x2 - 10, y2 - 5), t, _RGB32(255, 0, 0)
        Circle (x2 + 10, y2 - 5), t, _RGB32(255, 0, 0)
    Next t
    For t = .25 To 6 Step .25
        Circle (x2, y2 + 5), t, _RGB32(255, 0, 0), _Pi, 0, mouth2
    Next t
End If
If bosses = 3 Then
    If mouth2 > 1.8 Then mo2 = 1
    If mouth2 < .2 Then mo2 = 0
    If mo2 = 0 Then mouth2 = mouth2 + .025
    If mo2 = 1 Then mouth2 = mouth2 - .025
    c4 = 188: c5 = 128: c6 = 255
    Line (x2 - 29, y2 - 29)-(x2 + 29, y2 + 29), _RGB32(255, 6, 0)
    Line (x2 + 29, y2 - 29)-(x2 - 29, y2 + 29), _RGB32(255, 6, 0)
    For t = -15 To 15 Step 1
        c4 = c4 + t: c5 = c5 + t: c6 = c6 + t
        Line (x2 - 7, y2 + t)-(x2 + 7, y2 + t), _RGB32(c4, c5, c6)
    Next t
    For t = .25 To 2 Step .25
        Circle (x2 - 10, y2 - 5), t, _RGB32(255, 0, 0)
        Circle (x2 + 10, y2 - 5), t, _RGB32(255, 0, 0)
    Next t
    For t = .25 To 6 Step .25
        Circle (x2, y2 + 5), t, _RGB32(255, 0, 0), _Pi, 0, mouth2
    Next t
End If
If bosses = 4 Then
    If mouth2 > 1.8 Then mo2 = 1
    If mouth2 < .2 Then mo2 = 0
    If mo2 = 0 Then mouth2 = mouth2 + .025
    If mo2 = 1 Then mouth2 = mouth2 - .025
    c4 = 228: c5 = 188: c6 = 28
    Line (x2 - 29, y2 - 29)-(x2 + 29, y2 + 29), _RGB32(9, 255, 0)
    Line (x2 + 29, y2 - 29)-(x2 - 29, y2 + 29), _RGB32(9, 255, 0)
    Circle (x2 - 29, y2 - 29), 7, _RGB32(255, 0, 0)
    Circle (x2 + 29, y2 + 29), 7, _RGB32(255, 0, 0)
    Circle (x2 + 29, y2 - 29), 7, _RGB32(255, 0, 0)
    Circle (x2 - 29, y2 + 29), 7, _RGB32(255, 0, 0)
    For t = -15 To 15 Step 1
        c4 = c4 + t: c5 = c5 + t: c6 = c6 + t
        Line (x2 - 7, y2 + t)-(x2 + 7, y2 + t), _RGB32(c4, c5, c6)
    Next t
    For t = .25 To 2 Step .25
        Circle (x2 - 10, y2 - 5), t, _RGB32(0, 255, 0)
        Circle (x2 + 10, y2 - 5), t, _RGB32(0, 255, 0)
    Next t
    For t = .25 To 6 Step .25
        Circle (x2, y2 + 5), t, _RGB32(0, 255, 0), _Pi, 0, mouth2
    Next t
End If
If bosses = 5 Then
    If mouth2 > 1.8 Then mo2 = 1
    If mouth2 < .2 Then mo2 = 0
    If mo2 = 0 Then mouth2 = mouth2 + .025
    If mo2 = 1 Then mouth2 = mouth2 - .025
    c4 = 188: c5 = 128: c6 = 255
    For t = 20 To .25 Step -.25
        c4 = c4 + t / 4: c5 = c5 + t / 4: c6 = c6 + t / 4
        Circle (x2, y2), t, _RGB32(c4, c5, c6), , , .75
    Next t
    For t = 20 To 25 Step .25
        Circle (x2, y2), t, _RGB32(0, 0, 255), , , .75
    Next t
    For t = 25 To 29 Step .25
        Circle (x2, y2), t, _RGB32(255, 0, 0), , , .75
    Next t
    For t = .25 To 2 Step .25
        Circle (x2 - 10, y2 - 5), t, _RGB32(255, 0, 0)
        Circle (x2 + 10, y2 - 5), t, _RGB32(255, 0, 0)
    Next t
    For t = .25 To 6 Step .25
        Circle (x2, y2 + 5), t, _RGB32(255, 0, 0), _Pi, 0, mouth2
    Next t
End If
Return

'Draws enemy ship #2.
drawing3:
x5 = x3 + xx2: y5 = y3 + yy2
If x5 > 775 Then x5 = 775
If x5 < 25 Then x5 = 25
For t = 15 To 20 Step .25
    Circle (x5, y5), t, _RGB32(csaucer1, csaucer2, csaucer3), , , .5
Next t
For t = .25 To 8 Step .25
    Circle (x5, y5), t, _RGB32(c1, c2, c3), , , .5
Next t
For t = .25 To 3 Step .25
    Circle (x5 - 10, y5 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x5 + 10, y5 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x5, y5 + 10), t, _RGB32(255, 127, 0), , , .5
Next t
Return

'Draws enemy face.
drawing4:
x6 = x4 + xx3: y6 = y4 + yy3
If x6 > 775 Then x6 = 775
If x6 < 25 Then x6 = 25
If mouth > 1.8 Then mo = 1
If mouth < .2 Then mo = 0
If mo = 0 Then mouth = mouth + .025
If mo = 1 Then mouth = mouth - .025
For t = 15 To 20 Step .25
    Circle (x6, y6), t, _RGB32(csaucer1, csaucer2, csaucer3), , , .5
Next t
For t = .25 To 15 Step .25
    Circle (x6, y6), t, _RGB32(c1, c2, c3)
Next t
For t = .25 To 3 Step .25
    Circle (x6 - 10, y6 - 5), t, _RGB32(0, 255, 255)
    Circle (x6 + 10, y6 - 5), t, _RGB32(0, 255, 255)
Next t
For t = .25 To 6 Step .25
    Circle (x6, y6 + 5), t, _RGB32(0, 255, 255), _Pi, 0, mouth
Next t
Return

'Draws enemy ship #3.
drawing5:
x7 = x3 + xx4: y7 = y3 + yy4
If x7 > 775 Then x7 = 775
If x7 < 25 Then x7 = 25
For t = 15 To 20 Step .25
    Circle (x7, y7), t, _RGB32(csaucer1, csaucer2, csaucer3), , , .5
Next t
For t = .25 To 8 Step .25
    Circle (x7, y7), t, _RGB32(c1, c2, c3), , , .5
Next t
For t = .25 To 3 Step .25
    Circle (x7 - 10, y7 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x7 + 10, y7 - 5), t, _RGB32(255, 127, 0), , , .5
    Circle (x7, y7 + 10), t, _RGB32(255, 127, 0), , , .5
Next t
Return

'Mouse control for your movement and shooting.
mouse:
_Limit 200
If level = 6 And b > 0 Then
    Locate 3, 3: Print "BOSS ROBOT:"
    Line (150, 30)-(bx + 150, 50), _RGB32(227, 0, 0), BF
End If

Do While _MouseInput
    xt = _MouseX
    If _MouseButton(1) Then GoSub youshoot:
    a$ = InKey$
    If a$ = Chr$(27) Then End
Loop
For sz = .25 To 10 Step .25
    Line (xt - 10 - sz, yt + 10)-(xt - sz, yt - 10), _RGB32(0, 255, 128)
    Line (xt + 10 + sz, yt + 10)-(xt + sz, yt - 10), _RGB32(0, 255, 128)
Next sz

If xt > 780 Then xt = 780
If xt < 0 Then xt = 0

'Background Starfield
sp = .0005
tim = tim - 25
stars = Int(Rnd * 100) + 1
If stars > 15 Then
    s2 = s2 + 1
    If s2 > 950 Then s2 = 1
    'Set starting position.
    startx = Rnd * 400
    starty = Rnd * 300
    st = Int(Rnd * 360)
    x100 = (Sin(st) * startx) + 400
    y100 = (Cos(st) * starty) + 300
    starx(s2) = x100
    stary(s2) = y100
    'Set direction to move.
    ddx(s2) = ((x100 - 400) / 30)
    ddy(s2) = ((y100 - 300) / 30)
    'Set size.
    sz10(s2) = Rnd
    'Set speed
    speed(s2) = .1
End If
For t = 1 To 950
    speed(t) = speed(t) * (1.05 + sp)
    stary(t) = stary(t) + ddy(t) * speed(t)
    starx(t) = starx(t) + ddx(t) * speed(t)
    cx = starx(t): cy = stary(t)
    r = sz10(t) + .5
    c = _RGB32(255, 255, 255)
    fillCircle cx, cy, r, c
    'skip:
Next t
Line (0, 0)-(_Width, _Height), _RGB32(0, 0, 0, 20), BF
Return

'The start of your shot.
youshoot:
'sx2 and sy2 are your shot coordinates.
If ushoot = 0 Then
    sx2 = xt
    sy2 = yt - 20
    ushoot = 1
    Sound 400, .5
End If
Return

'The drawing and movement of your shot and if it reaches the enemy.
youshoot2:
If ushoot = 1 Then
    For sz = .25 To 5 Step .25
        Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
    Next sz
    sy2 = sy2 - 3
    If sy2 < 0 Then ushoot = 0: Return
    For szz = .25 To 5 Step .25
        Circle (sx2, sy2), szz, _RGB32(255, 0, 0)
    Next szz
    If sx2 > x2 - 21 And sx2 < x2 + 41 And sy2 > y2 - 11 And sy2 < y2 + 21 And e1 = 0 And boss = 0 Then
        enemy = 1
        ENEMYEXPLOSION sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy
        For sz = .25 To 5 Step .25
            Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
        Next sz
        sx = 1500
        GoSub redrawshooter:
        points = points + 100
        e1 = 1
        If e1 = 1 And e2 = 1 And e3 = 1 And e4 = 1 Then
            tim = 3000
            level = level + 1
            level2 = level2 + 1
            e1 = 0: e2 = 0: e3 = 0: e4 = 0
        End If
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5      Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        ushoot = 0
        GoTo go:
    End If
    If sx2 > x5 - 21 And sx2 < x5 + 41 And sy2 > y5 - 11 And sy2 < y5 + 21 And e2 = 0 And boss = 0 Then
        enemy = 2
        ENEMYEXPLOSION sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy
        For sz = .25 To 5 Step .25
            Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
        Next sz
        sx3 = 1500
        GoSub redrawshooter:
        points = points + 100
        e2 = 1
        If e1 = 1 And e2 = 1 And e3 = 1 And e4 = 1 Then
            tim = 3000
            level = level + 1
            level2 = level2 + 1
            e1 = 0: e2 = 0: e3 = 0: e4 = 0
        End If
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5      Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        ushoot = 0
        GoTo go:
    End If
    If sx2 > x6 - 21 And sx2 < x6 + 41 And sy2 > y6 - 11 And sy2 < y6 + 21 And e3 = 0 And boss = 0 Then
        enemy = 3
        ENEMYEXPLOSION sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy
        For sz = .25 To 5 Step .25
            Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
        Next sz
        sx4 = 1500
        GoSub redrawshooter:
        points = points + 100
        e3 = 1
        If e1 = 1 And e2 = 1 And e3 = 1 And e4 = 1 Then
            level = level + 1
            level2 = level2 + 1
            tim = 3000
            e1 = 0: e2 = 0: e3 = 0: e4 = 0
        End If
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5    Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        ushoot = 0
        GoTo go:
    End If

    If sx2 > x7 - 21 And sx2 < x7 + 41 And sy2 > y7 - 11 And sy2 < y7 + 21 And e4 = 0 And boss = 0 Then
        enemy = 5
        ENEMYEXPLOSION sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy
        For sz = .25 To 5 Step .25
            Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
        Next sz
        sx5 = 1500
        GoSub redrawshooter:
        points = points + 100
        e4 = 1
        If e1 = 1 And e2 = 1 And e3 = 1 And e4 = 1 Then
            level = level + 1
            level2 = level2 + 1
            e1 = 0: e2 = 0: e3 = 0: e4 = 0
            tim = 3000
        End If
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5    Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        ushoot = 0
        GoTo go:
    End If

    'To see if you hit the Boss.
    If sx2 > x2 - 31 And sx2 < x2 + 31 And sy2 > y2 - 11 And sy2 < y2 + 21 And e1 = 0 And boss = 1 Then
        b = b + 1
        BB = 10 - b
        If bx = 0 Then GoTo bxx:
        bxx:
        bx = BB * 10
        If bx < 0 Then GoTo bxx2:
        bxx2:
        Sound 100, 1
        points = points + 100
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5    Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        For sz = .25 To 5 Step .25
            Circle (sx2, sy2), sz, _RGB32(0, 0, 0)
        Next sz
        If b > 10 Then sx = 1500: enemy = 4: ENEMYEXPLOSION sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy
        If b < 11 Then ushoot = 0: Return
        GoSub redrawshooter:
        bx = 0
        BB = 0
        b = 0
        boss = 0
        points = points + 1000
        level = level + 1
        tim = 3000
        level2 = level2 + 1
        e1 = 0: e2 = 0: e3 = 0: e4 = 0
        lives$ = Str$(lives)
        points$ = Str$(points)
        level$ = Str$(level2)
        _Title "Tech Invaders 5    Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
        ushoot = 0
        GoTo go:
    End If
End If
Return

redrawshooter:
For sz = .25 To 10 Step .25
    Line (xt - 10 - sz, yt + 10)-(xt - sz, yt - 10), _RGB32(0, 255, 128)
    Line (xt + 10 + sz, yt + 10)-(xt + sz, yt - 10), _RGB32(0, 255, 128)
Next sz
Return

'The enemy's shot and if it reaches you.
shoot:
If shooting = 0 And e1 = 0 Then
    GoSub checktoshoot:
    sh = Int(Rnd * 10000) + 1
    If sh < shh Then GoTo nexone:
    'sx and sy are the first enemy shot coordinates.
    sx = x2
    sy = y2 + 10
    shooting = 1
    Sound 300, .5
End If
nexone:
If shooting2 = 0 And e2 = 0 Then
    GoSub checktoshoot:
    sh2 = Int(Rnd * 10000) + 1
    If sh2 < shh Then GoTo nexone2:
    'sx3 and sy3 are the second enemy shot coordinates.
    sx3 = x5
    sy3 = y5 + 10
    shooting2 = 1
    Sound 300, .5
End If
nexone2:
If shooting3 = 0 And e3 = 0 Then
    GoSub checktoshoot:
    sh3 = Int(Rnd * 10000) + 1
    If sh3 < shh Then GoTo nextwo:
    'sx4 and sy4 are the third enemy shot coordinates.
    sx4 = x6
    sy4 = y6 + 10
    shooting3 = 1
    Sound 300, .5
End If
nextwo:
If shooting4 = 0 And e4 = 0 Then
    GoSub checktoshoot:
    sh4 = Int(Rnd * 10000) + 1
    If sh4 < shh Then GoTo nexone3:
    'sx5 and sy5 are the fourth enemy shot coordinates.
    sx5 = x7
    sy5 = y7 + 10
    shooting4 = 1
    Sound 300, .5
End If

nexone3:
'To see if first enemy hit you.
If shooting = 1 And e1 = 0 Then
    For sz2 = .25 To 5 Step .25
        Circle (sx, sy), sz2, _RGB32(0, 0, 0)
    Next sz2
    sy = sy + 3
    If sy > 620 Then shooting = 0: GoTo nex4:
    For szz2 = .25 To 5 Step .25
        Circle (sx, sy), szz2, _RGB32(255, 0, 0)
    Next szz2
    If sx > xt - 20 And sx < xt + 20 And sy > yt - 1 And sy < yt + 21 Then
        For sz3 = .25 To 5 Step .25
            Circle (sx, sy), sz3, _RGB32(0, 0, 0)
        Next sz3
        shooting = 0
        GoSub explosion:
    End If
End If
nex4:
'To see if second enemy hit you.
If shooting2 = 1 And e2 = 0 Then
    For sz2 = .25 To 5 Step .25
        Circle (sx3, sy3), sz2, _RGB32(0, 0, 0)
    Next sz2
    sy3 = sy3 + 3
    If sy3 > 620 Then shooting2 = 0: GoTo nexx:
    For szz2 = .25 To 5 Step .25
        Circle (sx3, sy3), szz2, _RGB32(255, 0, 0)
    Next szz2
    If sx3 > xt - 20 And sx3 < xt + 20 And sy3 > yt - 1 And sy3 < yt + 21 Then
        For sz3 = .25 To 5 Step .25
            Circle (sx3, sy3), sz3, _RGB32(0, 0, 0)
        Next sz3
        shooting2 = 0
        GoSub explosion:
    End If
End If

nexx:
'To see if third enemy hit you.
If shooting3 = 1 And e3 = 0 Then
    For sz2 = .25 To 5 Step .25
        Circle (sx4, sy4), sz2, _RGB32(0, 0, 0)
    Next sz2
    sy4 = sy4 + 3
    If sy4 > 620 Then shooting3 = 0: GoTo nexx2:
    For szz2 = .25 To 5 Step .25
        Circle (sx4, sy4), szz2, _RGB32(255, 0, 0)
    Next szz2
    If sx4 > xt - 20 And sx4 < xt + 20 And sy4 > yt - 1 And sy4 < yt + 21 Then
        For sz3 = .25 To 5 Step .25
            Circle (sx4, sy4), sz3, _RGB32(0, 0, 0)
        Next sz3
        shooting3 = 0
        GoSub explosion:
    End If
End If

nexx2:
If shooting4 = 1 And e4 = 0 And boss = 0 Then
    For sz2 = .25 To 5 Step .25
        Circle (sx5, sy5), sz2, _RGB32(0, 0, 0)
    Next sz2
    sy5 = sy5 + 3
    If sy5 > 620 Then shooting4 = 0: Return
    For szz2 = .25 To 5 Step .25
        Circle (sx5, sy5), szz2, _RGB32(255, 0, 0)
    Next szz2
    If sx5 > xt - 20 And sx5 < xt + 20 And sy5 > yt - 1 And sy5 < yt + 21 Then
        For sz3 = .25 To 5 Step .25
            Circle (sx5, sy5), sz3, _RGB32(0, 0, 0)
        Next sz3
        shooting4 = 0
        GoSub explosion:
    End If
End If
Return

explosion:
Randomize Timer
dxx = (Rnd * 6) + -3
dyy = (Rnd * 6) + -3
dxx2 = (Rnd * 6) + -3
dyy2 = (Rnd * 6) + -3
dxx3 = (Rnd * 6) + -3
dyy3 = (Rnd * 6) + -3
dxx4 = (Rnd * 6) + -3
dyy4 = (Rnd * 6) + -3
dxx5 = (Rnd * 6) + -3
dyy5 = (Rnd * 6) + -3
dxx6 = (Rnd * 6) + -3
dyy6 = (Rnd * 6) + -3

Sound 160, .5
Sound 150, .5
Sound 140, .5
Sound 130, .5
Sound 120, .5
Sound 110, .5
Sound 100, .5
_AutoDisplay
yourexplosion:
DD = DD + 1
dxx = dxx + dxx / 4
dxx2 = dxx2 + dxx2 / 4
dxx3 = dxx3 + dxx3 / 4
dxx4 = dxx4 + dxx4 / 4
dxx5 = dxx5 + dxx5 / 4
dxx6 = dxx6 + dxx6 / 4
dyy = dyy + dyy / 4
dyy2 = dyy2 + dyy2 / 4
dyy3 = dyy3 + dyy3 / 4
dyy4 = dyy4 + dyy4 / 4
dyy5 = dyy5 + dyy5 / 4
dyy6 = dyy6 + dyy6 / 4
Line (xt + dxx, yt + dyy)-(xt + dxx + 2, yt + dyy + 2), _RGB32(255, 0, 0), BF
Line (xt + dxx2, yt + dyy2)-(xt + dxx2 + 2, yt + dyy2 + 2), _RGB32(0, 255, 0), BF
Line (xt + dxx3, yt + dyy3)-(xt + dxx3 + 2, yt + dyy3 + 2), _RGB32(255, 0, 0), BF
Line (xt + dxx4, yt + dyy4)-(xt + dxx4 + 2, yt + dyy4 + 2), _RGB32(0, 255, 0), BF
Line (xt + dxx5, yt + dyy5)-(xt + dxx5 + 2, yt + dyy5 + 2), _RGB32(255, 0, 0), BF
Line (xt + dxx6, yt + dyy6)-(xt + dxx6 + 2, yt + dyy6 + 2), _RGB32(0, 255, 0), BF
_Delay .02
If DD > 20 Then GoTo goingback
GoTo yourexplosion:
goingback:
DD = 0
Line (xt - 21, yt - 21)-(xt + 41, yt + 41), _RGB32(0, 0, 0), BF
For sz = .25 To 30 Step .5
    Circle (xt, yt), sz, _RGB32(0, 0, 0)
Next sz
Line (xt - 10, yt - 15)-(xt + 10, yt), _RGB(0, 0, 0), BF
DD = 0
lives = lives - 1
lives$ = Str$(lives)
points$ = Str$(points)
level$ = Str$(level2)
_Title "Tech Invaders 5    Lives: " + lives$ + "    Level: " + level$ + "      Score: " + points$
Line (xt - 22, yt - 42)-(xt + 42, yt + 42), _RGB32(0, 0, 0), BF
GoSub redrawshooter:
If lives = 0 Then
    Locate 20, 40: Print "G A M E  O V E R"
    Locate 22, 40: Print "Score: "; points
    Locate 23, 40: Print "Level: "; level2
    Locate 25, 40: Input "Press Enter to go to Top Ten Scores.", tt$

    'Top Ten Scores
    scc = points
    If _FileExists("toptentech.txt") Then
    Else
        Open "toptentech.txt" For Output As #1
        Restore originaltopten
        Do
            Read toptenname$, toptenscore!
            If toptenname$ = "EOF" Then Exit Do
            Print #1, toptenname$
            Print #1, toptenscore!
        Loop
        Close #1
    End If

    Open "toptentech.txt" For Input As #1
    For n = 1 To 10
        Input #1, name$(n)
        Input #1, score(n)
        If scc > score(n) And sct = 0 Then
            NN = n
            Print "You have made the Top Ten!"
            typename:
            Input "Type your name here (25 letters and spaces maximum.):", nm$(NN)
            If Len(nm$(NN)) > 25 Then
                Print "Name too long, try again."
                GoTo typename:
            End If
            sccc(NN) = scc
            sct = 1
        End If
        If n = 10 And sct = 0 Then Close #1: GoTo nex7:
    Next n
    Close #1
    nex5:
    Close #1
    Open "toptentech.txt" For Output As #1
    For n = 1 To NN
        If n <> NN Then Print #1, name$(n): Print #1, score(n)
        If n = NN Then
            Print #1, nm$(n)
            Print #1, sccc(n)
        End If
    Next n
    nex6:
    For n = NN To 10
        Print #1, name$(n): Print #1, score(n)
    Next n
    Close #1
    nex7:
    Cls
    Print: Print: Print
    Print "                                        T O P    T E N "
    Print: Print: Print
    Open "toptentech.txt" For Input As #1
    For n = 1 To 10
        If EOF(1) Then GoTo nex8:
        Input #1, name$(n)
        Input #1, score(n)
        Print "            "; n; ". "; name$(n); score(n)
    Next n
    nex8:
    Close #1
    Locate 21: Print "Play Again (Y/N)?"
    Do
        ag$ = InKey$
        If ag$ = "y" Or ag$ = "Y" Then Clear: GoTo begin:
        If ag$ = "n" Or ag$ = "N" Then End
    Loop

End If
OPENINGSOUND
Return

checktoshoot:
If level2 = 1 Then shh = 9950
If level2 = 2 Then shh = 9945
If level2 = 3 Then shh = 9940
If level2 = 4 Then shh = 9935
If level2 = 5 Then shh = 9930
If level2 = 6 Then shh = 9925
If level2 > 6 Then shh = 9920
Return

originaltopten:
Data Space Ace,7000
Data Suzy Swift,6000
Data Speedy Spencer,5000
Data Super Sam,4000
Data Battery Bob,3000
Data Karen Kryptonite,2750
Data Quick Ken,2500
Data Tiger Tessa,2250
Data Arcade Joe,2000
Data How Do U Play,1750
Data EOF,0

Sub OPENINGSOUND
    snd = 300
    snd2 = 800
    For t = 1 To 50
        If snd > 800 Then snd = 300
        If snd2 < 300 Then snd2 = 800
        snd = snd + 20
        Sound snd, .5
    Next t
End Sub

Sub ENEMYEXPLOSION (sx2, sy2, x2, y2, sx, sy, x5, y5, sx3, sy3, x6, y6, x7, y7, sx4, sy4, sx5, sy5, enemy)
    For sz4 = .25 To 5 Step .25
        Circle (sx2, sy2), sz4, _RGB32(0, 0, 0)
    Next sz4
    Sound 160, .5
    Sound 150, .5
    Sound 140, .5
    Sound 130, .5
    Sound 120, .5
    Sound 110, .5
    Sound 100, .5
    Randomize Timer
    dxx = (Rnd * 6) + -3
    dyy = (Rnd * 6) + -3
    dxx2 = (Rnd * 6) + -3
    dyy2 = (Rnd * 6) + -3
    dxx3 = (Rnd * 6) + -3
    dyy3 = (Rnd * 6) + -3
    dxx4 = (Rnd * 6) + -3
    dyy4 = (Rnd * 6) + -3
    dxx5 = (Rnd * 6) + -3
    dyy5 = (Rnd * 6) + -3
    dxx6 = (Rnd * 6) + -3
    dyy6 = (Rnd * 6) + -3
    _AutoDisplay
    explosion1:
    dd = dd + 1
    dxx = dxx + dxx / 4
    dxx2 = dxx2 + dxx2 / 4
    dxx3 = dxx3 + dxx3 / 4
    dxx4 = dxx4 + dxx4 / 4
    dxx5 = dxx5 + dxx5 / 4
    dxx6 = dxx6 + dxx6 / 4
    dyy = dyy + dyy / 4
    dyy2 = dyy2 + dyy2 / 4
    dyy3 = dyy3 + dyy3 / 4
    dyy4 = dyy4 + dyy4 / 4
    dyy5 = dyy5 + dyy5 / 4
    dyy6 = dyy6 + dyy6 / 4
    If enemy = 1 Or enemy = 4 Then
        Line (x2 + dxx, y2 + dyy)-(x2 + dxx + 2, y2 + dyy + 2), _RGB32(255, 0, 0), BF
        Line (x2 + dxx2, y2 + dyy2)-(x2 + dxx2 + 2, y2 + dyy2 + 2), _RGB32(0, 255, 0), BF
        Line (x2 + dxx3, y2 + dyy3)-(x2 + dxx3 + 2, y2 + dyy3 + 2), _RGB32(255, 0, 0), BF
        Line (x2 + dxx4, y2 + dyy4)-(x2 + dxx4 + 2, y2 + dyy4 + 2), _RGB32(0, 255, 0), BF
        Line (x2 + dxx5, y2 + dyy5)-(x2 + dxx5 + 2, y2 + dyy5 + 2), _RGB32(255, 0, 0), BF
        Line (x2 + dxx6, y2 + dyy6)-(x2 + dxx6 + 2, y2 + dyy6 + 2), _RGB32(0, 255, 0), BF
        If dd > 20 Then GoTo goingback
        GoTo explosion1:
        goingback:
        dd = 0
        Line (x2 - 21, y2 - 21)-(x2 + 41, y2 + 41), _RGB32(0, 0, 0), BF
        For sz4 = .25 To 5 Step .25
            Circle (sx2, sy2), sz4, _RGB32(0, 0, 0)
        Next sz4
        For sz4 = .25 To 5 Step .25
            Circle (sx, sy), sz4, _RGB32(0, 0, 0)
        Next sz4
    End If
    If enemy = 2 Then
        Line (x5 + dxx, y5 + dyy)-(x5 + dxx + 2, y5 + dyy + 2), _RGB32(255, 0, 0), BF
        Line (x5 + dxx2, y5 + dyy2)-(x5 + dxx2 + 2, y5 + dyy2 + 2), _RGB32(0, 255, 0), BF
        Line (x5 + dxx3, y5 + dyy3)-(x5 + dxx3 + 2, y5 + dyy3 + 2), _RGB32(255, 0, 0), BF
        Line (x5 + dxx4, y5 + dyy4)-(x5 + dxx4 + 2, y5 + dyy4 + 2), _RGB32(0, 255, 0), BF
        Line (x5 + dxx5, y5 + dyy5)-(x5 + dxx5 + 2, y5 + dyy5 + 2), _RGB32(255, 0, 0), BF
        Line (x5 + dxx6, y5 + dyy6)-(x5 + dxx6 + 2, y5 + dyy6 + 2), _RGB32(0, 255, 0), BF
        If dd > 20 Then GoTo goingback2:
        GoTo explosion1:
        goingback2:
        dd = 0
        Line (x5 - 21, y5 - 21)-(x5 + 41, y5 + 41), _RGB32(0, 0, 0), BF
        For sz5 = .25 To 5 Step .25
            Circle (sx2, sy2), sz5, _RGB32(0, 0, 0)
        Next sz5
        For sz5 = .25 To 5 Step .25
            Circle (sx3, sy3), sz5, _RGB32(0, 0, 0)
        Next sz5
    End If
    If enemy = 3 Then
        Line (x6 + dxx, y6 + dyy)-(x6 + dxx + 2, y6 + dyy + 2), _RGB32(255, 0, 0), BF
        Line (x6 + dxx2, y6 + dyy2)-(x6 + dxx2 + 2, y6 + dyy2 + 2), _RGB32(0, 255, 0), BF
        Line (x6 + dxx3, y6 + dyy3)-(x6 + dxx3 + 2, y6 + dyy3 + 2), _RGB32(255, 0, 0), BF
        Line (x6 + dxx4, y6 + dyy4)-(x6 + dxx4 + 2, y6 + dyy4 + 2), _RGB32(0, 255, 0), BF
        Line (x6 + dxx5, y6 + dyy5)-(x6 + dxx5 + 2, y6 + dyy5 + 2), _RGB32(255, 0, 0), BF
        Line (x6 + dxx6, y6 + dyy6)-(x6 + dxx6 + 2, y6 + dyy6 + 2), _RGB32(0, 255, 0), BF
        If dd > 20 Then GoTo goingback3:
        GoTo explosion1:
        goingback3:
        dd = 0
        Line (x6 - 21, y6 - 21)-(x6 + 41, y6 + 41), _RGB32(0, 0, 0), BF
        For sz5 = .25 To 5 Step .25
            Circle (sx2, sy2), sz5, _RGB32(0, 0, 0)
        Next sz5
        For sz5 = .25 To 5 Step .25
            Circle (sx4, sy4), sz5, _RGB32(0, 0, 0)
        Next sz5
    End If
    If enemy = 5 Then
        Line (x7 + dxx, y7 + dyy)-(x7 + dxx + 2, y7 + dyy + 2), _RGB32(255, 0, 0), BF
        Line (x7 + dxx2, y7 + dyy2)-(x7 + dxx2 + 2, y7 + dyy2 + 2), _RGB32(0, 255, 0), BF
        Line (x7 + dxx3, y7 + dyy3)-(x7 + dxx3 + 2, y7 + dyy3 + 2), _RGB32(255, 0, 0), BF
        Line (x7 + dxx4, y7 + dyy4)-(x7 + dxx4 + 2, y7 + dyy4 + 2), _RGB32(0, 255, 0), BF
        Line (x7 + dxx5, y7 + dyy5)-(x7 + dxx5 + 2, y7 + dyy5 + 2), _RGB32(255, 0, 0), BF
        Line (x7 + dxx6, y7 + dyy6)-(x7 + dxx6 + 2, y7 + dyy6 + 2), _RGB32(0, 255, 0), BF
        If dd > 20 Then GoTo goingback4:
        GoTo explosion1:
        goingback4:
        dd = 0
        Line (x7 - 21, y7 - 21)-(x7 + 41, y7 + 41), _RGB32(0, 0, 0), BF
        For sz5 = .25 To 5 Step .25
            Circle (sx2, sy2), sz5, _RGB32(0, 0, 0)
        Next sz5
        For sz5 = .25 To 5 Step .25
            Circle (sx5, sy5), sz5, _RGB32(0, 0, 0)
        Next sz5
    End If
End Sub

'from Steve Gold standard
Sub fillCircle (CX As Integer, CY As Integer, R As Integer, C As _Unsigned Long)
    Dim Radius As Integer, RadiusError As Integer
    Dim X As Integer, Y As Integer
    Radius = Abs(R): RadiusError = -Radius: X = Radius: Y = 0
    If Radius = 0 Then PSet (CX, CY), C: Exit Sub
    Line (CX - X, CY)-(CX + X, CY), C, BF
    While X > Y
        RadiusError = RadiusError + Y * 2 + 1
        If RadiusError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            End If
            X = X - 1
            RadiusError = RadiusError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    Wend
End Sub

Print this item

  Coding Efficiency
Posted by: SMcNeill - 08-11-2024, 12:16 AM - Forum: General Discussion - Replies (33)

To go kinda in tandem with Pete's post about coding styles, I wanted to take a second to get everyone's thoughts on Coding Efficiency.  What do you guys usually shoot for -- the most efficient code for you, or the most efficient code for your programs to run?

Everyone know bubble sorts are crap.  They're slow.  They're inefficient as heck.   And, if all we're doing is sorting a small set of items such as the order of a shopping list, or deck of cards, they're all we need!  Why bother with the time and effort to come up with something faster, when your biggest use case is sorting 100 things in 0.2 slow seconds?  My personal time as a programmer is worth more than the 0.1 second you'd save as an user of my "Shopping App Pro" program.  

Most programmers should for an adage of "Less is more".  bplus is terrible about this, with his constant need to count lines of code and use them as a marker for success.  (Not picking on bplus at all -- just using him as an example we see here on the forums, because he posts and shares these short programs a ton.)

The thing is, a lot of times, "MORE IS LESS" when it comes to coding.   For example, let's say I have a variable x that can do 100 different things..  Usually it's written in code as something like:

SELECT CASE x
   CASE 1
   CASE 2
   CASE 3
   CASE 4
   CASE 5
   ... so on.
END SELECT

Simple for the programmer to write, understand, and work with.   But wouldn't it be a lot more efficient with:

SELECT CASE x
    CASE 0 TO 50
       SELECT CASE x
          CASE 1
          CASE 2
          ...on
      END SELECT
    CASE 51 TO 100
...

We've now doubled the code for decision making, but halved the total possible number of IF checks required to process the code.  If we break it down further, binary-tree style, we can reduce it to a long arse batch of code that has to make a maximum of 8 decisions, instead of 100!

It's a lot more code on the programmer, but a lot more efficient for the program itself.



The question is, where do most of you guys try and draw the line?  How hard do you work for code efficiency, very programmer efficiency?  

Curious My-Minds Want To Know!!

Print this item

  Game Library Sneak Peek
Posted by: TerryRitchie - 08-10-2024, 06:42 PM - Forum: Works in Progress - Replies (7)

Over the past few months I have been updating my libraries and making improvements. While doing this I also decided to update that old Sprite Library I created back in 2012. However, instead of just focusing on sprites it now focuses on game creation in general. By organizing my libraries (thank you for $INCLUDEONCE !) I've been able to really make some headway with this new library. I compiled a list of functions and subroutines I have completed and was a bit shocked at what I have finished so far.

Here's a sneak peek at the commands I've finished so far. I still have a ways to go (bugs, a few more commands, documentation, testing, example programs).

Code: (Select All)
'FUNCTION SOUND__NextIndex% ()                                                - get the next available index in the sound database
'FUNCTION SOUND_Make% (FileName AS STRING, Mode AS INTEGER, Volume AS SINGLE) - loads a sound from a sound file
'FUNCTION SOUND_Exists% (hSnd AS INTEGER)                                    - returns the existence of a sound in the sound database
'    SUB SOUND_Volume (hSnd AS INTEGER, Volume AS SINGLE)                    - set the volume level of a sound
'FUNCTION SOUND_Volume! (hSnd AS INTEGER)                                    - get the volume level of a sound
'    SUB SOUND_Delete (hSnd AS INTEGER)                                      - remove a sound from RAM and the sound database
'    SUB SOUND_Play (hSnd AS INTEGER)                                        - play a sound from the sound database
'    SUB SOUND_Stop (hSnd AS INTEGER)                                        - stop one or all sounds from playing
'    SUB SOUND_Pause (hSnd AS INTEGER)                                      - pause one or all sounds from playing
'    SUB SOUND_Resume (hSnd AS INTEGER)                                      - resume playing one or all paused sounds
'FUNCTION SOUND_Paused% (hSnd AS INTEGER)                                    - returns if a sound is paused
'FUNCTION SOUND_Playing% (hSnd AS INTEGER)                                    - returns if a sound is playing
'    SUB SOUND_PlayMode (hSnd AS INTEGER, Mode AS INTEGER)                  - sets a sound's play mode
'FUNCTION SOUND_PlayMode% (hSnd AS INTEGER)                                  - returns a sound's play mode

'FUNCTION SHEET__NextIndex% ()                                                - get the next available index in the sprite sheet database
'FUNCTION SHEET_Exists% (hSht AS INTEGER)                                    - returns the existence of a sprite sheet in the sprite sheet database
'FUNCTION SHEET_Load% (Filename AS STRING, GridWidth AS INTEGER, GridHeight AS INTEGER) - load a sprite sheet into the sprite sheet database
'    SUB SHEET_Delete (hSht AS INTEGER)                                      - removes a sprite sheet from RAM and the sprite sheet database
'FUNCTION SHEET_ClearColor~& (hSht AS INTEGER)                                - returns the transparent color of a sprite sheet
'    SUB SHEET_ClearColor (hSht AS INTEGER, cColor AS _UNSIGNED LONG)        - sets the transparent color of a sprite sheet
'    SUB SHEET_GridSize (hSht AS INTEGER, GridWidth AS INTEGER, GridHeight AS INTEGER) - define a sprite sheet's grid cell dimensions
'FUNCTION SHEET_Width% (hSht AS INTEGER)                                      - returns the width of a sprite sheet
'FUNCTION SHEET_Height% (hSht AS INTEGER)                                    - returns the height of a sprite sheet
'FUNCTION SHEET_GridWidth% (hSht AS INTEGER)                                  - returns the width of the grid cells on a sprite sheet
'FUNCTION SHEET_GridHeight% (hSht AS INTEGER)                                - returns the height of the grid cells on a sprite sheet

'FUNCTION IMAGE__NextIndex% ()                                                - get the next available index in the image database
'FUNCTION IMAGE_Exists% (hImg AS INTEGER)                                    - returns the existence of an image in the image database
'FUNCTION IMAGE_Make% (hSht AS INTEGER, Column AS INTEGER, Row AS INTEGER)    - creates a still image from an individual sprite on a sprite sheet
'FUNCTION IMAGE_Load% (FileName AS STRING)                                    - creates a still image from an image file
'    SUB IMAGE_Delete (hImg AS INTEGER)                                      - remove an image from RAM and the image database
'    SUB IMAGE_ClearColor (hImg AS INTEGER, cColor AS _UNSIGNED LONG)        - sets the transparent color of an image
'FUNCTION IMAGE_ClearColor~& (hImg AS INTEGER)                                - returns the transparent color of an image
'    SUB IMAGE_Restore (hImg AS INTEGER)                                    - restores the working image to the original image
'    SUB IMAGE_Flip (hImg AS INTEGER, Flip AS INTEGER)                      - flips the working image horizontally, vertically, or both
'    SUB IMAGE_Zoom (hImg AS INTEGER, Zoom AS SINGLE)                        - zooms the working image
'    SUB IMAGE_Rotate (hImg AS INTEGER, Degree AS SINGLE)                    - rotates the working image
'    SUB IMAGE_Put (hImg AS INTEGER, x AS INTEGER, y AS INTEGER)            - draws the working image to the screen
'FUNCTION IMAGE_Width% (hImg AS INTEGER)                                      - returns the width of the working image
'FUNCTION IMAGE_Height% (hImg AS INTEGER)                                    - returns the height of the working image
'    SUB IMAGE_Brightness (hImg AS INTEGER, Level AS SINGLE)                - change the brightness level of an image
'    SUB IMAGE_Contrast (hImg AS INTEGER, Level AS SINGLE)                  - change the contrast level of an image
'    SUB IMAGE_Gamma (hImg AS INTEGER, Level AS SINGLE)                      - change the gamma level of an image
'    SUB IMAGE_Negative (hImg AS INTEGER)                                    - convert the image to a negative
'    SUB IMAGE_GrayScale (hImg AS INTEGER)                                  - convert the image to gray scale
'    SUB IMAGE_Blur (hImg AS INTEGER, Level AS INTEGER)                      - perform a gaussian blur on the image
'    SUB IMAGE_Filter (hImg AS INTEGER, Filter AS INTEGER)                  - apply a predefined filter to an image

'FUNCTION CLIP__NextIndex% ()                                                - get the next available index in the animation clip database
'FUNCTION CLIP_Exists% (hClp AS INTEGER)                                      - returns the existence of an animation clip in the clip database
'FUNCTION CLIP_Make% (hSht AS INTEGER, c AS INTEGER, r AS INTEGER, Cells AS INTEGER, Dir AS INTEGER, Mode AS INTEGER, FPS AS INTEGER) ' make clip
'FUNCTION CLIP_Load% (FileName AS STRING, cw AS INTEGER, Dir AS INTEGER, Mode AS INTEGER, FPS AS INTEGER) - load animation clip from image file
'    SUB CLIP_Delete (hClp AS INTEGER)                                      - remove animation clip from RAM and the animation clip database
'    SUB CLIP_ClearColor (hClp AS INTEGER, cColor AS _UNSIGNED LONG)        - set the transparent color of an animation clip
'FUNCTION CLIP_ClearColor~& (hClp AS INTEGER)                                - returns the transparent color of an animation clip
'FUNCTION CLIP_CellWidth% (hClp AS INTEGER)                                  - returns the width of each animation cell within an animation clip
'FUNCTION CLIP_CellHeight% (hClp AS INTEGER)                                  - returns the height of each animation cell within an animation clip
'    SUB CLIP_FPS (hClp AS INTEGER, FPS AS INTEGER)                          - sets the frames per second rate of an animation clip
'FUNCTION CLIP_FPS% (hClp AS INTEGER)                                        - returns the frames per second rate of an animation clip
'    SUB CLIP_Direction (hClp AS INTEGER, Dir AS INTEGER)                    - set the play direction of an animation clip
'FUNCTION CLIP_Direction% (hClp AS INTEGER)                                  - return the play direction of an animation clip
'    SUB CLIP_PlayMode (hClp AS INTEGER, Mode AS INTEGER)                    - set the animation clip play back mode
'FUNCTION CLIP_PlayMode% (hClp AS INTEGER)                                    - returns the animation clip play back mode
'    SUB CLIP_SoundApply (hClp AS INTEGER, hSnd AS INTEGER)                  - apply an associated sound to an animation clip
'    SUB CLIP_Restore (hClp AS INTEGER)                                      - restore the working film strip to the original film strip
'    SUB CLIP_Brightness (hClp AS INTEGER, Level AS SINGLE)                  - change the brightness level of an animation clip
'    SUB CLIP_Blur (hClp AS INTEGER, Level AS INTEGER)                      - perform a gaussian blur on the animation clip
'    SUB CLIP_Contrast (hClp AS INTEGER, Level AS SINGLE)                    - change the contrast level of an animation clip
'    SUB CLIP_Filter (hClp AS INTEGER, Filter AS INTEGER)                    - apply a predefined filter to an animation clip
'    SUB CLIP_Gamma (hClp AS INTEGER, Level AS SINGLE)                      - change the gamma level of an animation clip
'    SUB CLIP_GrayScale (hClp AS INTEGER)                                    - convert the animation clip to gray scale
'    SUB CLIP_Negative (hClp AS INTEGER)                                    - convert the animation clip to a negative

'FUNCTION SPRITE__NextIndex% ()                                              - get the next available index in the sprite database
'FUNCTION SPRITE_Exists% (hSpr AS INTEGER)                                    - returns the existence of a sprite in the sprite database
'    SUB SPRITE_Reset (hSpr AS INTEGER)                                      - resets a sprite's settings to defaults and removes associated image
'FUNCTION SPRITE_Make% ()                                                    - creates a new sprite ready to configure
'    SUB SPRITE_Delete (hSpr AS INTEGER)                                    - removes a sprite from RAM and the sprite database
'    SUB SPRITE_ImageApply (hSpr AS INTEGER, hImg AS INTEGER)                - applies an image to a sprite
'    SUB SPRITE_ClipApply (hSpr AS INTEGER, hClp AS INTEGER)                - applies an animation clip to a sprite
'    SUB SPRITE_Justify (hSpr AS INTEGER, Justify AS INTEGER)                - sets a sprite's display justification
'FUNCTION SPRITE_Justify% (hSpr AS INTEGER)                                  - returns a sprite's display justification setting
'    SUB SPRITE_Xoffset (hSpr AS INTEGER, xoffset AS INTEGER)                - set a custom x coordinate display justification offset
'    SUB SPRITE_Yoffset (hSpr AS INTEGER, yoffset AS INTEGER)                - set a custom y coordinate display justification offset
'    SUB SPRITE_Mode (hSpr AS INTEGER, Mode AS INTEGER)                      - set the sprite to still image or animation modes
'FUNCTION SPRITE_Mode% (hSpr AS INTEGER)                                      - returns the still image or animation mode of a sprite
'FUNCTION SPRITE_ClipExists% (hSpr AS INTEGER)                                - returns if an animation clip has been applied to a sprite
'    SUB SPRITE_ClipRemove (hSpr AS INTEGER)                                - remove an animation clip from a sprite and set mode to still image
'    SUB SPRITE_ImageChange (hSpr AS INTEGER, Change AS INTEGER)            - allow changes made in the image database to affect sprite images
'    SUB SPRITE_Flip (hSpr AS INTEGER, Flip AS INTEGER) '                    - flips a sprite horizontally, vertically, or both
'FUNCTION SPRITE_Flip% (hSpr AS INTEGER)                                      - returns a sprite's flipped orientation
'    SUB SPRITE_Zoom (hSpr AS INTEGER, Percent AS INTEGER)                  - zooms a sprite
'FUNCTION SPRITE_Zoom% (hSpr AS INTEGER)                                      - returns a sprite's zoom level
'    SUB SPRITE_Rotate (hSpr AS INTEGER, Degree AS SINGLE)                  - rotates a sprite from 0 to 359.999 degrees
'FUNCTION SPRITE_Rotate! (hSpr AS INTEGER)                                    - returns a sprite's rotation degree angle
'    SUB SPRITE_RotateTowardSprite (hSprFrom AS INTEGER, hSprTo AS INTEGER, Offset AS SINGLE) - rotates a sprite toward aother sprite
'    SUB SPRITE_RotateTowardPoint (hSpr AS INTEGER, x AS INTEGER, y AS INTEGER, Offset AS SINGLE) - rotates a sprite toward an x,y point
'FUNCTION SPRITE_VectorX! (hSpr AS INTEGER)                                  - returns a sprite's normalized x vector quantity
'FUNCTION SPRITE_VectorY! (hSpr AS INTEGER)                                  - returns a sprite's normalized y vector quantity
'    SUB SPRITE_Move (hSpr AS INTEGER)                                      - move a sprite in the direction of the degree angle set
'    SUB SPRITE_Draw (hSpr AS INTEGER)                                      - draw the sprite to the screen
'    SUB SPRITE_Put (hSpr AS INTEGER, x AS SINGLE, y AS SINGLE)              - moves a sprite to an x,y coordinate location
'    SUB SPRITE_PutX (hSpr AS INTEGER, x AS SINGLE)                          - moves a sprite to an x coordinate location
'    SUB SPRITE_PutY (hSpr AS INTEGER, y AS SINGLE)                          - moves a sprite to a y coordinate location
'FUNCTION SPRITE_X! (hSpr AS INTEGER)                                        - returns a sprite's x coordinate location
'FUNCTION SPRITE_Y! (hSpr AS INTEGER)                                        - returns a sprite's y coordinate location
'    SUB SPRITE_Area (hSpr AS INTEGER, x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER) ' returns the justified rectangular area of sprite
'    SUB SPRITE__ResetCollision (hSpr AS INTEGER)                            - resets a sprite's collision detection variables
'FUNCTION SPRITE_RectCollide% (hSpr1 AS INTEGER, hSpr2 AS INTEGER)            - returns a rectangular collision between two sprites
'FUNCTION SPRITE_CircCollide% (hSpr1 AS INTEGER, hSpr2 AS INTEGER)            - returns a circular collision between two sprites
'FUNCTION SPRITE_CircRectCollide% (hSpr1 AS INTEGER, hSpr2 AS INTEGER)        - returns rectangular and circular collision between two sprites
'FUNCTION SPRITE_PixelCollide% (hSpr1 AS INTEGER, hSpr2 AS INTEGER)          - returns a pixel perfect collision between two sprites
'FUNCTION SPRITE_Collide% (hSpr1 AS INTEGER, hSpr2 AS INTEGER)                - automated collision check between two sprites
'FUNCTION SPRITE_CollidedWith% (hSpr AS INTEGER)                              - returns the sprite that this sprite collided with
'FUNCTION SPRITE_Collision% (hSpr AS INTEGER)                                - returns if a sprite has been in a collision
'    SUB SPRITE_CollisionArea (hSpr AS INTEGER, x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE) ' returns rectangular area of a collision
'    SUB SPRITE_CollisionPoint (hSpr AS INTEGER, x AS SINGLE, y AS SINGLE)  - returns the x,y point of a collision
'FUNCTION SPRITE_Distance! (hSpr1 AS INTEGER, hSpr2 AS INTEGER)              - returns the distance between two sprites
'FUNCTION SPRITE_DistanceToPoint! (hSpr AS INTEGER, x AS INTEGER, y AS INTEGER) - returns the distance between a sprite and x,y coordinate point
'FUNCTION SPRITE_DistancePointToPoint! (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE) ' returns the distance between two x,y coordinates
'FUNCTION SPRITE_Seconds& ()                                                  - returns the number of seconds that FPS limiting has been active
'    SUB SPRITE_SpeedX (hSpr AS INTEGER, Speed AS SINGLE)                    - sets a sprite's x vector magnitude
'FUNCTION SPRITE_SpeedX! (hSpr AS INTEGER)                                    - returns a sprite's x vector magnitude
'    SUB SPRITE_SpeedY (hSpr AS INTEGER, Speed AS SINGLE)                    - sets a sprite's y vector magnitude
'FUNCTION SPRITE_SpeedY! (hSpr AS INTEGER)                                    - returns a sprite's y vector magnitude
'    SUB SPRITE_Reverse (hSpr AS INTEGER)                                    - reverse a sprite's direction by 180 degrees
'    SUB SPRITE_ReverseX (hSpr AS INTEGER)                                  - reverse a sprite's x vector direction
'    SUB SPRITE_ReverseY (hSpr AS INTEGER)                                  - reverse a sprite's y vector direction
'    SUB SPRITE_Status (hSpr AS INTEGER, Status AS INTEGER)                  - set a sprite's status (ignore, normal, pause)
'FUNCTION SPRITE_Status% (hSpr AS INTEGER)                                    - returns a sprite's status (ignore, normal, pause)
'    SUB SPRITE_Visible (hSpr AS INTEGER, Flag AS INTEGER)                  - set a sprite's on-screen visibility
'FUNCTION SPRITE_Visible% (hSpr AS INTEGER)                                  - return a sprite's on-screen visibility
'    SUB SPRITE_GlobalFPS (GlobalFPS AS INTEGER)                            - set the global frames per second rate
'FUNCTION SPRITE_GlobalFPS% ()                                                - return the global frames per second rate
'    SUB SPRITE_ResetFPS ()                                                  - reset the global frame and second counter
'    SUB SPRITE_LimitFPS ()                                                  - limit a loop to the global frames per second rate
'FUNCTION SPRITE_GlobalFrame% ()                                              - return the current global frame number
'    SUB SPRITE_ClipReset (hSpr AS INTEGER)                                  - reset a sprite's animation clip to default settings
'FUNCTION SPRITE_ClipNext% (hSpr AS INTEGER)                                  - advance to the next cell in the animation clip film strip
'    SUB SPRITE_ClipDirection (hspr AS INTEGER, Dir AS INTEGER)              - set a sprite's animation clip play direction
'FUNCTION SPRITE_ClipDirection% (hSpr AS INTEGER)                            - return a sprite's animation clip play direction
'    SUB SPRITE_ClipFPS (hSpr AS INTEGER, fps AS INTEGER)                    - set a sprite's animation clip frames per second rate
'FUNCTION SPRITE_ClipFPS% (hSpr AS INTEGER)                                  - return a sprite's animation clip frames per second rate
'    SUB SPRITE_ClipPlayMode (hSpr AS INTEGER, Mode AS INTEGER)              - set a sprite's animation clip play mode (once, loop)
'FUNCTION SPRITE_ClipPlayMode% (hSpr AS INTEGER)                              - return a sprite's animation clip play mode (once, loop)
'FUNCTION SPRITE_ClipFrame% (hSpr AS INTEGER)                                - return the frame number of a sprite's animation clip
'FUNCTION SPRITE_ClipCell% (hSpr AS INTEGER)                                  - return a sprite's current animation clip film strip cell in use
'FUNCTION SPRITE_ClipCellWidth% (hSpr AS INTEGER)                            - return a sprite's animation clip film strip cell width
'FUNCTION SPRITE_ClipCellHeight% (hSpr AS INTEGER)                            - return a sprite's animation clip film strip cell height
'    SUB SPRITE_Display ()                                                  - automated updating of all sprite characteristics and drawing
'    SUB SPRITE__Error (SubFunc AS STRING, Report AS STRING)                - report all errors found to programmer

Print this item

  Do you think we'll have new hobby programmers 10 years in the future?
Posted by: Pete - 08-10-2024, 05:16 PM - Forum: General Discussion - Replies (16)

With the growth of A.I., I wonder. Right now the programs A.I. can write are of varying languages, including QB64, but the so-called A.I. gets things wrong, meaning the code won't run. Now a hobbyist programmer can tweak that code, maybe 10% - 20% and get it working for projects of nominal size. Sine A.I. will continue to improve... funny if they could get it to actually try running the code it produces... (I wonder if A.I. is aware of words like f**k and damn, already? Oh well, I digress. Anyway, since it will continue to improve, what do you guys think? 10 years from now do you think we will see new users of QB64 and other languages, or will it be all Star Trek programming. Computer, make me a transparent aluminum whale container?

Pete

Print this item

  The program does not terminate
Posted by: krovit - 08-09-2024, 11:06 PM - Forum: Help Me! - Replies (11)

Hello everyone!
This code performs some operations on network interfaces and the system date.
Considering that the executable has administrator privileges, I note that the executable does not terminate and the execution remains suspended.
The code includes delays to allow the execution of commands, especially on network interfaces, which notoriously take time.
I also note that the execution goes all the way through (the network is reactivated and the system date is restored correctly) but the output on the screen (which is also misaligned with the window) stops at the executed ping.
Is this a bug or what? Any suggestions?

Thank you!


Code: (Select All)

SHELL ("powershell -Command " + CHR$(34) + "Get-NetAdapter | Enable-NetAdapter -Confirm:$false" + CHR$(34))


ex$ = MID$(DATE$, 7, 4) + "-" + MID$(DATE$, 4, 2) + "-" + LEFT$(DATE$, 2) + "T" + TIME$

' Disabilita le schede di rete
SHELL "cmd /c powershell -Command " + CHR$(34) + "Get-NetAdapter | Disable-NetAdapter -Confirm:$false" + CHR$(34)
PRINT "step 1 fatto"

SLEEP 5 ' Attendi un momento per assicurarti che le schede siano disabilitate

' Controlla se la rete è disattivata
PRINT "Controllo stato della rete..."
SHELL "cmd /c ping -n 4 8.8.8.8" ' Pinga un server per verificare la disattivazione della rete
PRINT "Ping eseguito."

' Imposta la data e l'ora
SHELL "cmd /c powershell -Command " + CHR$(34) + "Set-Date -Date 2023-10-01T14:30:00" + CHR$(34)
PRINT "step 2 fatto"

SLEEP 2 ' Aggiungi un ritardo

' Imposta la data e l'ora attuale
SHELL "cmd /c powershell -Command " + CHR$(34) + "Set-Date -Date " + ex$ + CHR$(34)
PRINT "step 3 fatto"

SLEEP 2 ' Aggiungi un ritardo di 2 secondi

' Riabilita le schede di rete
SHELL "cmd /c powershell -Command " + CHR$(34) + "Get-NetAdapter | Enable-NetAdapter -Confirm:$false" + CHR$(34)
PRINT "step 4 fatto"

SLEEP 2 ' Aggiungi un ritardo finale
PRINT "Comandi eseguiti."

Print this item

  Coding Styles
Posted by: Pete - 08-09-2024, 03:09 PM - Forum: General Discussion - Replies (33)

One of the things I love most about BASIC is the flexibility to code in various styles including declaring or not declaring variable types. This saved me a bunch of time back in the early days when memory was at a premium. I would use single letter variables, and DEFINT at the top of each program to assign A-G as variable length strings, H-P as integers, and other letters for long, double, etc. as needed. Also making most if not all of your variables integer types was an important for speed back in the day. There is also the choice to pass variables to sub routines as global variables. I did that almost exclusively. It sure takes the work out of passing a long laundry list of variables to several sub routines. The best compromise between these two methods, I think, is using UDT's, except, of course if you are heavy into arrays. I wish those could be supported some day, but, anyway, I found it much easier to pass UDT's in sub calls, as the whole grouping gets passed instead of typing out each passed variable.

So, anyone want to chime in on what they have found to be helpful coding styles for their projects? Maybe how and why you evolved to the way you code today, etc? It might make for a fun discussion thread, and a nice reference to help share knowledge.

Pete

Print this item

Heart QB64-PE v3.14.0 is now available
Posted by: RhoSigma - 08-08-2024, 04:48 PM - Forum: Announcements - Replies (27)

Visit GitHub for download.

Enhancements

  • #499 - Reliably enable window defocus on Linux. - @flukiluke
  • #501 - Modifies `_FILES$` to default to the * pattern rather than *.* when fileSpec$ is empty, enabling `_FILES$` to retrieve all directory entries rather than omitting files and directories that lack an extension. - @a740g
  • #502 - Optimize IDE internal string concatenation somewhat to reduce IDE lag. - @SteveMcNeill
  • #503 - Allow `_UPRINTSTRING` to render directly into any image, which can be specified as an optional argument. - @a740g
  • #506 - Added Metacommands and Variable Types items to the Help menu for quick access to these essential help pages. - @RhoSigma-QB64
  • #508 - Introducing the brand new Format Mode as command line switch. - @flukiluke
    - The -y command line option will format the input instead of compiling it.
    - Formatting is performed either according to the current IDE settings (Options > Code Layout...) or by overriding those settings using the new -f flags, e.g. `./qb64pe -y source/qb64pe.bas -f:autolayout=true -f:keywordcapitals=true -f:autoindent=true -f:autoindentsize=4 -f:indentsubs=true -o source/qb64pe.bas`
  • #510 - Optimizes `_DEFLATE$` and `_INFLATE$` to eliminate unnecessary buffer copies. This results in a nice speed boost of upto 15% in some cases. - @a740g
  • #517 - Stabilized and updated MIDI support. - @a740g
    - MIDI support in QB64-PE is finally out of the `$UNSTABLE` state now.
    - The compiled executable will no longer include an embedded soundfont.
    - To address this issue https://qb64phoenix.com/forum/showthread.php?tid=1962 discussed in the forum, ymfmidi, Opal, and a tiny FM bank are now used.
    - Soundfonts can be loaded using the _MIDISOUNDBANK command.
    - Depending on the sound bank type, a suitable MIDI rendering backend is selected.
    - The available backends are primesynth (SF2), TinySoundFont (SF3, SFO), and Opal (AD, OPL, OP2, TMB, WOPL).
    - For Windows users, a VSTi 2.x based renderer that is configurable by the user is also provided.
    - Multiple MIDI file formats are supported: MUS, HMI, HMP, HMQ, KAR, LDS, MDS, MIDS, RCP, R36, G18, G36, RMI, MID, MIDI, XFM, XMI
    - The use of `$UNSTABLE:MIDI` and `$MIDISOUNDFONT` triggers an appropriate "deprecated feature" warning message now.
  • #519 - Various IDE improvements. - @RhoSigma-QB64
    - Changing certain toggle settings in the Options Menu no longer causes your code to be marked as "changed".
    - IDE related config and workfiles were moved out of `internal/temp` into `settings` directly under the `qb64pe` folder.
    - Note the folder does not exist in the release archives, but is created on the first IDE run, at this time the user has a choice to import his settings from another QB64-PE installation or to continue with default settings.
    - The recent files and search string histories are globally shared now by all running IDE instances, limits can be set in the Undo/History... dialog (Options Menu).
    - We've added 4 new preset color schemes, Cornfield, Broadcast, X11 SgiColors by me (@RhoSigma-QB64) and VS Code curtesy to @a740g. If you use your own custom scheme, then it's ID will be automatically adjusted when importing your settings.
  • #520 - `_LOADIMAGE` and `_SAVEIMAGE` improvements. - @a740g
    - Added support to load ICO (icon) and CUR (cursor) files.
    - Added support to save ICO (icon) and single GIF (not animated ones) files.
  • #525 - Improving IDE Option dialogs. - @RhoSigma-QB64
    - Numeric input boxes now have spinner buttons
    - Invalid input turns the input box into error color

Lib/MinGW Updates
  • #513 - Updated nanosvg and stb_image to latest available versions. - @a740g
  • #522 - Update to LLVM-MinGW 20240619 with LLVM 18.1.8 for WoA. - @a740g

Bug Fixes
  • #497, #527 - Properly initialise memory when REDIMming with UDT, fix #331, #524. - @flukiluke
  • #500 - Allow setting environment variables with space in values on Linux, fix #386. - @flukiluke
  • #503 - Font fixes, in some fonts the underscore was clipped away with `_UPRINTSTRING`. - @a740g
  • #506 - IDE Help fixes. - @RhoSigma-QB64
    - Select All (CTRL-A) in the help text actually didn't select ALL after text was selected manually once before, because some internal variables were not reset correctly (bug dates back to the ancient SDL versions).
    - Fixed Definition Lists eating the first text char, if the list introducer is followed by a space.
  • #513 - Fixed the PCX image loader issues reported in the forum https://qb64phoenix.com/forum/showthread.php?tid=2792. - @a740g
  • #515 - Avoid eating 0-argument functions used after L/UBOUND, fix #244. - @flukiluke
  • #523 - Fixing a bug in the `KILL` command, which would previously terminate and fail to process the remaining files if the user opted to continue after an error condition. - @a740g

Full Changelog: https://github.com/QB64-Phoenix-Edition/......v3.14.0

Developer Notice
We are probably going to deprecate the $NOPREFIX feature sooner or later in the future. Nothing is finally decided yet, but as we have more and more efforts to keep new things compatible with $NOPREFIX it's a decision we've to make. Especially CONST and the pre-compiler metacommands show bad interactions with $NOPREFIX over and over again and make implementations overcomplicated.

With this notice we wish to get your attention for the issue and recommend to adapt your coding habits to no longer rely on $NOPREFIX right now, so it becomes an easy transition when we finally drop it.

Print this item

  Tasklist
Posted by: BDS107 - 08-08-2024, 01:59 PM - Forum: Help Me! - Replies (11)

Can you request a list in QB64 like the DOS command TASKLIST?
You can of course use a SHELL and save the result temporarily on disk. But that is too slow if you want to update constantly. So, I don't want this.

Print this item

  Using the tenary operator in C with 3 numbers
Posted by: Kernelpanic - 08-08-2024, 12:52 PM - Forum: Utilities - Replies (16)

The tenary operator was discussed here for some time ago, a bit complicated in Basic. It is quite useful for simple comparisons.

The program uses the tenary operator in C with a triple comparison. It also works with four numbers, but that gets a bit confusing. If one only want to compare two numbers, simply enter 0 for the third number. -- Both files in the same directory.

Code: (Select All)

'Aufruf des tenaeren Operators in C - 8. Aug. 2024

Option _Explicit

Declare Library "D:\Lab\QuickBasic64\Extern-nicht-Basic\Basic-ruft-C\btenaerDreifach"
  Function btenaerDreifach& (ByVal Zahl1 As Long, Byval Zahl2 As Long, Byval Zahl3 As Long)
End Declare

Dim As Long zahl1, zahl2, zahl3

Locate 3, 3
Print "Dreifachen tenaeren Operator in C aufrufen"
Locate 4, 3
Print "=========================================="

Locate 6, 3
Input "Zahl 1: ", zahl1

Locate 7, 3
Input "Zahl 2: ", zahl2

Locate 8, 3
Input "Zahl 3: ", zahl3

Locate 10, 3
Print Using "Die groesste Zahl ist: ####"; btenaerDreifach&(zahl1&, zahl2&, zahl3&)

End

Save the C program as btenaerDreifach.h
Code: (Select All)

//Dreifachen tenaeren Operator von Basic aufrufen - 7. Aug. 2024

#include <stdio.h>
#include <stdlib.h>

long btenaerDreifach(long zahl1, long zahl2, long zahl3)
{
long max;

max = (zahl1 > zahl2 ? ((zahl1 > zahl3) ? zahl1 : zahl3) : zahl2);

return(max);
}

Print this item