How do I stop a sprite from moving diagonally using Pygame? - python

I am making a snake game. Anytime I press an arrow key to move in one direction then press a key in another direction, the snake will diagonally. (E.g. if I first press right then press up.) This happens even if the previous key is released. How can I stop this?
# x and y marks the player's position
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -10
if event.key == pygame.K_RIGHT:
x_change = 10
if event.key == pygame.K_UP:
y_change = -10
if event.key == pygame.K_DOWN:
y_change = 10
x += x_change
y += y_change

I have added y_change = 0 and x_change = 0 to reset the values to only keep orthogonal movement.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -10
y_change = 0
if event.key == pygame.K_RIGHT:
x_change = 10
y_change = 0
if event.key == pygame.K_UP:
y_change = -10
x_change = 0
if event.key == pygame.K_DOWN:
y_change = 10
x_change = 0
x += x_change
y += y_change

Related

trying to make a sprite jump

**When ever i press up arrow the sprite jumps but when it comes down it carrys on going down. Here is my code. it does not do this with left and rght keys.
x = (display_width * 0.1)
y = (display_height * 0.75)
x_change = 0
y_change = 0
over = False
while over == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change -= 5
if event.key == pygame.K_RIGHT:
x_change += 5
if event.key == pygame.K_UP:
y_change = -30
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change = 0
if event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_UP:
y_change = 30
x += x_change
y += y_change
The problem is caused by the y_change remaining at 30 during later processing.
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change = 0
if event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_UP:
y_change = 30 # <=== HERE
So when the event fires, the y_change becomes 30 - so the position moves back down. But on the next loop, y_change is still 30, so it keeps moving down, again and again.

Flipping an image with python (pygame)

