[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] what is the use of Rect.move(offsetX, offsetY) for moving an image?



Welcome. Maybe you'll find the attached tiny example informative, then. You'll find move() used in the rendering part of the game loop. Feel free to do what you want with it.

On 9/5/2015 9:27 PM, tom arnall wrote:
thanks for responding to my questions. and thanks for the helpful
ideas. i'm still very much in learning mode with pygame. with python
too actually.

On 9/5/15, bw <stabbingfinger@xxxxxxxxx> wrote:
It's convenient. Also, in my experience move() is faster than "rect.x +=
1; rect.y += 1" even though it creates a new Rect object.

I use it in the case where I have a map of objects that is bigger than
the screen. The screen is a viewport that pans around. move() is
valuable in converting the objects from real space to screen space.

On 9/5/2015 6:29 PM, tom arnall wrote:
you mean by manipulating Rect.x  etc?  yep that works fine and that's
how i handle the problem.

but why have the move() method in pygame at all? i mean, what do
people use it for typically?


On 9/5/15, bw <stabbingfinger@xxxxxxxxx> wrote:
You are correct, sir. The Rect methods convert your inputs to int, at
which point precision is lost. If we want finer spatial calculations we
must keep them in forms that don't lose precision, and apply them to the
Rect object as needed.

On 9/5/2015 2:52 PM, tom arnall wrote:
The docs say the Rect.move() can take only integers for the offset
parameters. My experiments seem to verify that. This means that it can
move an object in only a few directions, i.e., 1,0 for 0 degrees, 1,1
for 45 degrees etc. You can of course increase the magnitudes of the
offsets and get more angles, but then it is impossible to create the
effect of smooth movement.

My take anyway. Am I missing something?



import random
import pygame
from pygame.locals import *


def get_tiles_in_rect(tiles, rect):
    collide_rect = rect.colliderect
    return [t for t in tiles if collide_rect(t.rect)]


pygame.init()

resolution = 640, 480
screen = pygame.display.set_mode(resolution)
screen_rect = screen.get_rect()

clock = pygame.time.Clock()
max_fps = 120

font = pygame.font.SysFont('sans', 16)
font_fg = Color('white')
black = Color('black')

# make the ground tiles bigger than the screen
tile_group = []
world_rect = Rect(-1000, -1000, 2000, 2000)
tile_height, tile_width = 100, 100
for x in range(world_rect.x, world_rect.w, tile_width):
    for y in range(world_rect.y, world_rect.h, tile_height):
        # make the tile sprite at position (x, y), fill with a random color
        s = pygame.sprite.Sprite()
        s.image = pygame.Surface((tile_width, tile_height))
        s.image.fill(Color(random.randrange(64, 128), random.randrange(64, 128), random.randrange(64, 128)))
        s.rect = Rect(x, y, tile_width, tile_height)
        # label it
        f = font.render('{}, {}'.format(x, y), 1, font_fg)
        s.image.blit(f, (5, 5))
        tile_group.append(s)

# make a rect to use as the camera, same size as the screen;
# this will be used to compute the translation of tile rects to screen
camera = screen.get_rect(center=world_rect.center)

visible_tiles = get_tiles_in_rect(tile_group, camera)
move_x = move_y = 0

running = True
while running:
    screen.fill(black)
    for s in visible_tiles:
        screen.blit(s.image, s.rect.move(-camera.x, -camera.y))
    pygame.display.flip()

    for e in pygame.event.get():
        if e.type == KEYDOWN:
            if e.key == K_ESCAPE:
                running = False
            elif e.key == K_RIGHT:
                move_x += 1
            elif e.key == K_DOWN:
                move_y += 1
            elif e.key == K_LEFT:
                move_x -= 1
            elif e.key == K_UP:
                move_y -= 1
        elif e.type == KEYUP:
            if e.key == K_RIGHT:
                move_x -= 1
            elif e.key == K_DOWN:
                move_y -= 1
            elif e.key == K_LEFT:
                move_x += 1
            elif e.key == K_UP:
                move_y += 1
        elif e.type == QUIT:
            running = False

    if move_x or move_y:
        camera.x += move_x
        camera.y += move_y
        visible_tiles = get_tiles_in_rect(tile_group, camera)

    dt = clock.tick(max_fps) / 1000.0