Could you identify a bug in my code and explain why, when I use int((mouse_x + scroll_x) // (tw / MAX_COL)), int((mouse_y // th / MAX_ROW))
and hover over some tile, it consistently prints incorrect tile numbers every time I scale my window? For instance, when referring to tile (19, 0), the printed number is incorrect, it displays (21, 0), and the offset increases or descreases with a larger window scale. It also occurs only if I scroll my window firts. My code:
import pygame as pg
import json
SCREEN_WIDTH = 1920
SCREEN_HEIGHT = 1080
ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT
WIDTH = 640
HEIGHT = 360
TILE_SIZE = 32
MAX_COL = 20
MAX_ROW = 10
pg.init()
# 16:9 R
screen = pg.display.set_mode((WIDTH, HEIGHT), pg.RESIZABLE) # 0, 0
s = pg.Surface([WIDTH, HEIGHT])
pg.display.set_caption("Level editor")
scroll_x = 0
move_front = False
move_back = False
img = pg.image.load("rock.png") # .get_rect().colliderect() -> bool
world_data = []
for col in range(MAX_COL):
world_data.append([-1 for i in range(MAX_ROW)])
def draw_world():
for x, col in enumerate(world_data):
for y, row in enumerate(col):
if row >= 0:
s.blit(img, (x * TILE_SIZE - scroll_x, y * TILE_SIZE))
with open("data.json", "w") as file:
json.dump(world_data, file)
def draw_grid():
s.fill((255, 255, 255))
for v in range(MAX_COL + 1):
# vertical / col
pg.draw.line(s, (0, 0, 0), (TILE_SIZE * v - scroll_x, 0), (TILE_SIZE * v - scroll_x, HEIGHT))
# horizontal / row
for h in range(MAX_ROW + 1):
pg.draw.line(s, (0, 0, 0), (0 - scroll_x, TILE_SIZE * h), (MAX_COL * TILE_SIZE - scroll_x, TILE_SIZE * h))
def draw_bg():
global tw, th
sw = screen.get_width()
sh = screen.get_height()
tw = sw
th = tw / ASPECT
if th > sh:
th = sh
tw = th * ASPECT
pad_x = sw / 2 - tw / 2
pad_y = sh / 2 - th / 2
f = pg.transform.scale(s, (tw ,th))
screen.blit(f, (pad_x, pad_y))
while True:
draw_grid()
draw_world()
draw_bg()
if move_front: # move_right
scroll_x += 1
elif move_back:
scroll_x -= 1
mouse_x, mouse_y = pg.mouse.get_pos()
grid_x = screen.get_width() / 2 - tw / 2
grid_y = screen.get_height() / 2 - th / 2
mouse_x -= grid_x
mouse_y -= grid_y
print(int((mouse_x + scroll_x) // (tw / MAX_COL)), int((mouse_y // th / MAX_ROW)))
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_d:
move_front = True
elif event.key == pg.K_a:
move_back = True
if event.type == pg.KEYUP:
if event.key == pg.K_d:
move_front = False
elif event.key == pg.K_a:
move_back = False
if event.type == pg.MOUSEBUTTONDOWN:
if mouse_x >= 0 and mouse_y >= 0:
if mouse_x < tw and mouse_y < th:
pass
pg.display.flip()
The problem is that you scale scroll_x
when calculating the column. However, the grid is scrolled before it is scaled, so the tile size used when drawing the grid must be used to calculate the scroll offset:
print(int((mouse_x + scroll_x) // (tw / MAX_COL)), int((mouse_y // th / MAX_ROW)))
print(int(scroll_x / TILE_SIZE + mouse_x / (tw / MAX_COL)), int((mouse_y // (th / MAX_ROW))))