Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Another type of match-3 controls
#1
I like match-3 games (most common type of mobile game genre, I think). I've posted a couple of these before, but here's a control method that I don't think I've implemented before. Requires a bit more skill than just clicking.



Code:
' match3drag.n7
' -------------

visible vTileSize = 40
visible vMapRows = 12, vMapCols = 16
visible vMap = fill([type: 0, offs: 0, pop: 0], vMapCols, vMapRows)
visible vMapOffsX, vMapOffsY
visible vPieceColors = [[255, 32, 64], [64, 255, 32], [64, 32, 255], [192, 32, 255]]
visible vPath = [], vPathType

set window "match3drag", 800, 600
set redraw off

' Map draw offset.
vMapOffsX = (width(primary) - vMapCols*vTileSize)/2
vMapOffsY = (height(primary) - vMapRows*vTileSize)/2

' Set random types for map.
randomize time()
for y = 0 to vMapRows - 1  for x = 0 to vMapCols - 1  vMap[x][y].type = rnd(4)

' Game loop.
while not keydown(KEY_ESCAPE, true)
    ' Convert mouse to map coordinates.
    tileX = floor((mousex() - vMapOffsX)/vTileSize)
    tileY = floor((mousey() - vMapOffsY)/vTileSize)
    ' Valid position?
    if tileX >= 0 and tileX < vMapCols and tileY >= 0 and tileY < vMapRows
        if mousebutton(0)
            pos = Pos(tileX, tileY)
            type = vMap[tileX][tileY].type
            ' Start new path?
            if sizeof(vPath) = 0
                vPath[0] = pos
                vPathType = type
            ' Correct type?
            elseif type = vPathType
                ' Back to old position?
                if val(vPath, pos)
                    for i = sizeof(vPath) - 1 to 0
                        if vPath[i] = pos  break
                        else  free key vPath, i
                    next
                ' Add new position?
                else
                    lastPos = vPath[sizeof(vPath) - 1]
                    lastX = PosX(lastPos)
                    lastY = PosY(lastPos)
                    if tileY = lastY and |tileX - lastX| = 1 or
                            tileX = lastX and |tileY - lastY| = 1
                        vPath[sizeof(vPath)] = pos
                    endif
                endif
            endif
        else
            ' Pop?
            if sizeof(vPath) >= 3
                for i = 0 to sizeof(vPath) - 1
                    pos = vPath[i]
                    vMap[PosX(pos)][PosY(pos)].pop = (i + 1)*4
                next
            endif
            clear vPath
        endif
    ' Clear path if mouse button is released outside game area.
    elseif sizeof(vPath) > 0 and not mousebutton(0)
        clear vPath
    endif
   
    ' Update grid.
    for y = 0 to vMapRows - 1  for x = 0 to vMapCols - 1
        ' About to pop?
        if vMap[x][y].pop > 0
            vMap[x][y].pop = vMap[x][y].pop - 1
            ' Pop?
            if vMap[x][y].pop <= 0
                ' Copy above pieces and add draw offsets to make them fall.
                yy = y
                while yy > 0
                    vMap[x][yy].type = vMap[x][yy - 1].type
                    vMap[x][yy].offs = vMap[x][yy - 1].offs + vTileSize
                    vMap[x][yy].pop = vMap[x][yy - 1].pop
                    yy = yy - 1
                wend
                ' Add new piece at top.
                vMap[x][yy].type = rnd(4)
                vMap[x][yy].offs = vMap[x][yy + 1].offs + vTileSize
                vMap[x][yy].pop = 0
            endif
        endif
        ' Move down.
        vMap[x][y].offs = max(vMap[x][y].offs - 6, 0)
    next

    ' Draw.
    set color 0, 0, 0
    cls
   
    set clip rect vMapOffsX, vMapOffsY, vMapCols*vTileSize, vMapRows*vTileSize
    for y = 0 to vMapRows - 1  for x = 0 to vMapCols - 1
        set color vPieceColors[vMap[x][y].type]
        draw rect vMapOffsX + x*vTileSize + 2, vMapOffsY + y*vTileSize + 2 - vMap[x][y].offs,
                vTileSize - 4, vTileSize - 4, true
    next
    clear clip rect
   
    if sizeof(vPath) > 0
        for i = 0 to sizeof(vPath) - 1
            x = vMapOffsX + PosX(vPath[i])*vTileSize
            y = vMapOffsY + PosY(vPath[i])*vTileSize
            set color 255, 255, 255, 128
            draw rect x, y, vTileSize, vTileSize, true
            set color 255, 255, 255
            draw rect x, y, vTileSize, vTileSize 
        next
    endif
   
    set color 255, 255, 255
    set caret width(primary)/2, 4
    center "Mark three or more adjacent blocks of the same color, by drawing"
    center "a path with your left mouse button, to make them pop!"
   
    redraw
    fwait 60
wend

' Return map coordinates as single integer.
function Pos(x, y);  return y*vMapCols + x;  endfunc
' Return x part of single integer coordinates.
function PosX(pos);  return pos%vMapCols;  endfunc
' Return y part of single integer coordinates.
function PosY(pos);  return int(pos/vMapCols);  endfunc
Reply


Messages In This Thread
Another type of match-3 controls - by Marcus - 02-12-2026, 03:26 PM
RE: Another type of match-3 controls - by oskarg - 02-12-2026, 05:54 PM
RE: Another type of match-3 controls - by kevin - 02-12-2026, 06:41 PM
RE: Another type of match-3 controls - by Marcus - 02-14-2026, 01:32 PM
RE: Another type of match-3 controls - by Marcus - 02-14-2026, 07:47 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)