简体   繁体   中英

Pygame shape rotation

I'm working on a little game and i'm having trouble rotating one of the shapes when a key is pressed. I have managed to rotate the shape however when the key is pressed it continues to rotate (90 degrees) rather than staying in its new position. I have a feeling that it is in some type of loop however i cant seem to get it out of the loop. Hope someone can help. The relevant code is located at the sixth line up from the bottom (elif keys[K_d])

class Player(pygame.sprite.Sprite):

def __init__(self, screen):
    self.screen = screen
    self.image = pygame.image.load(os.path.join('shape.png'))
    self.rect = self.image.get_rect()
    self.rect.x = 10
    self.rect.y = 540
    #You don't need to define self.width because it is now self.rect.width
    #Same with self.height
    self.speed = 10

def update(self):
    keys = pygame.key.get_pressed()      

    if keys[K_LEFT]:
        self.rect.left -= self.speed
        if self.rect.left < 0: #The left edge
            self.rect.left = 0
    elif keys[K_RIGHT]:
        self.rect.right += self.speed
        if self.rect.right > WINDOW_WIDTH:
            self.rect.right = WINDOW_WIDTH
    elif keys[K_UP]:
        self.rect.top -= self.speed
        if self.rect.top < 0:
            self.rect.top = 0
    elif keys[K_DOWN]:
        self.rect.bottom += self.speed
        if self.rect.bottom > WINDOW_HEIGHT:
            self.rect.bottom = WINDOW_HEIGHT
    ***#THE CODE BELOW IS THE SHAPES ROTATION***.        
    elif keys[K_d]:
        self.image = pygame.transform.rotate(self.image, 90)   

def draw(self, screen=None):
    if screen is None:
        screen = self.screen

    screen.blit(self.image, (self.rect.x, self.rect.y))

As far as I see it, you are actually calling the update every frame.

pygame.keys.get_pressed() returns "d" as pressed every frame if "d" really is pressed. Better work with an event check for pygame.KEYDOWN and KEYUP events. They are only fired once the key is pressed and once it is released.

I suggest to add a keymap to the main program class' constructor (the

def __init__(self):

part).

I only add the d-key now to my example, the others you could add on your own.

self.keymap = {pygame.K_d: False}

then also in the main loop check for events:

while running:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key in self.keymap:
                self.keymap[event.key] = True

        if event.type == pygame.KEYUP:
            if event.key in self.keymap:
                self.keymap[event.key] = False

KEYDOWN is fired only ONCE when the key is pressed and doesn't return True every frame while the key is being held down. It sets a variable in the main class to True which you can use then in the other classes.

KEYUP is also fired only ONCE when you release a key. It resets the variable in the keymap back to False, so the program is ready to deal with the next KEYDOWN event of that key.

Check for the variable in your player's update method:

if Main.keymap[K_d] == True:
    self.image = pygame.transform.rotate(self.image, 90)

Is this of any use for you?

//edit: To make this very clear again and hopefully point out where the problem in your code lies:

pygame.keys.get_pressed

returns True every frame if the key is still pressed, therefore your rotation is performed in every frame while the key is held down.

pygame.KEYDOWN

and

pygame.KEYUP

are only fired once when the key is pressed or released, so they don't return True a second time, even if you keep pressing the key.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM