02-02-2025, 11:36 PM
Thank you Deciheximal!! Your game helped me improve mine greatly. Now the keys work every time as soon as you press them. Also, I took up what B+ said about natural flight, so I changed that too, and it's actually a much more fun game to play.
What do you guys think?
What do you guys think?
Code: (Select All)
'Asteroids Clone by, SierraKen
'February 2, 2025
'Thank you QB64pe Forum for your inspiration!
'Thank you also ChatGPT for a lot of the math.
'This game is not intended to replace any other game already in existence.
'It is a labor of love and given out for free.
'Update: Fixed speed of ship and better response to keys. Thank you Deciheximal for your game code!
_Title "Asteroids Clone - by SierraKen"
Screen _NewImage(800, 600, 32)
Randomize Timer
Dim oldx(100), oldy(100)
Dim llx(500), lly(500)
Dim lx(500), ly(500), ldir(500)
Dim x1 As Single, y1 As Single
Const numPoints = 30
Dim x2(100, 40), y2(100, 40)
Dim xRot(100, 40), yRot(100, 40)
Dim cx2(200), cy2(200), angle2(200)
Dim dx(100), dy(100)
Dim nox(500)
start:
numAsteroids = 8
radius2 = 45 'Asteroids
level = 1
score = 0
health = 50
healthp = 100
rot = -90
Cls
_AutoDisplay
Locate 3, 25: Print "A s t e r o i d s C l o n e"
Locate 5, 25: Print "By SierraKen"
Locate 10, 25: Print "Move your ship around with the arrow keys."
Locate 11, 25: Print "Turn your ship with the left and right arrow keys."
Locate 12, 25: Print "Go forward with the up arrow key."
Locate 12, 25: Print "Press Space Bar to fire at asteroids."
Locate 13, 25: Print "To pause and un-pause, press Esc."
Locate 14, 25: Print "Press Q anytime to quit."
Locate 20, 25: Input "Press Enter to Begin.", a$
start2:
Cls
_Title "Score: " + Str$(score) + " Health: " + Str$(healthp) + "% Level: " + Str$(level)
numAsteroids = numAsteroids + 2
If numAsteroids > 40 Then numAsteroids = 40
num = numAsteroids
rock = 0
hits = 0
speed2 = 0
laser = 0
ll = 0
numpoints2 = Int(Rnd * numPoints) + 10
For ll3 = 1 To 200
lx(ll3) = 0
ly(ll3) = 0
ldir(ll3) = 0
Next ll3
sx = 400
sy = 300
oldx = 400
oldy = 300
det = 0
r1 = 3 'bullets
r3 = 25 'Your ship
loops = 0
Play "MB"
' Initialize asteroids
For a = 0 To num - 1
more:
cx2(a) = Int(Rnd * 680) + 55 ' Random start X
cy2(a) = Int(Rnd * 480) + 55 ' Random start Y
If cx2(a) > 250 And cx2(a) < 550 And cy2(a) > 150 And cy2(a) < 450 Then GoTo more:
angle2(a) = Rnd * 360 ' Random starting rotation
dx(a) = (Rnd - 0.5) * 2 ' Random speed X (-1 to 1)
dy(a) = (Rnd - 0.5) * 2 ' Random speed Y (-1 to 1)
' Generate random asteroid shape
For i = 0 To numpoints2
ang = i * (360 / numpoints2)
rOffset = radius2 + Int(Rnd * 15 - 7) ' Vary radius randomly
x2(a, i) = Cos(ang * _Pi / 180) * rOffset
y2(a, i) = Sin(ang * _Pi / 180) * rOffset
Next
rock = rock + 1
Next
Do
_Limit 100
If _KeyDown(32) Then
laser = 1
ll = ll + 1
If ll > 500 Then ll = 1
lx(ll) = x1
ly(ll) = y1
ldir(ll) = angle
End If
If _KeyDown(52) Or _KeyDown(19200) Then dir1 = 1 ' Left Arrow (rotate counterclockwise)
If _KeyDown(54) Or _KeyDown(19712) Then dir1 = 2 ' Right Arrow (rotate clockwise)
If _KeyDown(56) Or _KeyDown(18432) Then dir2 = 3 ' Up Arrow (thrust forward)
If _KeyDown(50) Or _KeyDown(20480) Then dir2 = 4 ' Down Arrow (thrust backward)
If dir1 = 1 Then
angle = angle - 1
If right = 1 Then
right = 0
dir1 = 0
GoTo nex2
End If
left = 1
right = 0
End If
If dir1 = 2 Then
angle = angle + 1
If left = 1 Then
left = 0
dir1 = 0
GoTo nex2
End If
right = 1
left = 0
End If
If dir2 = 3 Then
speed2 = speed2 + .01
If speed2 > 2 Then speed2 = 2
sx = sx + speed2 * Cos(angle * _Pi / 180)
sy = sy + speed2 * Sin(angle * _Pi / 180)
End If
If dir2 = 4 Then
speed2 = speed2 - .01
If speed2 < 0 Then speed2 = 0
sx = sx + speed2 * Cos(angle * _Pi / 180)
sy = sy + speed2 * Sin(angle * _Pi / 180)
End If
nex2:
If sx > 800 Then sx = 0
If sx < 0 Then sx = 800
If sy > 600 Then sy = 0
If sy < 0 Then sy = 600
If _KeyHit = 27 Then
Do
If _KeyHit = 27 Then GoTo go
Loop
End If
go:
k$ = ""
If _KeyDown(81) Or _KeyDown(113) Then End
' Update and draw each asteroid
For a = 0 To num - 1
If nox(a) = 1 Then GoTo skip
angle2(a) = angle2(a) + 1 ' Rotate
If angle2(a) >= 360 Then angle2(a) = 0
' Rotate asteroid points
rad = angle2(a) * _Pi / 180
For i = 0 To numpoints2
xRot(a, i) = cx2(a) + (x2(a, i) * Cos(rad) - y2(a, i) * Sin(rad))
yRot(a, i) = cy2(a) + (x2(a, i) * Sin(rad) + y2(a, i) * Cos(rad))
Next
' Draw asteroid
For i = 0 To numpoints2 - 1
j = (i + 1) Mod numpoints2
Line (xRot(a, i), yRot(a, i))-(xRot(a, j), yRot(a, j)), _RGB32(255, 255, 255)
Next
' Move asteroid
cx2(a) = cx2(a) + dx(a)
cy2(a) = cy2(a) + dy(a)
' Wrap around screen edges
If cx2(a) < 0 Then cx2(a) = 800
If cx2(a) > 800 Then cx2(a) = 0
If cy2(a) < 0 Then cy2(a) = 600
If cy2(a) > 600 Then cy2(a) = 0
Next
skip:
If laser = 1 Then
For lz = 0 To ll - 1 Step 10
lx2 = Cos(ldir(lz) * _Pi / 180) * 10
ly2 = Sin(ldir(lz) * _Pi / 180) * 10
lx(lz) = lx2 + lx(lz)
ly(lz) = ly2 + ly(lz)
If lx(lz) > 850 Then lx(lz) = 850
If lx(lz) < -50 Then lx(lz) = -50
If ly(lz) > 650 Then ly(lz) = 650
If ly(lz) < -50 Then ly(lz) = -50
fillCircle lx(lz), ly(lz), r1, _RGB32(255, 0, 5)
For chk = 0 To num - 1
distance = Sqr((lx(lz) - cx2(chk)) ^ 2 + (ly(lz) - cy2(chk)) ^ 2)
If distance <= r1 + radius2 Then
DetectCollision = -1 ' True (collision detected)
Else
DetectCollision = 0 ' False (no collision)
End If
If DetectCollision = -1 And nox(chk) <> 1 Then
For explosion = 1 To 50
Circle (lx(lz), ly(lz)), explosion, _RGB32(255, 0, 0)
llx(explosion) = lx(lz)
lly(explosion) = ly(lz)
Next explosion
'SOUND frequency!, duration![, volume!][, panPosition!][, waveform&][, waveformParameters!][, voice&]]
Sound 800, .4, , , 5
Sound 200, .75, , , 6
Sound 100, .75, , , 7
nox(rock) = 1
rock = rock - 1
num = num - 1
cx2(chk) = -500: cy2(chk) = 1200
lx(lz) = -150: ly(lz) = -150: ldir(lz) = 0
score = score + 10
_Title "Score: " + Str$(score) + " Health: " + Str$(healthp) + "% Level: " + Str$(level)
hits = hits + 1
laser = 0
End If
Next chk
'Detect Level Change
If hits > numAsteroids - 1 Then
Cls
level = level + 1
For n = 1 To 200
nox(n) = 0
Next n
For n = 0 To 100
cx2(n) = -400: cy2(n) = -400
dx(n) = 0: dy(n) = 0
angle2(n) = 0
Next n
GoTo start2
End If
Next lz
End If
'Draw ship,
DrawTriangle sx, sy, 20, angle, x1, y1
For chk = 0 To num - 1
distance = Sqr((sx - cx2(chk)) ^ 2 + (sy - cy2(chk)) ^ 2)
If distance <= r3 + radius2 Then
DetectCollision = -1 ' True (collision detected)
Else
DetectCollision = 0 ' False (no collision)
End If
If DetectCollision = -1 And nox(chk) <> 1 Then
det = 1
health = health - .2
healthp = Int((health / 50) * 100)
_Title "Score: " + Str$(score) + " Health: " + Str$(healthp) + "% Level: " + Str$(level)
If health < .01 Then
health = 0
healthp = 0
For explosion = 1 To 200
Circle (sx, sy + 25), explosion, _RGB32(255, 0, 0)
Next explosion
For nn = 1 To 200
nox(nn) = 0
Next nn
Sound 500, 4, , , 8
Sound 500, 8, , , 5
Sound 100, 4, , , 7
Locate 20, 30: Print "G A M E O V E R"
Locate 25, 30: Input "Again (Y/N)"; ag$
ag2$ = LTrim$(RTrim$(ag$))
If Left$(ag2$, 1) = "y" Or Left$(ag2$, 1) = "Y" Then GoTo start
End
End If
End If
Next chk
skip3:
If det > 0 Then
det = det + 1
Paint (sx, sy), _RGB32(255, 0, 0), _RGB32(255, 255, 255)
If det > 200 Then det = 0
End If
If loops < 1000 Then
loops = loops + 1
End If
_Display
Cls
Loop
'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
Sub DrawTriangle (cx As Integer, cy As Integer, size As Integer, angle As Single, x1, y1)
Dim x2 As Single, y2 As Single
Dim x3 As Single, y3 As Single
Dim a1 As Single, a2 As Single, a3 As Single
' Define angles of triangle vertices
a1 = angle
a2 = angle + 120
a3 = angle + 240
' Convert polar to Cartesian coordinates
x1 = cx + size * Cos(a1 * _Pi / 180)
y1 = cy + size * Sin(a1 * _Pi / 180)
x2 = cx + size * Cos(a2 * _Pi / 180)
y2 = cy + size * Sin(a2 * _Pi / 180)
x3 = cx + size * Cos(a3 * _Pi / 180)
y3 = cy + size * Sin(a3 * _Pi / 180)
' Draw triangle
Line (x1, y1)-(x2, y2), _RGB32(255, 255, 255)
Line (x2, y2)-(x3, y3), _RGB32(255, 255, 255)
Line (x3, y3)-(x1, y1), _RGB32(255, 255, 255)
'Draw Gun
gx = x1 + Cos(angle * _Pi / 180) * 5
gy = y1 + Sin(angle * _Pi / 180) * 5
Line (x1, y1)-(gx, gy), _RGB32(255, 255, 255)
End Sub

