2

This is in pygame. How do I flip an image (lets say an image of a pig looking to the right) to look to the left when I press the left arrow key, and stay like that even if I don't press any keys or if I press the up and down arrow keys. Then how do I switch it back again to look to the right when I press the right arrow key and make it stay like that even if I don't press any key or if I press the up and down arrow keys.

I know I have to use pygame.transform.flip(). But, I don't know how to put it in my code.

This is the main game:

import sys

import pygame

from pig import Pig

pygame.init()

screen_width = 800
screen_height = 600

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Flying Pig")

blue_sky = 135, 206, 250
brown = 139, 69, 19

pig = Pig(screen)

while True:

    # Accept events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        # Keydown events
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                pig.moving_right = True
            elif event.key == pygame.K_LEFT:
                pig.moving_left = True
            elif event.key == pygame.K_UP:
                pig.moving_up = True
            elif event.key == pygame.K_DOWN:
                pig.moving_down = True

        # Keyup events
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                pig.moving_right = False
            elif event.key == pygame.K_LEFT:
                pig.moving_left = False
            elif event.key == pygame.K_UP:
                pig.moving_up = False
            elif event.key == pygame.K_DOWN:
                pig.moving_down = False

    screen.fill(blue_sky)

    pig.blitme()
    pig.update()

    pygame.display.flip()

The pig class: (This is indented. I just don't know how to properly copy and paste my code here)

import pygame 

class Pig():

    def __init__(self, screen):
        """Initialize the pig and set its starting position."""
        self.screen = screen

        # Load the pig image and set pig and screen to rect.
        self.image = pygame.image.load('pig.png')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Start the pig at the bottom center of the screen.
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # Speed of the pig
        self.pig_speed = 1.5
        self.center = float(self.pig_speed)

        # Set a variable for each movement.
        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False

        self.direction = ['right', 'left']

    def update(self):
        """Update the position of the pig."""

        if self.rect.right <= self.screen_rect.right:
            if self.moving_right:
                self.rect.centerx += self.pig_speed

        if self.rect.left > 0:
            if self.moving_left:
                self.rect.centerx -= self.pig_speed

        if self.rect.top > 0:
            if self.moving_up:
                self.rect.bottom -= self.pig_speed

        if self.rect.bottom <= self.screen_rect.bottom:
            if self.moving_down:
                self.rect.bottom += self.pig_speed

    def blitme(self):
        """Draw the pig at its current location."""
        self.screen.blit(self.image, self.rect)
skrx
  • 19,980
  • 5
  • 34
  • 48
Katrina
  • 111
  • 2
  • 2
  • 10
  • To format the code correctly, you have to select it in the submission window and press "Ctrl-K" (that adds four extra spaces before each line of code). – skrx Aug 10 '17 at 00:54

3 Answers3

5

Add a pig orientation variable. Set it on key down, don't change it back on key up. Have movement rely on the moving_direction variable and the sprite displayed rely on the orientation variable.

Change blitme like so:

def blitme(self):
    if self.orientation == "Right":
        self.screen.blit(self.image, self.rect)
    elif self.orientation == "Left":
        self.screen.blit(pygame.transform.flip(self.image, False, True), self.rect)

Then you can have your key press logic like so:

elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                pig.moving_right = True
                pig.orientation = "Right"
            elif event.key == pygame.K_LEFT:
                pig.moving_left = True
                pig.orientation = "Left"
            elif event.key == pygame.K_UP:
                pig.moving_up = True
            elif event.key == pygame.K_DOWN:
                pig.moving_down = True

In this way you can separate display and movement logic.

Saedeas
  • 1,548
  • 8
  • 17
3

pygame.transform.flip takes three arguments:

  1. The surface you want to flip
  2. A boolean to indicate that the surface should be flipped horizontally
  3. A boolean to indicate that the surface should be flipped vertically

To flip the surface only vertically pass True as the third argument:

flipped_surface = pygame.transform.flip(surface, False, True)

Regarding your specific problem, you could do something like this:

PIG_RIGHT = pygame.image.load('pig.png').convert()
PIG_LEFT = pygame.transform.flip(PIG_RIGHT, True, False)

pig = Pig(screen, PIG_RIGHT)  # Assign this image to `self.image`.
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                pig.moving_right = True
                pig.image = PIG_RIGHT
            elif event.key == pygame.K_LEFT:
                pig.moving_left = True
                pig.image = PIG_LEFT

    screen.fill(blue_sky)

    pig.blitme()
    pig.update()

    pygame.display.flip()
    clock.tick(30)

You could also store the two suraces in your Pig class and switch the self.image in relation to the state of the self.moving_right, self.moving_left or self.direction attributes.

skrx
  • 19,980
  • 5
  • 34
  • 48
  • When I press the left arrow key it flips to the left (so the pig is looking to the left) but when I release it, it flips back to the original image (so the pig is now looking to the right again). How do I make it stay looking to the left even if i release the key? – Katrina Aug 09 '17 at 22:56
  • You could do it like so: First load the original image and create the flipped version in the global scope. When the player presses the left key, set `pig.image` to the left image and when the player presses the right key set the `pig.image` back to the right image. – skrx Aug 09 '17 at 23:27
  • Side note: I recommend to add a `pygame.time.Clock` to limit the frame rate. – skrx Aug 10 '17 at 00:51
  • Also, note that constantly flipping or scaling a surface during the run time of the game is a lot more costly than creating the surfaces beforehand and to switch the `self.image` attribute. – skrx Aug 10 '17 at 00:57
0

Try adding something like this:

elif event.key == pygame.K_RIGHT:
    pig.image = pygame.transform.flip(pig.image, True, False)
    pygame.display.update()'''I dont think you need this'''
elif event.key == pygame.K_LEFT:
    pig.image = pygame.transform.flip(pig.image, True, False)
    pygame.display.update()'''Or this'''
Technojazz
  • 48
  • 4