I'm trying to learn python so I'm messing around with pygame. I'm a complete beginner.
so far I have made it so that I can control an image, moving it in 2d with the arrow keys.
However, I drew the image facing left and it is always facing left and I want to make it face the direction it's moving. I managed to make it rotate 180 degrees when I press right, but that was everytime I press right so I kept flipping the wrong way.
I need it to face right when moving right and left when moving left.
Image attached.
Thank you
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black=(0,0,0)
white=(255,255,255)
gamedisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg= pygame.image.load('snake.png')
snake_width = 96
snake_height= 79
def snake(x,y):
gamedisplay.blit(snakeimg, (x,y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = TRUE
print (event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change=0
y_change=0
snake_speed=0
gameExit= False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
print(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_RIGHT:
x_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change = 0
elif event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
y += y_change
gamedisplay.fill(white)
snake(x,y)
if x > display_width-snake_width or x < 0:
gameExit=True
if y > display_height-snake_height or y < 0:
True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Mainly i change the snake function, so that it computes the correct rotation and then rotates the image. Also I change a little bit of the logic, especially at event handling so it is easier to read
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black = (0, 0, 0)
white = (255, 255, 255)
gamedisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg = pygame.image.load('snake.png')
snake_width = 96
snake_height = 79
def snake(x, y):
if x_change == 0 and y_change == 0:
rotation = -90
elif x_change > 0 and y_change == 0:
rotation = 180
elif x_change < 0 and y_change == 0:
rotation = 0
elif x_change == 0 and y_change > 0:
rotation = 90
elif x_change == 0 and y_change < 0:
rotation = -90
elif x_change < 0 and y_change < 0:
rotation = -45
elif x_change < 0 and y_change > 0:
rotation = 45
elif x_change > 0 and y_change < 0:
rotation = -135
elif x_change > 0 and y_change > 0:
rotation = 135
gamedisplay.blit(pygame.transform.rotate(snakeimg, rotation), (x, y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = True
print(event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
snake_speed = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
gameExit = True
discovered = True # so you can actually quit the game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
x_change = 0
elif event.key in (pygame.K_UP, pygame.K_DOWN):
y_change = 0
x += x_change
y += y_change
gamedisplay.fill(white)
snake(x, y)
if x > display_width - snake_width or x < 0:
gameExit = True
if y > display_height - snake_height or y < 0:
gameExit = True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
And still i have the question: Why 2 game loops inside each other?

Falling mechanics (gravity) in pygame

How would I get some mechanics for falling when in an empty space, many answers on the internet said to add gravity but I couldn't understand how they did that they just showed me a bunch of equations.
Also, how would I set an image as my background?
Here's my source code:
import pygame
pygame.init()
display_width = 2560
display_height = 1440
white = (255,255,255)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('RGB')
clock = pygame.time.Clock()
filler = pygame.image.load('filleraftergimp.png')
def fill(x,y):
gameDisplay.blit(filler,(x,y))
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
diedorgameover = False
while not diedorgameover:
for event in pygame.event.get():
if event.type == pygame.QUIT:
diedorgameover = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
x_change = -5
elif event.key == pygame.K_d:
x_change = 5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_w:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
x_change = 0
if event.key == pygame.K_s or event.key == pygame.K_w:
y_change = 0
x += x_change
y += y_change
gameDisplay.fill(white)
fill(x,y)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
To implement gravity in your game (as in a 2D platformer), you can just increase the y_change variable each frame, so that you move the object a bit faster downwards each time. Take a look at this example:
import pygame as pg
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
DARKBLUE = pg.Color(11, 8, 69)
display = pg.display.set_mode((800, 600))
width, height = display.get_size()
clock = pg.time.Clock()
player_image = pg.Surface((30, 60))
player_image.fill(DARKBLUE)
x = width * 0.45
y = 0
x_change = 0
y_change = 0
on_ground = False
# A constant value that you add to the y_change each frame.
GRAVITY = .3
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
x_change = -5
elif event.key == pg.K_d:
x_change = 5
elif event.key == pg.K_s:
y_change = 5
elif event.key == pg.K_w:
if on_ground: # Only jump if the player is on_ground.
y_change = -12
on_ground = False
elif event.type == pg.KEYUP:
if event.key == pg.K_a and x_change < 0:
x_change = 0
elif event.key == pg.K_d and x_change > 0:
x_change = 0
# Add the GRAVITY value to y_change, so that
# the object moves faster each frame.
y_change += GRAVITY
x += x_change
y += y_change
# Stop the object when it's near the bottom of the screen.
if y >= height - 130:
y = height - 130
y_change = 0
on_ground = True
# Draw everything.
display.fill(LIGHTBLUE)
pg.draw.line(display, (0, 0, 0), (0, height-70), (width, height-70))
display.blit(player_image, (x, y))
pg.display.update()
clock.tick(60)
pg.quit()

Pygame simple issue, object movement and display

player_1 = pygame.image.load(player1)
#
def player1(x,y):
window.blit(player_1, (x,y))
x = (110)
y = (150)
x_change = 0
y_change = 0
player1_speed = 0
while not gameover:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameover = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
elif event.key == pygame.K_UP:
y_change = -5
elif event.key == pygame.K_DOWN:
y_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
x_change = 0
x += x_change
y += y_change
player1(x,y)
pygame.display.update()
fpsClock.tick(60)
screen.blit(background_surface, (0,0))
# update display
pygame.display.flip()
Hi, I have a program where unfortunatley when moving the object, it moves left & right perfectly but up and down does not seem to stop. There is also an issue of the screen flashing. Sorry for the long question but any help would be appreciated. Thanks
1. As far as I see you are only blitting player1. Where is player2?
2. You are missing some indentation in your code. I guess the correct form would be:
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
x_change = 0
3. Then your are only setting x_change to 0. I guess you want to set y_change to 0 as well... even though you have to make your query more specific by grouping up vertical and horizontal keys.
Like:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
4. You call the blit method after updating the screen. Moving pygame.display.update() after screen.blit(..) would fix some things...
5. The flip method is outside of your loop. It will only be called if your game loop breaks!
Little hint: Copy-Pasting is a very bad practice. Try to do it yourself instead!

My sprite keeps moving off of the screen in pygame

so I've been messing around with sprites and movement in pygame and the issue I keep running into with my code is that when you hold down the key the sprite won't stop moving, but if it is past the point at which it is supposed to stop and you let go and try again it will do what it is meant to and not move, is there any way I can have it happen straight away so it won't keep disappearing from my screen?
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
if player.x + 4 < 700:
moveX = 4
else:
moveX = 0
if event.key == pygame.K_LEFT:
if player.x == 0:
moveX = 0
else:
moveX = -4
if event.key == pygame.K_UP:
moveY = -4
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
moveX = 0
if event.key == pygame.K_LEFT:
moveX = 0
if event.key == pygame.K_UP:
moveY = 0
player.falling = True
player.collision = False
player.onground = False
Something seems not right with the indentation.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
if player.x + 4 < 700:
moveX = 4 # <----- should this be here ?
else: # <----- this should match the `event.key == pygame.K_RIGHT` condition
moveX = 0
if event.key == pygame.K_LEFT:
if player.x == 0:
moveX = 0
else:
moveX = -4
if event.key == pygame.K_UP:
moveY = -4
Can you please redo the indentation and check?
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
if player.x + 4 < 700: moveX = 4
else: moveX = 0
if event.key == pygame.K_LEFT:
if player.x == 0: moveX = 0 # here you might want to try player.x <= 0 ...
else: moveX = -4
...
may be easier to handle ...

Categories