Pygame simple issue, object movement and display - python

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!

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.

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

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

Python keyboard controls

Here is my code I have trouble with, it's a basic side scroller game but I am having troubles with my keyboard control definitions, they don't seem to work, and I can't find the problem.
if keys[K_LEFT]:
newmove= LEFT
moveLeft(guy,10)
climb(guy)
if keys[K_RIGHT]:
newmove=RIGHT
moveRight(guy,10)
climb(guy)
if keys[K_SPACE] and guy[ONGROUND]:
guy[VY] = -14
else:
frame=0
if move==newmove:
frame=frame+0.1
if frame>=len(pics[move]):
frame=1
elif newmove!=-1:
move=newmove
frame=1
Have you tried using this? or something like this?
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
xChange = -5
print("Left")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 5
print("Right")
if event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
xChange = 0

pygame - How do I change a variable while it is being used?

I'm making a simple top-down game with moving and collision between player and walls, using pygame.
I made my code so that when keys[pygame.K_LSHIFT] is True during the pygame.key.get_pressed at the state of the keyboard when it's called, block_speed changes to 5 instead of 3. So it works and when I hold SHIFT and move with WASD keys at the same time my speed becomes 5.
Now, the problem is when I let go of SHIFT while still moving, my speed doesn't change back to 3 but stays at 5. But if I stop moving, then move, block_speed changes back to 3 as expected. It seems as if any change to block_speed only happens when I stop moving then move again.
I'm guessing it only receives the new value of block_speed after the current copy of block_speed is done being used.
How do I change block_speed with SHIFT while this variable is being used by the program?
def run(self):
pygame.init()
pygame.display.set_caption("Platformer v1")
block_speed = 3
sprite_list = pygame.sprite.Group()
wall_list = pygame.sprite.Group()
left_wall = Wall(0,0,10,resolution[1])
wall_list.add(left_wall)
sprite_list.add(left_wall)
top_wall = Wall(10,0,resolution[0]-10,10)
wall_list.add(top_wall)
sprite_list.add(top_wall)
test_wall = Wall(10,150,200,10)
wall_list.add(test_wall)
sprite_list.add(test_wall)
player = Player(50,50)
player.walls = wall_list
sprite_list.add(player)
while True:
self.screen.fill(black)
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if keys[pygame.K_LSHIFT]:
block_speed = 5
else:
block_speed = 3
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
player.change_x += block_speed
elif event.key == pygame.K_a:
player.change_x += -block_speed
elif event.key == pygame.K_w:
player.change_y += -block_speed
elif event.key == pygame.K_s:
player.change_y += block_speed
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
player.change_x = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
player.change_y = 0
sprite_list.update()
sprite_list.draw(self.screen)
pygame.display.update()
self.clock.tick(FPS)
Your issue is that when you add block speed to player.change_x/change_y, it performs that calculation at that time. Changing the variable afterwards won't make a difference.
A simple solution for your case is to simply make the change to block_speed happen before you use it. If you do this, block_speed has the value you want when it comes to changing the other variables, giving you the result you want.
Edit: I realise there is another issue - that is, you only change the movement speed if the key is newly pressed (the event is fired), so changing block speed still won't change the speed unless a direction key is pressed. The solution is to do your calculation every time, regardless.
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if keys[pygame.K_LSHIFT]:
block_speed = 5
else:
block_speed = 3
if keys[pygame.K_d]:
player.change_x += block_speed
if keys[pygame.K_a]:
player.change_x += -block_speed
if keys[pygame.K_w]:
player.change_y += -block_speed
if keys[pygame.K_s]:
player.change_y += block_speed
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
player.change_x = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
player.change_y = 0
An alternative would be to store the direction when a key is pressed, then multiply this up by the speed at the time you do the movement each frame:
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if keys[pygame.K_LSHIFT]:
player.block_speed = 5
else:
player.block_speed = 3
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
player.change_x += 1
elif event.key == pygame.K_a:
player.change_x -= 1
elif event.key == pygame.K_w:
player.change_y -= 1
elif event.key == pygame.K_s:
player.change_y += 1
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
player.change_x = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
player.change_y = 0
And then in your position code, do self.rect.x += self.change_x * self.block_speed instead. This is probably a preferable solution.
I've had the same issue and tried using the code from the suggested answer but found it did not work for me. My sprite still moved at the base speed until a key was lifted.
Looking at this thread, I tried moving the get_pressed() key detection outside of the event loop, which fixed things.
keys = pygame.key.get_pressed()
if keys[pygame.K_LSHIFT]:
player.block_speed = 5
else:
player.block_speed = 3
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
player.change_x += 1
#etc.
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
player.change_x = 0
#etc.
As in the above answer, in your position code have self.rect.x += self.change_x * self.block_speed.
This allowed me to get a speed boost effect when a certain key was held down and revert back to the base speed when it was not.
import pygame
running = True
while running:
for event in pygame.event.get():
#K_UP mean releasing the key
if event.type == pygame.K_UP:
if event.key == pygame.K_LSHIFT:
block_speed = 3

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