How do I flip an image horizontally in pygame?
Solution 1
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.
Solution 2
pygame.transform.flip
takes three arguments:
- The surface you want to flip
- A boolean to indicate that the surface should be flipped horizontally
- 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.
Katrina
Updated on July 25, 2022Comments
-
Katrina almost 2 years
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 almost 7 yearsTo 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).
-
-
Katrina almost 7 yearsWhen 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?
-
skrx almost 7 yearsYou 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 thepig.image
back to the right image. -
Katrina almost 7 yearsCan you elaborate more?
-
Saedeas almost 7 yearsSee my edit. I think it should clarify (note you may have to tweak things a little).
-
skrx almost 7 yearsSide note: I recommend to add a
pygame.time.Clock
to limit the frame rate. -
skrx almost 7 yearsAlso, 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.