Rect.move() Does not move the rect

2019-07-03 16:01发布

问题:

    '''
Created on 21. sep. 2013

Page 136 in ze almighty python book, 4.3

@author: Christian
'''

import sys,pygame,time

pygame.init()

numLevels = 15           # Number of levels    
unitSize = 25            # Height of one level 
white = (255,255,255)    # RGB Value of White
black = (0,0,0)          # RGB Value of Black
size = unitSize * (numLevels + 1)
xPos = size /2.0         # Constant position of X value 
screenSize = size,size   # Screen size to accomodate pygame 

screen = pygame.display.set_mode(screenSize)

for level in range(numLevels):
    yPos = (level + 1) * unitSize
    width = (level +1) * unitSize
    block = pygame.draw.rect(screen,white,(0,0,width,unitSize),0)
    block.move(xPos,yPos)
    pygame.time.wait(100)
    pygame.display.flip()

The block.move(xPos,yPos) should work, but it does not for some odd reason. I have no idea why. I am fairly certain that everything else is working just fine, I have searched the interwebs for hours before coming on this site to ask for help.

回答1:

From the documentation it seems draw.rect takes a Rect in its constructor, not a tuple:

block = pygame.draw.rect(screen, white, Rect(0, 0, width, unitSize), 0)

Moving the returned Rect doesn't magically draw the block again. To draw the block again, you will need to draw the block again:

block.move(xPos,yPos)
block = pygame.draw.rect(screen, white, block, 0)

Of course you now have two blocks on your screen, because you have drawn twice. Since you want to move the block anyway, why draw it at the old location in the first place? Why not just specify the location you want it at to begin with?

block = pygame.draw.rect(screen, white, Rect(xPos, yPos, width, unitSize), 0)

With more information on what you're trying to do, perhaps a better answer can be constructed.



回答2:

It's unclear to me what your code is trying to accomplish (and I don't recongnize the book reference), so this is just a guess. It first constructs a Rect object and then incrementally re-positions and re-sizes (inflates) it just before it's drawn on each iteration of the loop.

Note the use of move_ip() and inflate_ip() which change the Rect object "in place", meaning they modify its characteristics rather than returning a new one, but don't (re)draw it (and don't return anything). This uses less resources than creating a new Rect for each iteration.

import sys, pygame, time

pygame.init()

numLevels = 15           # Number of levels
unitSize = 25            # Height of one level
white = (255, 255, 255)  # RGB Value of White
black = (0, 0, 0)        # RGB Value of Black
size = unitSize * (numLevels+1)
xPos = size / 2.0        # Constant position of X value
screenSize = size, size  # Screen size to accomodate pygame

screen = pygame.display.set_mode(screenSize)
block = pygame.Rect(0, 0, unitSize, unitSize)

for level in range(numLevels):
    block.move_ip(0, unitSize)
    block.inflate_ip(0, unitSize)
    pygame.draw.rect(screen, white, block, 0)
    pygame.time.wait(100)
    pygame.display.flip()


标签: python pygame