For this I would opt for a grid x,y co-ordinates system, I started coding a simple example and got a little bit carried away lol.
http://parttimecode.16mb.com/Grid/Grid_Movement.html
EDIT: cleaned up my code (made more modular) and added keyboard movement, fixed an error with out-of-bounds array index if trying to move outside grid
// Project: Grid Movement
// Created: 2017-07-25
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Grid Movement" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
#Constant KEY_LEFT GetRawKeyPressed(37)
#Constant KEY_UP GetRawKeyPressed(38)
#Constant KEY_RIGHT GetRawKeyPressed(39)
#Constant KEY_DOWN GetRawKeyPressed(40)
#Constant KEY_W GetRawKeyPressed(87)
#Constant KEY_S GetRawKeyPressed(83)
#Constant KEY_A GetRawKeyPressed(65)
#Constant KEY_D GetRawKeyPressed(68)
#Constant GRID_SIZE 32 // the grid size
#Constant GRID_WIDTH 12 // grid cells x
#Constant GRID_HEIGHT 12 // grid cells y
#Constant GRID_OFFSET_X 200 // grid x offset
#Constant GRID_OFFSET_Y 100 // grid y offset
#Constant GRID_MOVE_MAX 1 // max move cells
#Constant GRID_MOVE_DIAG 0 // move diag (0 = false, 1 = true)
Global player
Global pickups
Global max_cell_width
Global max_cell_height
// cell array for walls, pickups ETC
Type tCell
name as string
sprite_id
EndType
Global cell as tCell[GRID_WIDTH,GRID_HEIGHT]
Global cell_index_x
Global cell_index_y
// cell area size
max_cell_width=GRID_OFFSET_X+(GRID_WIDTH*GRID_SIZE)
max_cell_height=GRID_OFFSET_Y+(GRID_HEIGHT*GRID_SIZE)
// create objects
for celly=GRID_OFFSET_Y to max_cell_height step GRID_SIZE
for cellx=GRID_OFFSET_X to max_cell_width step GRID_SIZE
center_x=GRID_OFFSET_X+GRID_SIZE*GRID_WIDTH/2
center_y=GRID_OFFSET_Y+GRID_SIZE*GRID_HEIGHT/2
// create player on center cell
if cellx=center_x and celly=center_y
//create player
player = CreateSprite(0)
SetSpriteSize(player,GRID_SIZE, GRID_SIZE)
SetSpriteColor(player, 255, 0,0, 255)
SetSpritePosition(player, cellx, celly)
else
if Random(1, 5)=1
wall=CreateSprite(0)
SetSpriteSize(wall,GRID_SIZE, GRID_SIZE)
SetSpriteColor(wall, 0, 255 ,0, 255)
SetSpritePosition(wall, cellx, celly)
cell[cell_index_x, cell_index_y].name="wall"
cell[cell_index_x, cell_index_y].sprite_id=wall
elseif Random(1, 10)=1
pickup=CreateSprite(0)
SetSpriteSize(pickup,GRID_SIZE, GRID_SIZE)
SetSpriteColor(pickup, 0, 0 ,255, 255)
SetSpritePosition(pickup, cellx, celly)
cell[cell_index_x, cell_index_y].name="pickup"
cell[cell_index_x, cell_index_y].sprite_id=pickup
endif
endif
inc cell_index_x, 1
next
cell_index_x=0
inc cell_index_y, 1
next
do
DrawGrid()
//TODO: get active player sprite
// get player co-ords
player_x = (GetSpriteX(player)-GRID_OFFSET_X)/GRID_SIZE
player_y = (GetSpriteY(player)-GRID_OFFSET_Y)/GRID_SIZE
// get mouse co-ords
mouse_x=(GetPointerX()-GRID_OFFSET_X-(GRID_SIZE/2))/GRID_SIZE
mouse_y=(GetPointerY()-GRID_OFFSET_Y-(GRID_SIZE/2))/GRID_SIZE
if KEY_LEFT or KEY_A
ProcessMovement(player, player_x-1, player_y, player_x, player_y)
endif
if KEY_RIGHT or KEY_D
ProcessMovement(player, player_x+1, player_y, player_x, player_y)
endif
if KEY_UP or KEY_W
ProcessMovement(player, player_x, player_y-1, player_x, player_y)
endif
if KEY_DOWN or KEY_S
ProcessMovement(player, player_x, player_y+1, player_x, player_y)
endif
// mouse click movement
if GetPointerPressed()
ProcessMovement(player, mouse_x, mouse_y, player_x, player_y)
endif
Sync()
loop
Function Clamp(value, min, max)
if value < min
value=min
elseif value>max
value=max
endif
EndFunction value
Function DrawGrid()
// draw the grid
for celly=GRID_OFFSET_Y to max_cell_height step GRID_SIZE
for cellx=GRID_OFFSET_X to max_cell_width step GRID_SIZE
c_white=MakeColor(255,255,255)
DrawBox(cellx, celly, cellx+GRID_SIZE, celly+GRID_SIZE, c_white, c_white, c_white, c_white, 0)
next
next
EndFunction
Function MovePlayerSprite(sprite, new_x, new_y)
// is there a wall in the target cell
if not cell[new_x, new_y].name="wall"
// move sprite
new_player_x=GRID_OFFSET_X+(GRID_SIZE*new_x)
new_player_y=GRID_OFFSET_Y+(GRID_SIZE*new_y)
SetSpritePosition(sprite, new_player_x, new_player_y)
// get pickups
if cell[new_x, new_y].name="pickup"
cell[new_x, new_y].name=""
DeleteSprite(cell[new_x, new_y].sprite_id)
inc pickups,1
endif
endif
EndFunction
Function ProcessMovement(sprite_id, move_x, move_y, player_x, player_y)
// distance to move
dist_x=0
dist_y=0
// get x distance
if move_x>player_x
dist_x=move_x-player_x
elseif move_x<player_x
dist_x=player_x-move_x
endif
// get y distance
if move_y>player_y
dist_y=move_y-player_y
elseif move_y<player_y
dist_y=player_y-move_y
endif
move_x=Clamp(move_x, 0, GRID_WIDTH)
move_y=Clamp(move_y, 0, GRID_HEIGHT)
// can we move diag
if GRID_MOVE_DIAG
// are we within distance
if dist_x<=GRID_MOVE_MAX and dist_y<=GRID_MOVE_MAX
MovePlayerSprite(sprite_id, move_x, move_y)
endif
else
// is this diagional movement
if dist_x>0 and dist_y=0 or dist_x=0 and dist_y>0
// are we within distance
if dist_x<=GRID_MOVE_MAX and dist_y<=GRID_MOVE_MAX
MovePlayerSprite(sprite_id, move_x, move_y)
endif
endif
endif
EndFunction