Countour-Integral
Countour-Integral

Reputation: 1154

Pygame - Transform screen on mouse movement

I am trying to implement the transformation, where if you are holding down the left mouse button and you move your mouse, the screen will be transformed accordingly. The same thing that happens in Google maps, the holding and dragging the screen thing. I could not find a function in pygame to transform the screen, something like screen.transform so I did this.

I am converting from pixel to cartesian cordinates, and vice versa.

x_offset = 0
y_offset = 0

# Cartesian to pixels
def to_pixels(x, y):
    center_x = (WIDTH / 2) + x_offset  # The center of the screen (Width/2) + some transformation in x 
    center_y = (HEIGHT / 2) + y_offset 
    return center_x + x, center_y - y

# Pixels to cartesian
def to_cartesian(pW, pH):
    center_x = (WIDTH / 2) + x_offset
    center_y = (HEIGHT / 2) + y_offset
    return (pW - center_x), -(pH - center_y)

The way I am performing the screen transformation is by adding an x_offset and y_offset basically moving the center.

Now, the real problem in the main loop I am storing the mouse position in an array pos = [0, 0] and updating every time

while 1:
    posX, posY = to_cartesian(*pygame.mouse.get_pos()) # mouse cords to caretsian
    if pygame.mouse.get_pressed(3)[0]:
        # Translate X
        translate = pos[0] - (pos[0] - posX)
        x_offset += translate
        # Translate Y
        translate = pos[1] - (pos[1] - posY)
        y_offset -= translate

    pos = [posX, posY]
    pygame.draw.rect(screen, color, (*to_pixels(0, 0), 20, 20)) # Drawing any shape to visualize

The problem is, despite the transformation being smooth, that the mouse cursor, is always be stuck in the (0, 0) coordinates of the screen. Wherever i click, it becomes the center.

If you are bored to write the basic pygame.init() functions here is a working example but instead of pygame.rect it uses another shape to better illustrate the problem

Upvotes: 2

Views: 163

Answers (1)

Spacha
Spacha

Reputation: 373

The problem is that your program does not remember the old offset value.

Here is a modified version of your code which works as expected. One solution is that you use a flag mouse_held that becomes True when mouse is just pressed down and False when it's released. This can then be used to save the old offset values so they won't get overwritten when the mouse is pressed down next time.

    # ...

    if pygame.mouse.get_pressed(3)[0]:
        mpos = pygame.mouse.get_pos()

        # mouse is just PRESSED down
        if not mouse_held:
            mouse_origin = mpos
            mouse_held = True
        
        # mouse is being HELD
        if mouse_held:
            offset_x = old_offset_x + mpos[0]-mouse_origin[0]
            offset_y = old_offset_y +mpos[1]-mouse_origin[1]

    # mouse is just RELEASED
    elif mouse_held:
        old_offset_x = offset_x
        old_offset_y = offset_y
        mouse_held = False

    # ...

Also, your to_pixels function returned floats which is not very good thing.

Upvotes: 2

Related Questions