Change the position of the origin in PyGame coordinate system
Asked Answered
C

3

12

I am doing some operations with vectors and physics in PyGame and the default coordinate system is inconvenient for me. Normally the (0, 0) point is at the top-left corner, but I would rather that the origin were at the bottom-left corner. I would rather change the coordinate system than converting every single thing I have to draw.

Is it possible to change the coordinate system in PyGame to make it work like this?

Countless answered 16/4, 2012 at 0:12 Comment(0)
D
17

Unfortunately, pygame does not provide any such functionality. The simplest way to do it would be to have a function to convert coordinates, and use it just before drawing any object.

def to_pygame(coords, height):
    """Convert coordinates into pygame coordinates (lower-left => top left)."""
    return (coords[0], height - coords[1])

This will take your coordinates and convert them into pygame's coordinates for drawing, given height, the height of the window, and coords, the top left corner of an object.

To instead use the bottom left corner of the object, you can take the above formula, and subtract the object's height:

def to_pygame(coords, height, obj_height):
    """Convert an object's coords into pygame coordinates (lower-left of object => top left in pygame coords)."""
    return (coords[0], height - coords[1] - obj_height)
Dara answered 17/4, 2012 at 1:43 Comment(0)
M
4

If the objects you're trying to render are vertically symmetrical (like rectangles), you can just flip the screen to get the coordinate system to be the bottom-left, like this:

display_surface = pygame.display.get_surface()
display_surface.blit(pygame.transform.flip(display_surface, False, True), dest=(0, 0))

You can do the same thing horizontally top/bottom-right. The important methods are documented here:

Marigolda answered 22/2, 2020 at 19:58 Comment(0)
R
0

(⚠️ this example rotates in the other direction you can probably take the point transformation from the other answer and convert -90 to 90)

from typing import Sequence
import pygame
from pygame.surface import Surface


class ConvertableScreen:

    def __init__(self, surface: Surface):
        self.surface = surface
        size = surface.get_size()
        self.width = size[0]
        self.height = size[0]

    def blit(self, source: Surface, dest: Sequence[float]):
        # convert points
        new_dest = (self.height-dest[1], dest[0])
        # rotate surface
        rotate90 = pygame.transform.rotate(source, -90)
        self.surface.blit(rotate90, new_dest)
        pass

    def fill(self, col):
        self.surface.fill(col)

this is also an approach , but it has the drawback that pygame expects surfaces for some function calls

  • youd have to rewrite those to .surface

and also depending on the apis you use you may need to forward additional calls

Rambunctious answered 7/2 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.