1

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()

enter image description here enter image description here enter image description here

1
  • It scales when I drag the window on both, x, y axis. In that case my inner window stays in some specific aspect ratio and has black bars. My only issue here is that am not able to print tile location correctly if I also use scroll, which somehow only occurs if I scale my window first Commented Nov 11, 2023 at 16:58

1 Answer 1

1

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))))
Sign up to request clarification or add additional context in comments.

1 Comment

Oh I see, so in order to add scroll to my mouse position I first have to calculate scroll_x separately with TILE_SIZE because thats also an absolute constant in this case. Clever, simple, thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.