you can use modulus to check for odd/even and apply an additional offset of 1/2 tile to the even number objects to maintain the centering.
if the modulus 2 of the boxes is 0 it is even, if it is 1 it is odd.
this gives you 1 grid square worth of space to move the mouse within centered on the object center, equal to the 1 grid square space at the center of an odd number object.
to handle rectangular objects, you will need to check both the x tile count and the y tile count to determine which/both need to get an offset
if boxX mod 2 = 0
`it's even
gx = (((mousex() + GWIDTH/2) / GWIDTH) - boxX/2)
else
`it's odd
gx = (mousex() / GWIDTH) - boxX/2
endif
if boxY mod 2 = 0
`it's even
gy = (((mousey() + GHEIGHT/2) / GHEIGHT) - boxY/2)
else
`it's odd
gy = (mousey() / GHEIGHT) - boxY/2
endif
I've added a drawCenter function which for me makes the centering feel more visually natural, since the mouse can move around in a grid squares worth of space.
Rem Project: Dark Basic Pro Project
Rem Created: Saturday, February 09, 2013
Rem ***** Main Source File *****
set display mode 1024, 768, 32
REM Tile size for the grid
#CONSTANT GWIDTH = 64
#CONSTANT GHEIGHT = 64
REM Maximum grid numbers
MaxGridX = screen width()/GWIDTH
MaxGridY = screen height()/GHEIGHT
REM define an array with a size equal to the number
REM of grid tiles on screen.
dim grid(MaxGridX, MaxGridY)
REM Size of the box (3x3)
boxX = 8
boxY = 5
sync on
DO
cls
if boxX mod 2 = 0
`it's even
gx = (((mousex() + GWIDTH/2) / GWIDTH) - boxX/2)
cx# = ((mousex() + GWIDTH/2) / GWIDTH) - 0.5
else
`it's odd
gx = (mousex() / GWIDTH) - boxX/2
cx# = mousex() / GWIDTH
endif
if boxY mod 2 = 0
`it's even
gy = (((mousey() + GHEIGHT/2) / GHEIGHT) - boxY/2)
cy# = ((mousey() + GHEIGHT/2) / GHEIGHT) - 0.5
else
`it's odd
gy = (mousey() / GHEIGHT) - boxY/2
cy# = mousey() / GHEIGHT
endif
REM Constraints (make sure box stays within boundaries
if gx < 0 then gx = 0
if gy < 0 then gy = 0
if gx > MaxGridX - boxX then gx = MaxGridX - boxX
if gy > MaxGridY - boxY then gy = MaxGridY - boxY
REM draw the object
ink rgb(255,0,0),0
drawBox(gx, gy, boxX, boxY)
REM draw center
ink rgb(255,128,128)
drawCenter(cx#, cy#, 1, 1)
REM draw the grid
ink rgb(128,128,128),0
drawGrid()
sync
LOOP
REM Draws a box at specified grid position.
REM Width and height are in number of grid
REM spaces: 3x3, 4x2, etc...
function drawBox(gridX, gridY, width, height)
box gridX*GWIDTH, gridY*GHEIGHT, gridX*GWIDTH+width*GWIDTH, gridY*GHEIGHT+height*GHEIGHT
endfunction
function drawCenter(gridX#, gridY#, width, height)
box gridX#*GWIDTH, gridY#*GHEIGHT, gridX#*GWIDTH+width*GWIDTH, gridY#*GHEIGHT+height*GHEIGHT
endfunction
REM Draw a grid divided by tiles with
REM the specified dimensions.
function drawGrid()
sw = screen width()
sh = screen height()
w = sw / GWIDTH
h = sh / GHEIGHT
for x = 0 to w-1
line x*GWIDTH, 1, x*GWIDTH, sh
next x
for y = 0 to h-1
line 1, y*GHEIGHT, sw, y*GHEIGHT
next y
endfunction