Pac-Man maze - Jules Marchildon - 08-30-2025
I'm starting to work on a pac-man maze. I have a long road ahead of me with this challenge. I'm going with a technique I read up on using tiles that are setup as a grid that allows you to draw the maze dynamically. Each tile is stored in a 2D array. The maze is setup 28 across and 31 tiles down. The array elements are structures that allow you to include properties or attributes about the tile and can be used for game flow logic and drawing updates. I'm curious to know if anyone else in PB land has done any work in this area? TIA.
A picture of what I have so far... (obviously more work to be done )
RE: Pac-Man maze - Stuart McLachlan - 08-30-2025
ISTM that if you are happy for those large areas to be filled rather than empty internally you just need to store a flag for whether each square is filled or not and a flag for whether it has a "dot"
For any empty block you just need to look at four adjacent blocks to determine whether you can move there or not.
Note, you walls are one wide and your passages are two wide. That is back asswrd. 
Movement ain't gonna work.
RE: Pac-Man maze - Jules Marchildon - 08-30-2025
That's interesting, when I first did it that way, it looked the opposite to me visually. Walls too thick and tunnel to narrow. Back to the drawing board.
RE: Pac-Man maze - Kurt Kuzba - 08-30-2025
(08-30-2025, 03:28 AM)Jules Marchildon Wrote: I'm starting to work on a pac-man maze. I have a long road ahead of me with this challenge. I'm going with a technique I read up on using tiles that are setup as a grid that allows you to draw the maze dynamically. Each tile is stored in a 2D array. The maze is setup 28 across and 31 tiles down. The array elements are structures that allow you to include properties or attributes about the tile and can be used for game flow logic and drawing updates. I'm curious to know if anyone else in PB land has done any work in this area? TIA.
A picture of what I have so far... (obviously more work to be done )
I did something similar once, where I used an ascii text map.
Resolution can be whatever you like, of course.
As a simple example, this:
"__X__X__"
"_____X__"
"_____X__"
"XXXXXX__"
"__X_____"
Creation of the maze is visually simplified, and the array can be created directly from the strings.
The size of open areas and thickness of walls can be easily controlled by the number of array elements they employ.
RE: Pac-Man maze - Jules Marchildon - 08-30-2025
Thanks Kurt,
Yes, like this that created the last image.
Code: maze(0) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
maze(1) = "X XX X"
maze(2) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(3) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(4) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(5) = "X X"
maze(6) = "X XXXX XX XXXXXXXX XX XXXX X"
maze(7) = "X XXXX XX XXXXXXXX XX XXXX X"
maze(8) = "X XX XX XX X"
maze(9) = "XXXXXX XXXXX XX XXXXX XXXXXX"
maze(10) = " X XXXXX XX XXXXX X "
maze(11) = " X XX XX X "
maze(12) = " X XX XXXXXXXX XX X "
maze(13) = "XXXXXX XX X X XX XXXXXX"
maze(14) = " X X "
maze(15) = "XXXXXX XX X X XX XXXXXX"
maze(16) = " X XX XXXXXXXX XX X "
maze(17) = " X XX XX X "
maze(18) = " X XX XXXXXXXX XX X "
maze(19) = "XXXXXX XX XXXXXXXX XX XXXXXX"
maze(20) = "X XX X"
maze(21) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(22) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(23) = "X XX XX X"
maze(24) = "XXX XX XX XXXXXXXX XX XX XXX"
maze(25) = "XXX XX XX XXXXXXXX XX XX XXX"
maze(26) = "X XX XX XX X"
maze(27) = "X XXXXXXXXXX XX XXXXXXXXXX X"
maze(28) = "X XXXXXXXXXX XX XXXXXXXXXX X"
maze(29) = "X X"
maze(30) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
RE: Pac-Man maze - Kurt Kuzba - 08-31-2025
(08-30-2025, 10:18 PM)Jules Marchildon Wrote: Thanks Kurt,
Yes, like this that created the last image.
Code: maze(0) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
maze(1) = "X XX X"
maze(2) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(3) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(4) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(5) = "X X"
maze(6) = "X XXXX XX XXXXXXXX XX XXXX X"
maze(7) = "X XXXX XX XXXXXXXX XX XXXX X"
maze(8) = "X XX XX XX X"
maze(9) = "XXXXXX XXXXX XX XXXXX XXXXXX"
maze(10) = " X XXXXX XX XXXXX X "
maze(11) = " X XX XX X "
maze(12) = " X XX XXXXXXXX XX X "
maze(13) = "XXXXXX XX X X XX XXXXXX"
maze(14) = " X X "
maze(15) = "XXXXXX XX X X XX XXXXXX"
maze(16) = " X XX XXXXXXXX XX X "
maze(17) = " X XX XX X "
maze(18) = " X XX XXXXXXXX XX X "
maze(19) = "XXXXXX XX XXXXXXXX XX XXXXXX"
maze(20) = "X XX X"
maze(21) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(22) = "X XXXX XXXXX XX XXXXX XXXX X"
maze(23) = "X XX XX X"
maze(24) = "XXX XX XX XXXXXXXX XX XX XXX"
maze(25) = "XXX XX XX XXXXXXXX XX XX XXX"
maze(26) = "X XX XX XX X"
maze(27) = "X XXXXXXXXXX XX XXXXXXXXXX X"
maze(28) = "X XXXXXXXXXX XX XXXXXXXXXX X"
maze(29) = "X X"
maze(30) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
You can improve the look of it by a higher resolution to your map. But then, you have the track space issue, where moving inside the map has to be limited to specific map spaces. So, for instance, where you have X for a wall and a space for an open area, you could also have another character to designate a motion track, within the open areas. This will reduce the code required to track the movement to the space, since it can only move to a track space. Testing for walls and the like becomes a non-problem.
RE: Pac-Man maze - Stuart McLachlan - 08-31-2025
(08-31-2025, 11:36 AM)Kurt Kuzba Wrote: You can improve the look of it by a higher resolution to your map. But then, you have the track space issue, where moving inside the map has to be limited to specific map spaces. So, for instance, where you have X for a wall and a space for an open area, you could also have another character to designate a motion track, within the open areas. This will reduce the code required to track the movement to the space, since it can only move to a track space. Testing for walls and the like becomes a non-problem.
I don't get the difference between a "space" and a "track space". You should be able to move to any adjacent space.
There are only four possible directions to move. The key value will tell you which of those directions the player is trying to move. On every attempted move, just test whether the adjacent cell in that direction is a block or a space. If it is a space, then move. If it is a block, then don't move.
RE: Pac-Man maze - Jules Marchildon - 08-31-2025
As you know I always like to complicate a Ham sandwich, this is what I was thinking, maybe I'm backwards, wrong, NOT thinking. I'll be tied up for the next 2 days, tiling my shower stall at home, will check back later.
Trial, No Fill...
Code: #COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
%DEBUG_MODE = 1 '-draw red grid
TYPE Tile
IsPath AS BYTE '<-*1 if this is a path tile, 0 if wall
Connection AS BYTE '<-*4-bit connection value (top=1, right=2, bottom=4, left=8)
END TYPE
GLOBAL grid() AS Tile
GLOBAL gmaze() AS STRING
GLOBAL gtile_size AS LONG
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WINMAIN(BYVAL hInstance AS LONG, BYVAL hPrevInstance AS LONG, BYVAL lpCmdLine AS ASCIIZ PTR, BYVAL iCmdShow AS LONG) AS LONG
LOCAL i, lRow, lCol AS LONG
LOCAL value AS BYTE
DIM gmaze(0 TO 30) AS GLOBAL STRING '-31 rows
gtile_size = 24 '-tile size
DIM grid(0 TO 30, 0 TO 27) AS GLOBAL Tile '-28 wide by 31 high
'-define our Pac-Man maze layout, original 28x31, no padding
gmaze(0) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
gmaze(1) = "X XX X"
gmaze(2) = "X XXXX XXXXX XX XXXXX XXXX X"
gmaze(3) = "X XXXX XXXXX XX XXXXX XXXX X"
gmaze(4) = "X XXXX XXXXX XX XXXXX XXXX X"
gmaze(5) = "X X"
gmaze(6) = "X XXXX XX XXXXXXXX XX XXXX X"
gmaze(7) = "X XXXX XX XXXXXXXX XX XXXX X"
gmaze(8) = "X XX XX XX X"
gmaze(9) = "XXXXXX XXXXX XX XXXXX XXXXXX"
gmaze(10) = " X XXXXX XX XXXXX X "
gmaze(11) = " X XX XX X "
gmaze(12) = " X XX XXXXXXXX XX X "
gmaze(13) = "XXXXXX XX X X XX XXXXXX"
gmaze(14) = " X X "
gmaze(15) = "XXXXXX XX X X XX XXXXXX"
gmaze(16) = " X XX XXXXXXXX XX X "
gmaze(17) = " X XX XX X "
gmaze(18) = " X XX XXXXXXXX XX X "
gmaze(19) = "XXXXXX XX XXXXXXXX XX XXXXXX"
gmaze(20) = "X XX X"
gmaze(21) = "X XXXX XXXXX XX XXXXX XXXX X"
gmaze(22) = "X XXXX XXXXX XX XXXXX XXXX X"
gmaze(23) = "X XX XX X"
gmaze(24) = "XXX XX XX XXXXXXXX XX XX XXX"
gmaze(25) = "XXX XX XX XXXXXXXX XX XX XXX"
gmaze(26) = "X XX XX XX X"
gmaze(27) = "X XXXXXXXXXX XX XXXXXXXXXX X"
gmaze(28) = "X XXXXXXXXXX XX XXXXXXXXXX X"
gmaze(29) = "X X"
gmaze(30) = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
'-prepare the connection values for our path tiles
FOR lRow = 0 TO 30
FOR lCol = 0 TO 27
IF MID$(gmaze(lRow), lCol + 1, 1) = " " THEN
grid(lRow, lCol).IsPath = 1
value = 0
IF lRow > 0 AND MID$(gmaze(lRow - 1), lCol + 1, 1) = " " THEN value = value OR 1 '-*Top
IF lCol < 27 AND MID$(gmaze(lRow), lCol + 2, 1) = " " THEN value = value OR 2 '-*Right
IF lRow < 30 AND MID$(gmaze(lRow + 1), lCol + 1, 1) = " " THEN value = value OR 4 '-*Bottom
IF lCol > 0 AND MID$(gmaze(lRow), lCol, 1) = " " THEN value = value OR 8 '-*Left
grid(lRow, lCol).Connection = value
ELSE
grid(lRow, lCol).IsPath = 0
grid(lRow, lCol).Connection = 0
END IF
NEXT lCol
NEXT lRow
'-window setup
LOCAL wce AS WNDCLASSEX
LOCAL szAppName AS ASCIIZ * 80
szAppName = "GAMEBOARD32"
wce.cbSize = SIZEOF(wce)
wce.style = %CS_HREDRAW OR %CS_VREDRAW
wce.lpfnWndProc = CODEPTR(WndProc)
wce.hInstance = hInstance
wce.hIcon = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
wce.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wce.hbrBackground = GetStockObject(%WHITE_BRUSH)
wce.lpszClassName = VARPTR(szAppName)
wce.hIconSm = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
RegisterClassEx wce
LOCAL hWnd AS LONG
hWnd = CreateWindowEx(0, szAppName, "Pac-Man Layout Trials:", %WS_OVERLAPPEDWINDOW, _
%CW_USEDEFAULT, %CW_USEDEFAULT, _
28 * gtile_size + GetSystemMetrics(%SM_CXFRAME) * 2, _
31 * gtile_size + GetSystemMetrics(%SM_CYFRAME) + GetSystemMetrics(%SM_CYCAPTION), _
%NULL, %NULL, hInstance, BYVAL %NULL)
ShowWindow hWnd, iCmdShow
UpdateWindow hWnd
LOCAL uMsg AS tagMSG
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
FUNCTION = uMsg.wParam
END FUNCTION
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WndProc(BYVAL hWnd AS LONG, BYVAL uMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
SELECT CASE uMsg
CASE %WM_PAINT
LOCAL ps AS PAINTSTRUCT
LOCAL hDC AS LONG
hDC = BeginPaint(hWnd, ps)
LOCAL lRow, lCol AS LONG
LOCAL hPen, hDebugPen AS LONG
LOCAL x, y AS LONG
'-create colored pen for maze outlines, no fill while testing
LOCAL lb AS LOGBRUSH
lb.lbStyle = %BS_SOLID
lb.lbColor = RGB(0, 0, 0)
hPen = ExtCreatePen(%PS_GEOMETRIC OR %PS_ENDCAP_ROUND OR %PS_JOIN_ROUND, 2, lb, 0, BYVAL %NULL)
SelectObject hDC, hPen
#IF %DEBUG_MODE
'-ceate hatched red pen for debug outlines
LOCAL lbDebug AS LOGBRUSH
lbDebug.lbStyle = %BS_HATCHED
lbDebug.lbColor = RGB(255, 0, 0)
lbDebug.lbHatch = %HS_DIAGCROSS
hDebugPen = ExtCreatePen(%PS_GEOMETRIC, 1, lbDebug, 0, BYVAL %NULL)
SelectObject hDC, hDebugPen
'-draw debug outlines for all tiles
FOR lRow = 0 TO 30
FOR lCol = 0 TO 27
x = lCol * gtile_size
y = lRow * gtile_size
MoveToEx hDC, x, y, BYVAL %NULL
LineTo hDC, x + gtile_size, y
LineTo hDC, x + gtile_size, y + gtile_size
LineTo hDC, x, y + gtile_size
LineTo hDC, x, y
NEXT lCol
NEXT lRow
DeleteObject hDebugPen
SelectObject hDC, hPen '-switch back to gmaze pen
#ENDIF
'-draw outer edges of wall structures
FOR lRow = 0 TO 30
FOR lCol = 0 TO 27
IF MID$(gmaze(lRow), lCol + 1, 1) = "X" THEN
x = lCol * gtile_size
y = lRow * gtile_size
'-draw top edge if no wall above or at top edge
IF lRow = 0 OR MID$(gmaze(lRow - 1), lCol + 1, 1) = " " THEN
MoveToEx hDC, x, y, BYVAL %NULL
LineTo hDC, x + gtile_size, y
END IF
'-draw right edge if no wall to right or at right edge
IF lCol = 27 OR MID$(gmaze(lRow), lCol + 2, 1) = " " THEN
MoveToEx hDC, x + gtile_size, y, BYVAL %NULL
LineTo hDC, x + gtile_size, y + gtile_size
END IF
'-draw bottom edge if no wall below or at bottom edge
IF lRow = 30 OR MID$(gmaze(lRow + 1), lCol + 1, 1) = " " THEN
MoveToEx hDC, x + gtile_size, y + gtile_size, BYVAL %NULL
LineTo hDC, x, y + gtile_size
END IF
'-draw left edge if no wall to left or at left edge
IF lCol = 0 OR MID$(gmaze(lRow), lCol, 1) = " " THEN
MoveToEx hDC, x, y + gtile_size, BYVAL %NULL
LineTo hDC, x, y
END IF
END IF
NEXT lCol
NEXT lRow
'-clean up
DeleteObject hPen
EndPaint hWnd, ps
FUNCTION = 0
EXIT FUNCTION
CASE %WM_DESTROY
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, uMsg, wParam, lParam)
END FUNCTION
RE: Pac-Man maze - Kurt Kuzba - 09-01-2025
(08-31-2025, 11:46 AM)Stuart McLachlan Wrote: I don't get the difference between a "space" and a "track space". You should be able to move to any adjacent space.
There are only four possible directions to move. The key value will tell you which of those directions the player is trying to move. On every attempted move, just test whether the adjacent cell in that direction is a block or a space. If it is a space, then move. If it is a block, then don't move.
If you increase the resolution of the map, to use smaller tiles, then your track space will be surrounded by open spaces. Movement into those spaces will cause a collision with a wall. Since the Pacman model does not allow real 4 directional movement, and is constrained by a system of walls, you would need to test for collisions with walls.
Assuming you increased the resolution of your map, of course. One advantage is that turning around in the space available happens more quickly, since the movement to the next track space is less than the movement to the next game space. Just more complications you can add, if you want to.
(08-31-2025, 11:46 AM)Stuart McLachlan Wrote: I don't get the difference between a "space" and a "track space". You should be able to move to any adjacent space.
There are only four possible directions to move. The key value will tell you which of those directions the player is trying to move. On every attempted move, just test whether the adjacent cell in that direction is a block or a space. If it is a space, then move. If it is a block, then don't move.
(08-31-2025, 11:46 AM)Stuart McLachlan Wrote: I don't get the difference between a "space" and a "track space". You should be able to move to any adjacent space.
There are only four possible directions to move. The key value will tell you which of those directions the player is trying to move. On every attempted move, just test whether the adjacent cell in that direction is a block or a space. If it is a space, then move. If it is a block, then don't move.
RE: Pac-Man maze - Jules Marchildon - 09-01-2025
Found this image, I will continue to work on the drawing details in a few days. I want stick to dynamically drawing the blue lines instead of using a map overlay or image tiles.
|