-' Svjatoslav Agejenko\r
-' Use keys:\r
-' Up, Down, Left, Right, w, z - rotate\r
-' <space> - speed down\r
-' q - quit\r
-\r
-DECLARE SUB getcor ()\r
-DECLARE SUB mulcor ()\r
-DECLARE SUB nait3d ()\r
-DECLARE SUB calcsin ()\r
-DEFINT A-Z\r
-DIM SHARED Xn(100), Yn(100), Zn(100)\r
-DIM SHARED Xs1(100), Ys1(100), Xe1(100), Ye1(100)\r
-DIM SHARED x(100), y(100), z(100), pointers1(100), pointers2(100)\r
-DIM SHARED Cosine&(360), Sine&(360)\r
-DIM SHARED np, nl\r
-DIM SHARED jrp, jrl\r
-jrp = 0\r
-jrl = 0\r
-\r
-\r
-SCREEN 12\r
-CLS\r
-\r
-\r
-calcsin\r
-getcor\r
-mulcor\r
-nait3d\r
-\r
-\r
-\r
-\r
-DATA 5, -60, -10\r
-DATA 15,-50, -10\r
-DATA 15, 0, -10\r
-DATA 5, 10, -10\r
-DATA -5, 10, -10\r
-DATA -15, 0, -10\r
-DATA -15,-50, -10\r
-DATA -5, -60, -10\r
-\r
-DATA 5, -60, 10\r
-DATA 15,-50, 10\r
-DATA 15, 0, 10\r
-DATA 5, 10, 10\r
-DATA -5, 10, 10\r
-DATA -15, 0, 10\r
-DATA -15,-50, 10\r
-DATA -5, -60, 10\r
-\r
-DATA 5, 20, 10\r
-DATA 15, 30, 10\r
-DATA 15, 40, 10\r
-DATA 5, 50, 10\r
-DATA -5, 50, 10\r
-DATA -15, 40, 10\r
-DATA -15, 30, 10\r
-DATA -5, 20, 10\r
-\r
-DATA 5, 20, -10\r
-DATA 15, 30, -10\r
-DATA 15, 40, -10\r
-DATA 5, 50, -10\r
-DATA -5, 50, -10\r
-DATA -15, 40, -10\r
-DATA -15, 30, -10\r
-DATA -5, 20, -10\r
-\r
-DATA 999,999,999\r
-\r
-DATA 0,1\r
-DATA 1,2\r
-DATA 2,3\r
-DATA 3,4\r
-DATA 4,5\r
-DATA 5,6\r
-DATA 6,7\r
-DATA 7,0\r
-\r
-DATA 8,9\r
-DATA 9,10\r
-DATA 10,11\r
-DATA 11,12\r
-DATA 12,13\r
-DATA 13,14\r
-DATA 14,15\r
-DATA 15,8\r
-\r
-\r
-DATA 0,8\r
-DATA 1,9\r
-DATA 2,10\r
-DATA 3,11\r
-DATA 4,12\r
-DATA 5,13\r
-DATA 6,14\r
-DATA 7,15\r
-\r
-DATA 16,17\r
-DATA 17,18\r
-DATA 18,19\r
-DATA 19,20\r
-DATA 20,21\r
-DATA 21,22\r
-DATA 22,23\r
-DATA 23,16\r
-\r
-\r
-DATA 24,25\r
-DATA 25,26\r
-DATA 26,27\r
-DATA 27,28\r
-DATA 28,29\r
-DATA 29,30\r
-DATA 30,31\r
-DATA 31,24\r
-\r
-DATA 24,16\r
-DATA 25,17\r
-DATA 26,18\r
-DATA 27,19\r
-DATA 28,20\r
-DATA 29,21\r
-DATA 30,22\r
-DATA 31,23\r
-\r
-DATA 999, 999\r
-\r
-SUB calcsin\r
-FOR a! = 0 TO 359 / 57.29577951# STEP 1 / 57.29577951#\r
- Cosine&(a) = INT(.5 + COS(a!) * 1024)\r
- Sine&(a) = INT(.5 + SIN(a!) * 1024)\r
- a = a + 1\r
-NEXT\r
-END SUB\r
-\r
-SUB getcor\r
-FOR a = 0 TO 10000\r
- READ x(a), y(a), z(a)\r
- IF x(a) = 999 THEN x(a) = 0: y(a) = 0: z(a) = 0: GOTO 1\r
-NEXT\r
-1\r
-np = a\r
-\r
-FOR a = 0 TO 10000\r
- READ pointers1(a), pointers2(a)\r
- IF pointers1(a) = 999 THEN GOTO 2\r
-NEXT\r
-2\r
-nl = a\r
-\r
-END SUB\r
-\r
-SUB mulcor\r
-suur = 0\r
-FOR a = 0 TO np\r
-IF ABS(x(a)) > suur THEN suur = ABS(x(a))\r
-IF ABS(y(a)) > suur THEN suur = ABS(y(a))\r
-IF ABS(z(a)) > suur THEN suur = ABS(z(a))\r
-NEXT a\r
-ksuur = 100 / suur\r
-\r
-FOR a = 0 TO np\r
-x(a) = x(a) * ksuur\r
-y(a) = y(a) * ksuur\r
-z(a) = z(a) * ksuur\r
-NEXT a\r
-END SUB\r
-\r
-SUB nait3d\r
-\r
-DO\r
-\r
- Deg1 = Deg1 + d1\r
- Deg2 = Deg2 + d2\r
- Deg3 = Deg3 + d3\r
- \r
- IF Deg1 <= 0 THEN Deg1 = Deg1 + 360\r
- IF Deg2 <= 0 THEN Deg2 = Deg2 + 360\r
- IF Deg3 <= 0 THEN Deg3 = Deg3 + 360\r
- \r
- IF Deg1 >= 360 THEN Deg1 = Deg1 - 360\r
- IF Deg2 >= 360 THEN Deg2 = Deg2 - 360\r
- IF Deg3 >= 360 THEN Deg3 = Deg3 - 360\r
- \r
- C1& = Cosine&(Deg1): S1& = Sine&(Deg1)\r
- C2& = Cosine&(Deg2): S2& = Sine&(Deg2)\r
- C3& = Cosine&(Deg3): S3& = Sine&(Deg3)\r
- \r
-FOR a = 0 TO np - 1\r
-R = a\r
-Xo = x(R): Yo = y(R): Zo = z(R)\r
- \r
-X1 = (Xo * C1& - Yo * S1&) \ 1024\r
-Y1 = (Xo * S1& + Yo * C1&) \ 1024\r
- \r
-X2& = (X1 * C2& - Zo * S2&) \ 1024\r
-z1 = (X1 * S2& + Zo * C2&) \ 1024\r
- \r
-Y2& = (Y1 * C3& - z1 * S3&) \ 1024\r
-z2 = (Y1 * S3& + z1 * C3&) \ 1024\r
- \r
-z2 = z2 + 300\r
-Xn(R) = 320 + (X2& / z2 * 500)\r
-Yn(R) = 240 + (Y2& / z2 * 500)\r
-NEXT\r
- \r
-\r
-FOR a1 = 0 TO nl - 1\r
-F1 = pointers1(a1)\r
-S1 = pointers2(a1)\r
- \r
-Xn = Xn(F1)\r
-Yn = Yn(F1)\r
- \r
-X1 = Xn(S1)\r
-Y1 = Yn(S1)\r
- \r
-LINE (Xs1(a1), Ys1(a1))-(Xe1(a1), Ye1(a1)), 0\r
-LINE (X1, Y1)-(Xn, Yn), 15\r
- \r
-\r
-Xs1(a1) = X1: Ys1(a1) = Y1\r
-Xe1(a1) = Xn: Ye1(a1) = Yn\r
-NEXT\r
- \r
-\r
-K$ = INKEY$\r
-IF K$ <> "" THEN\r
-\r
-SELECT CASE K$\r
-\r
-CASE CHR$(0) + CHR$(72)\r
-d1 = d1 + 1\r
-\r
-CASE CHR$(0) + CHR$(80)\r
-d1 = d1 - 1\r
-\r
-CASE CHR$(0) + CHR$(75)\r
-d2 = d2 - 1\r
-\r
-CASE CHR$(0) + CHR$(77)\r
-d2 = d2 + 1\r
-\r
-CASE "w"\r
-d3 = d3 - 1\r
-\r
-CASE "z"\r
-d3 = d3 + 1\r
-\r
-CASE " "\r
-d1 = d1 / 2\r
-d2 = d2 / 2\r
-d3 = d3 / 2\r
-\r
-CASE CHR$(27)\r
-SYSTEM\r
-\r
-END SELECT\r
-END IF\r
-\r
-LOOP\r
-END SUB\r
-\r
+' 3D Wireframe Exclamation mark
+' Author: Svjatoslav Agejenko
+' Use keys:
+' Up, Down, Left, Right, w, z - rotate
+' <space> - speed down
+' q - quit
+
+DECLARE SUB GetCoordinates ()
+DECLARE SUB ScaleCoordinates ()
+DECLARE SUB Render3D ()
+DECLARE SUB CalculateSineCosine ()
+
+DefInt A-Z
+Dim Shared Xn(100), Yn(100), Zn(100)
+Dim Shared Xs1(100), Ys1(100), Xe1(100), Ye1(100)
+Dim Shared x(100), y(100), z(100), pointers1(100), pointers2(100)
+Dim Shared Cosine&(360), Sine&(360)
+Dim Shared numPoints, numLines
+Dim Shared rotationX, rotationY
+rotationX = 0
+rotationY = 0
+
+Screen 12
+Cls
+CalculateSineCosine
+GetCoordinates
+ScaleCoordinates
+Render3D
+
+' Vertex data
+Data 5,-60,-10
+Data 15,-50,-10
+Data 15,0,-10
+Data 5,10,-10
+Data -5,10,-10
+Data -15,0,-10
+Data -15,-50,-10
+Data -5,-60,-10
+Data 5,-60,10
+Data 15,-50,10
+Data 15,0,10
+Data 5,10,10
+Data -5,10,10
+Data -15,0,10
+Data -15,-50,10
+Data -5,-60,10
+Data 5,20,10
+Data 15,30,10
+Data 15,40,10
+Data 5,50,10
+Data -5,50,10
+Data -15,40,10
+Data -15,30,10
+Data -5,20,10
+Data 5,20,-10
+Data 15,30,-10
+Data 15,40,-10
+Data 5,50,-10
+Data -5,50,-10
+Data -15,40,-10
+Data -15,30,-10
+Data -5,20,-10
+Data 999,999,999
+
+' Line data
+Data 0,1
+Data 1,2
+Data 2,3
+Data 3,4
+Data 4,5
+Data 5,6
+Data 6,7
+Data 7,0
+Data 8,9
+Data 9,10
+Data 10,11
+Data 11,12
+Data 12,13
+Data 13,14
+Data 14,15
+Data 15,8
+Data 0,8
+Data 1,9
+Data 2,10
+Data 3,11
+Data 4,12
+Data 5,13
+Data 6,14
+Data 7,15
+Data 16,17
+Data 17,18
+Data 18,19
+Data 19,20
+Data 20,21
+Data 21,22
+Data 22,23
+Data 23,16
+Data 24,25
+Data 25,26
+Data 26,27
+Data 27,28
+Data 28,29
+Data 29,30
+Data 30,31
+Data 31,24
+Data 24,16
+Data 25,17
+Data 26,18
+Data 27,19
+Data 28,20
+Data 29,21
+Data 30,22
+Data 31,23
+Data 999,999
+
+Sub CalculateSineCosine
+ ' Precalculate sine and cosine values for faster computation
+ For angle! = 0 To 359 / 57.29577951# Step 1 / 57.29577951#
+ Cosine&(angle) = Int(.5 + Cos(angle!) * 1024)
+ Sine&(angle) = Int(.5 + Sin(angle!) * 1024)
+ angle = angle + 1
+ Next
+End Sub
+
+Sub GetCoordinates
+ ' Read vertex coordinates from DATA statements
+ For i = 0 To 10000
+ Read x(i), y(i), z(i)
+ If x(i) = 999 Then x(i) = 0: y(i) = 0: z(i) = 0: GoTo EndVertexData
+ Next
+ EndVertexData:
+ numPoints = i
+
+ ' Read line data from DATA statements
+ For i = 0 To 10000
+ Read pointers1(i), pointers2(i)
+ If pointers1(i) = 999 Then GoTo EndLineData
+ Next
+ EndLineData:
+ numLines = i
+End Sub
+
+Sub ScaleCoordinates
+ ' Scale coordinates to fit the screen
+ maxValue = 0
+ For i = 0 To numPoints
+ If Abs(x(i)) > maxValue Then maxValue = Abs(x(i))
+ If Abs(y(i)) > maxValue Then maxValue = Abs(y(i))
+ If Abs(z(i)) > maxValue Then maxValue = Abs(z(i))
+ Next i
+ scaleFactor = 100 / maxValue
+ For i = 0 To numPoints
+ x(i) = x(i) * scaleFactor
+ y(i) = y(i) * scaleFactor
+ z(i) = z(i) * scaleFactor
+ Next i
+End Sub
+
+Sub Render3D
+ Do
+ ' Update rotation angles
+ rotationX = rotationX + dx
+ rotationY = rotationY + dy
+ rotationZ = rotationZ + dz
+ Sound 0, 1
+
+ ' Wrap rotation angles within 0 to 359 degrees
+ If rotationX <= 0 Then rotationX = rotationX + 360
+ If rotationY <= 0 Then rotationY = rotationY + 360
+ If rotationZ <= 0 Then rotationZ = rotationZ + 360
+ If rotationX >= 360 Then rotationX = rotationX - 360
+ If rotationY >= 360 Then rotationY = rotationY - 360
+ If rotationZ >= 360 Then rotationZ = rotationZ - 360
+
+ ' Get sine and cosine values for rotation angles
+ cosX& = Cosine&(rotationX): sinX& = Sine&(rotationX)
+ cosY& = Cosine&(rotationY): sinY& = Sine&(rotationY)
+ cosZ& = Cosine&(rotationZ): sinZ& = Sine&(rotationZ)
+
+ ' Rotate and project vertices
+ For i = 0 To numPoints - 1
+ Xo = x(i): Yo = y(i): Zo = z(i)
+ X1 = (Xo * cosX& - Yo * sinX&) \ 1024
+ Y1 = (Xo * sinX& + Yo * cosX&) \ 1024
+ X2& = (X1 * cosY& - Zo * sinY&) \ 1024
+ Z1 = (X1 * sinY& + Zo * cosY&) \ 1024
+ Y2& = (Y1 * cosZ& - Z1 * sinZ&) \ 1024
+ Z2 = (Y1 * sinZ& + Z1 * cosZ&) \ 1024
+ Z2 = Z2 + 300
+ Xn(i) = 320 + (X2& / Z2 * 500)
+ Yn(i) = 240 + (Y2& / Z2 * 500)
+ Next
+
+ ' Draw lines between vertices
+ For i = 0 To numLines - 1
+ startVertex = pointers1(i)
+ endVertex = pointers2(i)
+ Xn = Xn(startVertex)
+ Yn = Yn(startVertex)
+ X1 = Xn(endVertex)
+ Y1 = Yn(endVertex)
+ Line (Xs1(i), Ys1(i))-(Xe1(i), Ye1(i)), 0
+ Line (X1, Y1)-(Xn, Yn), 15
+ Xs1(i) = X1: Ys1(i) = Y1
+ Xe1(i) = Xn: Ye1(i) = Yn
+ Next
+
+ ' Handle user input
+ K$ = InKey$
+ If K$ <> "" Then
+ Select Case K$
+ Case Chr$(0) + Chr$(72) ' Up arrow
+ dx = dx + 1
+ Case Chr$(0) + Chr$(80) ' Down arrow
+ dx = dx - 1
+ Case Chr$(0) + Chr$(75) ' Left arrow
+ dy = dy - 1
+ Case Chr$(0) + Chr$(77) ' Right arrow
+ dy = dy + 1
+ Case "w"
+ dz = dz - 1
+ Case "z"
+ dz = dz + 1
+ Case " " ' Space bar
+ dx = dx / 2
+ dy = dy / 2
+ dz = dz / 2
+ Case Chr$(27) ' Escape key
+ System
+ End Select
+ End If
+ Loop
+End Sub
\ No newline at end of file
-' 3D starfield\r
-' made by Svjatoslav Agejenko\r
-' in 2003.03\r
-' H-Page: svjatoslav.eu\r
-' E-Mail: svjatoslav@svjatoslav.eu\r
-\r
-DECLARE SUB setstar (x2!, y2!, z2!)\r
-DECLARE SUB galaxy ()\r
-DIM SHARED mitu\r
-DIM SHARED mituv\r
-\r
-\r
-RANDOMIZE TIMER\r
-mituv = 2000\r
-mitu = mituv\r
-rns = 500\r
-wl = 0\r
-\r
-DIM SHARED px(1 TO mitu + 1000)\r
-DIM SHARED py(1 TO mitu + 1000)\r
-DIM SHARED pz(1 TO mitu + 1000)\r
-\r
-FOR a = 1 TO mitu\r
-pz(a) = RND * 500 + 20\r
- n = RND * 100\r
- px(a) = SIN(n) * 20\r
- py(a) = COS(n) * 20\r
-NEXT a\r
-\r
-\r
-SCREEN 13\r
-\r
-\r
-frm = 10\r
-1\r
-fps = fps + 1\r
-IF tm$ <> TIME$ THEN\r
-'LOCATE 1, 1\r
-'PRINT fps\r
-IF fps > 20 THEN wl = wl + 2 ELSE wl = wl - 1\r
-IF wl < 0 THEN wl = 0\r
-fps = 0\r
-tm$ = TIME$\r
-END IF\r
-frm = frm + 1\r
-xp = SIN(frm / 21) * 3\r
-yp = SIN(frm / 18) * 3\r
-\r
-nrk = (3.1412) / 2 + SIN(frm / 35) / 100 + SIN(frm / 21) / 100\r
-rs1 = SIN(nrk)\r
-rc1 = COS(nrk)\r
-\r
-FOR a = 1 TO mitu\r
-x = px(a)\r
-y = py(a)\r
-z = pz(a)\r
-x1 = x / z * 160 + 160\r
-y1 = y / z * 100 + 100\r
-PSET (x1, y1), 0\r
-\r
-x5 = x * rs1 - y * rc1\r
-y5 = x * rc1 + y * rs1\r
-\r
-x = x5\r
-y = y5\r
-\r
-z = z - 3\r
-x = x + xp\r
-y = y + yp\r
-IF z < 10 THEN\r
-z = RND * 300 + 400\r
-x = RND * 800 - 400\r
-y = RND * 800 - 400\r
-END IF\r
-\r
-x1 = x / z * 160 + 160\r
-y1 = y / z * 100 + 100\r
-c = 3000 / z + 15\r
-IF c > 31 THEN c = 31\r
-PSET (x1, y1), c\r
-\r
-px(a) = x\r
-py(a) = y\r
-pz(a) = z\r
-NEXT a\r
-\r
-\r
-IF mituv - mitu > rns THEN galaxy: rns = RND * 800 + 100\r
-\r
-FOR a = 1 TO 2\r
-b = RND * (mitu - 10) + 1\r
-SWAP px(mitu), px(b)\r
-SWAP py(mitu), py(b)\r
-SWAP pz(mitu), pz(b)\r
-\r
-x = px(mitu)\r
-y = py(mitu)\r
-z = pz(mitu)\r
-x1 = x / z * 160 + 160\r
-y1 = y / z * 100 + 100\r
-PSET (x1, y1), 0\r
-mitu = mitu - 1\r
-NEXT a\r
-\r
-'LOCATE 2, 1\r
-'PRINT wl\r
-FOR a = 0 TO wl\r
-FOR b = 0 TO 1000\r
-c = c / 100\r
-NEXT b\r
-NEXT a\r
-\r
-IF INKEY$ <> "" THEN SYSTEM\r
-GOTO 1\r
-\r
-SUB galaxy\r
-\r
-xf = RND * 4 - 2\r
-yf = RND * 4 - 2\r
-xp = RND * 200 - 100\r
-yp = RND * 200 - 100\r
-\r
-FOR a = 1 TO RND * 15 + 10 STEP .04\r
-x = SIN(a) * a * a / 10\r
-y = COS(a) * a * a / 10\r
-setstar x + RND * a * a / 30 + xp, y + RND * a * a / 30 + yp, 700 + RND * a * a / 30 + (x * xf) + (y * yf)\r
-NEXT a\r
-\r
-'SOUND 1000, 1\r
-END SUB\r
-\r
-SUB setstar (x2, y2, z2)\r
-mitu = mitu + 1\r
-s = mitu\r
-\r
-px(s) = x2\r
-py(s) = y2\r
-pz(s) = z2\r
-END SUB\r
+' 3D Starfield Simulation\r
+' Originally made by Svjatoslav Agejenko in 2003.03\r
+' In 2024 code was modernized using artificial intelligence\r
+' Homepage: svjatoslav.eu\r
+' Email: svjatoslav@svjatoslav.eu\r
+\r
+DECLARE SUB AddStar (xPosition AS SINGLE, yPosition AS SINGLE, zPosition AS SINGLE)\r
+DECLARE SUB CreateGalaxy ()\r
+\r
+Dim Shared totalStars As Integer\r
+Dim Shared maxStars As Integer\r
+\r
+Randomize Timer\r
+maxStars = 2000\r
+totalStars = maxStars\r
+starFieldDepth = 500\r
+\r
+Dim Shared starXPositions(1 To maxStars + 1000) As Single\r
+Dim Shared starYPositions(1 To maxStars + 1000) As Single\r
+Dim Shared starZPositions(1 To maxStars + 1000) As Single\r
+\r
+' Initialize the positions of the stars\r
+For starIndex = 1 To totalStars\r
+ starZPositions(starIndex) = Rnd * starFieldDepth + 20\r
+ angle = Rnd * 100\r
+ starXPositions(starIndex) = Sin(angle) * 20\r
+ starYPositions(starIndex) = Cos(angle) * 20\r
+Next starIndex\r
+\r
+Screen 13\r
+\r
+\r
+Do\r
+\r
+ ' Calculate the camera's rotation and position offsets\r
+ frameCount = frameCount + 1\r
+ cameraRotation = (3.1412 / 2) + Sin(frameCount / 35) / 100 + Sin(frameCount / 21) / 100\r
+ rs1 = Sin(cameraRotation)\r
+ rc1 = Cos(cameraRotation)\r
+\r
+ ' Update and draw each star\r
+ For starIndex = 1 To totalStars\r
+ x = starXPositions(starIndex)\r
+ y = starYPositions(starIndex)\r
+ z = starZPositions(starIndex)\r
+\r
+ ' Project the star's 3D position onto the 2D screen\r
+ projectedX = (x / z) * 160 + 160\r
+ projectedY = (y / z) * 100 + 100\r
+ PSet (projectedX, projectedY), 0 ' Erase the previous position\r
+\r
+ ' Rotate the star's position around the camera\r
+ x5 = x * rs1 - y * rc1\r
+ y5 = x * rc1 + y * rs1\r
+\r
+ ' Update the star's position with camera movement\r
+ x = x5 + Sin(frameCount / 21) * 3\r
+ y = y5 + Sin(frameCount / 18) * 3\r
+\r
+ ' Move the star closer to the viewer and wrap around if too close\r
+ z = z - 3\r
+ If z < 10 Then\r
+ z = Rnd * 300 + 400\r
+ x = Rnd * 800 - 400\r
+ y = Rnd * 800 - 400\r
+ End If\r
+\r
+ ' Project the new position and draw with perspective-based brightness\r
+ projectedX = (x / z) * 160 + 160\r
+ projectedY = (y / z) * 100 + 100\r
+ colorCode = 3000 / z + 15\r
+ If colorCode > 31 Then colorCode = 31\r
+ PSet (projectedX, projectedY), colorCode\r
+\r
+ ' Update the star's array positions\r
+ starXPositions(starIndex) = x\r
+ starYPositions(starIndex) = y\r
+ starZPositions(starIndex) = z\r
+ Next starIndex\r
+\r
+ ' Add new stars to the galaxy if needed\r
+ If maxStars - totalStars > Rnd * 800 + 100 Then CreateGalaxy: totalStars = totalStars + 1\r
+\r
+ ' Remove the two farthest stars and replace them with new ones\r
+ For a = 1 To 2\r
+ starIndex = Int(Rnd * (totalStars - 10)) + 1\r
+ Swap starXPositions(totalStars), starXPositions(starIndex)\r
+ Swap starYPositions(totalStars), starYPositions(starIndex)\r
+ Swap starZPositions(totalStars), starZPositions(starIndex)\r
+\r
+ x = starXPositions(totalStars)\r
+ y = starYPositions(totalStars)\r
+ z = starZPositions(totalStars)\r
+ projectedX = (x / z) * 160 + 160\r
+ projectedY = (y / z) * 100 + 100\r
+ PSet (projectedX, projectedY), 0 ' Erase the star\r
+ totalStars = totalStars - 1\r
+ Next a\r
+\r
+\r
+ ' Check for user input to exit the program\r
+ If InKey$ <> "" Then System\r
+\r
+ ' sleep, to limit framerate\r
+ Sound 0, 1\r
+Loop\r
+\r
+' Subroutine to create a new galaxy of stars\r
+Sub CreateGalaxy\r
+ xForce = Rnd * 4 - 2\r
+ yForce = Rnd * 4 - 2\r
+ xPositionOffset = Rnd * 200 - 100\r
+ yPositionOffset = Rnd * 200 - 100\r
+\r
+ ' Add a new set of stars with varying positions and velocities\r
+ For starIndex = 1 To Int(Rnd * 15) + 10 Step .04\r
+ x = Sin(starIndex) * starIndex * starIndex / 10\r
+ y = Cos(starIndex) * starIndex * starIndex / 10\r
+ AddStar x + RND * starIndex * starIndex / 30 + xPositionOffset, _\r
+ y + RND * starIndex * starIndex / 30 + yPositionOffset, _\r
+ 700 + RND * starIndex * starIndex / 30 + (x * xForce) + (y * yForce)\r
+ Next starIndex\r
+\r
+ ' Play a sound when creating new stars (commented out)\r
+ ' SOUND 1000, 1\r
+End Sub\r
+\r
+' Subroutine to add a new star at the specified position\r
+Sub AddStar (xPosition As Single, yPosition As Single, zPosition As Single)\r
+ totalStars = totalStars + 1\r
+ starIndex = totalStars\r
+\r
+ starXPositions(starIndex) = xPosition\r
+ starYPositions(starIndex) = yPosition\r
+ starZPositions(starIndex) = zPosition\r
+End Sub\r
\r