Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Qix line monster
#1
Anyone remember the 1980's arcade game (and later home computer / console game) Qix ?

I was thinking about how to re-create the "line monster" (the Qix) from this game.  Basically it is an array of lines (ie:  (x1,y1) and (x2,y2) coordinates).  A line is drawn, then the color is dimmed a little, and the next line is drawn.  This produces a fade out effect.  The coordinates of the first line are changed each time the monster moves.  Each remaining line is a copy of the one before it in the array.  The code would be something like this:

for q = last_line to 2 step -1
    line(q) = line(q-1)
next q
update_coords line(1)

In the 1980's game, the array contained only a handful of lines, maybe a dozen or so at most.  This was likely done because of hardware limitations (both CPU speeds, and screen resolution).  Today, with our high-res screens and faster CPUs, we can make the array much longer...

Below is my first attempt at doing this.  It is not the most elegant code, but it works.  The array is 135 lines long (const cnqlen, ie: Qix Length).  It doesn't look exactly like the arcade.  It sort of reminds me of the old "Mystify" screen saver for Windows...  The line will change colors every few seconds, or you can press 1-7 to change colors.

Code: (Select All)

'' Qix line experiment 1 (first attempt at reproducing the "line monster" from the 1980's game Qix)
'' by Abazek    2025-Jan-19
''
'' Future plans:
'' 1. Optimize the code (there are parts of this I could do differently/better)
'' 2. Greater variety of movement (perhaps RND, or SIN and COS, so cx/cy can be more than just 1, 0, or -1)
'' 3. Qix size limits (ie: if qixA and qixB get too far apart, change cx/cy to bring them closer together)

Const cnqlen = 135
Const cnfade = 2
Const cnSPD = 0.05
Const cnResX = 1280
Const cnResY = 960
Const cnMinChg = 25
Const cnMaxChg = 100
Const defx1 = 620
Const defy1 = 460
Const defx2 = 660
Const defy2 = 500

Type coord
    x As Integer
    y As Integer
    c As Integer
End Type

Dim qixA(cnqlen) As coord
Dim qixB(cnqlen) As coord
Dim scn&, pixcolr&
Dim a$, qq, d1, d2, colr, fw, flag, cl, clrchg, whenclr
Dim showc
Dim Shared cx, cy, chgdirA, chgdirB, whenChgA, whenChgB

Randomize Timer
scn& = _NewImage(cnResX, cnResY, 32)
Screen scn&
Cls 0, _RGB(0, 0, 0)
_Title "Qix Experiment 1"

For qq = 1 To cnqlen
    qixA(qq).x = defx1
    qixA(qq).y = defy1
    qixA(qq).c = 7
    qixB(qq).x = defx2
    qixB(qq).y = defy2
    qixB(qq).c = 7
Next qq
GoSub changedirA
GoSub changedirB

chgdirA = 0
chgdirB = 0
clrchg = 0
whenclr = cnMaxChg
showc = 0
flag = 0
While flag = 0
    GoSub MoveQix
    If showc = 1 Then GoSub ShowCoords
    GoSub DrawQix
    Color _RGB32(128, 128, 128)
    Locate 1, 1
    Print "ESC or SPACE to exit.  S to show coordintates.  D to hide coordintates.  1-7 manually change color."
    ''GoSub framewait
    _Delay cnSPD
    ''GoSub WaitKey
    a$ = InKey$
    If a$ = Chr$(27) Then flag = 1
    If a$ = Chr$(32) Then flag = 1
    If a$ = "S" Or a$ = "s" Then showc = 1: Cls
    If a$ = "D" Or a$ = "d" Then showc = 0: Cls
    If a$ = "1" Then cl = 1: GoSub ManualClr
    If a$ = "2" Then cl = 2: GoSub ManualClr
    If a$ = "3" Then cl = 3: GoSub ManualClr
    If a$ = "4" Then cl = 4: GoSub ManualClr
    If a$ = "5" Then cl = 5: GoSub ManualClr
    If a$ = "6" Then cl = 6: GoSub ManualClr
    If a$ = "7" Then cl = 7: GoSub ManualClr
Wend
End

WaitKey:
a$ = InKey$
If a$ = "" Then GoTo WaitKey
If a$ = Chr$(27) Then flag = 1
Return

framewait:
fw = Timer
While (Abs(Timer - fw) < cnSPD)
Wend
Return

ShowCoords:
For qq = 1 To cnqlen
    If qq < 51 Then
        Locate (qq + 1), 1
    ElseIf qq < 101 Then
        Locate (qq - 49), 50
    ElseIf qq < 151 Then
        Locate (qq - 99), 100
    Else
        Locate 51, 100
    End If
    Color _RGB32(128, 128, 128)
    Print "Coords "; qq; " = ("; qixA(qq).x; ","; qixA(qq).y; ") - ("; qixB(qq).x; ","; qixB(qq).y; ")"
Next qq
Locate 52, 1
Print "Timer = "; Timer; "  Delay="; cnSPD; "  ChgdirA="; chgdirA; "/"; whenChgA; "  ChgdirB="; chgdirB; "/"; whenChgB;
colr = 128
GoSub setColor
Color pixcolr&
Print "  Color "; clrchg; "/"; whenclr; "  "
Return

DrawQix:
colr = 1
For qq = cnqlen To 1 Step -1
    cl = qixA(qq).c
    GoSub setColor
    Color pixcolr&
    Line (qixA(qq).x, qixA(qq).y)-(qixB(qq).x, qixB(qq).y), pixcolr&
    colr = colr + cnfade
    If colr > 255 Then colr = 255
Next qq
Color _RGB32(1, 1, 1)
Return

MoveQix:
For qq = cnqlen To 2 Step -1
    qixA(qq).x = qixA(qq - 1).x
    qixA(qq).y = qixA(qq - 1).y
    qixA(qq).c = qixA(qq - 1).c
    qixB(qq).x = qixB(qq - 1).x
    qixB(qq).y = qixB(qq - 1).y
    qixB(qq).c = qixB(qq - 1).c
Next qq
qq = 1
chgdirA = chgdirA + 1
chgdirB = chgdirB + 1
clrchg = clrchg + 1
If chgdirA > whenChgA Then
    GoSub changedirA
End If
If chgdirB > whenChgB Then
    GoSub changedirB
End If
If clrchg > whenclr Then
    GoSub changeClr
    qixA(qq).c = cl
    qixB(qq).c = cl
End If
SetMoveDir d1
cx = cx * 2
cy = cy * 2
qixA(qq).x = qixA(qq).x + cx
qixA(qq).y = qixA(qq).y + cy
If qixA(qq).x < 1 Then qixA(qq).x = 1: GoSub changedirA
If qixA(qq).x > cnResX Then qixA(qq).x = cnResX: GoSub changedirA
If qixA(qq).y < 1 Then qixA(qq).y = 1: GoSub changedirA
If qixA(qq).y > cnResY Then qixA(qq).y = cnResY: GoSub changedirA
SetMoveDir d2
cx = cx * 2
cy = cy * 2
qixB(qq).x = qixB(qq).x + cx
qixB(qq).y = qixB(qq).y + cy
If qixB(qq).x < 1 Then qixB(qq).x = 1: GoSub changedirB
If qixB(qq).x > cnResX Then qixB(qq).x = cnResX: GoSub changedirB
If qixB(qq).y < 1 Then qixB(qq).y = 1: GoSub changedirB
If qixB(qq).y > cnResY Then qixB(qq).y = cnResY: GoSub changedirB
Return

changedirA:
d1 = Int(Rnd * 8) + 1
cl = cnMaxChg - cnMinChg
whenChgA = Int(Rnd * cl) + cnMinChg
chgdirA = 0
Return

changedirB:
d2 = Int(Rnd * 8) + 1
cl = cnMaxChg - cnMinChg
whenChgB = Int(Rnd * cl) + cnMinChg
chgdirB = 0
Return

changeClr:
cl = Int(Rnd * 7) + 1
clrchg = 0
Return

ManualClr:
qixA(1).c = cl
qixB(1).c = cl
clrchg = 0
Return

setColor:
Select Case cl
    Case 1
        pixcolr& = _RGB32(colr, 0, 0)
    Case 2
        pixcolr& = _RGB32(0, colr, 0)
    Case 3
        pixcolr& = _RGB32(colr, colr, 0)
    Case 4
        pixcolr& = _RGB32(0, 0, colr)
    Case 5
        pixcolr& = _RGB32(colr, 0, colr)
    Case 6
        pixcolr& = _RGB32(0, colr, colr)
    Case Else
        pixcolr& = _RGB32(colr, colr, colr)
End Select
Return

Sub SetMoveDir (dir)
    Select Case dir
        Case 1
            cx = 1: cy = 0
        Case 2
            cx = 0: cy = 1
        Case 3
            cx = -1: cy = 0
        Case 4
            cx = 0: cy = -1
        Case 5
            cx = 1: cy = -1
        Case 6
            cx = -1: cy = 1
        Case 7
            cx = -1: cy = -1
        Case Else
            cx = 1: cy = 1
    End Select
End Sub
Reply




Users browsing this thread: Abazek, 1 Guest(s)