I've been watching a pygame tutorial on youtube on player movement, and by using this code below, the guy making the video was able to hold down a key and the character would keep moving, but when i hold down a key the character will move once and then stop. Any ideas on how to fix this?
Code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("huge honkabonkaros")
x = 50
y = 440
width = 40
height = 60
vel = 5
run = True
while run:
pygame.time.delay(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
pygame.quit()
It is a matter of Indentation. The continuous movement must be in the application loop and not in the event loop. The application loop runs once per frame, but the event loop only runs once per event. When a key is pressed a KEYDOWN event occurs and when a key is released a KEYUP event occurs, but there is no event when a key is held down:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("huge honkabonkaros")
x = 50
y = 440
width = 40
height = 60
vel = 5
run = True
while run:
pygame.time.delay(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# INDENTATION
#<--|
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
pygame.quit()
Related
My character movement is bugging and i don't know why at all
When i run it it moves forward and like bugs backwards
Ive changed velocity and framerate to no avail and an scared to touch the code coz i just got it to work when the backgound is visible
import pygame
import os
WIDTH, HEIGHT = 1920, 1080
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Gaem")
WHITE = (255, 255, 255)
FPS = 60
Vel = 5
CHARACTER = pygame.image.load('MAN.png')
def draw_window(CHARACTERM):
WIN.fill((WHITE))
WIN.blit(CHARACTER, (CHARACTERM.x, CHARACTERM.y))
pygame.display.update()
def main():
CHARACTERM = pygame.Rect(100, 300, 850, 450)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
##########CHARACTER MOVMENT####################
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_a]: #Left
CHARACTERM.x -= Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_d]: #Right
CHARACTERM.x += Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_w]: #Up
CHARACTERM.y -= Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_s]: #Down
CHARACTERM.y += Vel
################################################
draw_window(CHARACTERM)
pygame.quit()
if __name__ == "__main__":
main()
Thank you Zatando1
It is sufficient to call pygame.key.get_pressed() and draw_window() once:
def main():
CHARACTERM = pygame.Rect(100, 300, 850, 450)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_a]: #Left
CHARACTERM.x -= Vel
if keys_pressed[pygame.K_d]: #Right
CHARACTERM.x += Vel
if keys_pressed[pygame.K_w]: #Up
CHARACTERM.y -= Vel
if keys_pressed[pygame.K_s]: #Down
CHARACTERM.y += Vel
draw_window(CHARACTERM)
pygame.quit()
If you call draw_window() multiple times, pygame.display.update() will be executed multiple times in each frame. An update of the display at the end of the application loop is sufficient. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering.
I am making a game in pygame. In this game, the background image is large. On the screen, player only sees about 1/20th of the background image. I want, when player presses the left, right, up or down arrow keys, the background image moves respectively, but, it stops moving when player reaches the end of the image. I have no idea how to do this.
My code up to this point :-
import pygame
FPS = 60
screen = pygame.display.set_mode((1000, 1000))
bg = pygame.image.load('map.png')
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
Thanks in Advance :-
Get the sice of the background and the screen by get_size():
screen_size = screen.get_size()
bg_size = bg.get_size()
Define the initial start of the background in range [0, bg_size[0]-screen_size[0]]. e.g. center of the background:
bg_x = (bg_size[0]-screen_size[0]) // 2
Get the list of the key states by pygame.key.get_pressed():
keys = pygame.key.get_pressed()
Change bg_x dependent on the state of left and right:
if keys[pygame.K_LEFT]:
bg_x -= 10
if keys[pygame.K_RIGHT]:
bg_x += 10
Clamp bg_x to the range [0, bg_size[0]-screen_size[0]]:
bg_x = max(0, min(bg_size[0]-screen_size[0], bg_x))
blit the background at -bg_x on the screen:
screen.blit(bg, (-bg_x, 0))
See the example:
import pygame
FPS = 60
screen = pygame.display.set_mode((1000, 1000))
bg = pygame.image.load('map.png')
screen_size = screen.get_size()
bg_size = bg.get_size()
bg_x = (bg_size[0]-screen_size[0]) // 2
bg_y = (bg_size[1]-screen_size[1]) // 2
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
bg_x -= 10
if keys[pygame.K_RIGHT]:
bg_x += 10
if keys[pygame.K_UP]:
bg_y -= 10
if keys[pygame.K_DOWN]:
bg_y += 10
bg_x = max(0, min(bg_size[0]-screen_size[0], bg_x))
bg_y = max(0, min(bg_size[1]-screen_size[1], bg_y))
screen.blit(bg, (-bg_x, -bg_y))
pygame.display.flip()
How can I add a sprite when no keys are pressed? I have each four directions covered when the arrow keys are pressed but when they are released the sprite goes obviously but cant think of how to add it. I tried adding else statements and other things best thing i got was the standing forward sprite being underneath the others but cant seem to get it to go when one of the arrow keys is pressed and return when they are relased.
Any help appreciated. Thanks in advance.
my code:
import pygame
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)
# background
background = pygame.image.load('Playing Game state 2.png')
# character
standingforward = pygame.image.load('standingforward.png')
standingdownward = pygame.image.load('standingdownwards.png')
standingleft = pygame.image.load('standingleft.png')
standingright = pygame.image.load('standingright.png')
# player variables
x = 375
y = 525
w = 50
h = 50
vel = 0.5
screenWidth = 800
screenHeight = 575
screen = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption("FROGGER")
sprite = pygame.draw.rect
running = True
while running:
# sprites
screen.blit(background, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
screen.blit(standingleft, (x, y))
if keys[pygame.K_RIGHT]:
screen.blit(standingright, (x, y))
if keys[pygame.K_DOWN]:
screen.blit(standingdownward, (x, y))
if keys[pygame.K_UP]:
screen.blit(standingforward, (x, y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
# controls
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if x < 0:
x = 0
if keys[pygame.K_RIGHT]:
x += vel
if x > screenWidth-w:
x = screenWidth-w
if keys[pygame.K_UP]:
y -= vel
if y < 0:
y = 0
if keys[pygame.K_DOWN]:
y += vel
if y > screenHeight-h:
y = screenHeight-h
pygame.quit()
Add a variable that refers to the current image. Change the variable when a key is pressed. Draw the current image in the application loop:
current_image = standingright
running = True
while running:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
current_image = standingleft
if keys[pygame.K_RIGHT]:
current_image = standingright
if keys[pygame.K_DOWN]:
current_image = standingdownward
if keys[pygame.K_UP]:
current_image = standingforward
screen.blit(background, (0, 0))
screen.blit(current_image, (x, y))
# [...]
I am a Pygame beginner. I started to build a game on jumping dinosaur. The character I created doesn't come back to the exact platform after a single trigger press on UP arrow key. It lands slightly above the platform and its lands perfectly after 2,3 UP arrow presses.
I am a complete beginner.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 20
y = 400
width = 30
height = 45
vel = 10
black = (0,0,0)
x1 = 20
y1 = 30
white = (255,255,255)
run = True
while run:
pygame.time.delay(20)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x>=20:
x -= vel
if keys[pygame.K_RIGHT]and x<=450:
x += vel
if keys[pygame.K_UP] and y>=20:
y -= vel
if keys[pygame.K_DOWN] and y<=390:
y += vel
#gravity
else:
if not keys[pygame.K_UP] and y <= 400:
y += 30
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win,white,[0,472],[472,472],2)
pygame.display.update()
pygame.display.flip()
pygame.quit()
Your gravity application is broken. There is plenty of ways to fix this, my choice here is to always apply gravity but limit y so that it can never go bigger than the height of the character above the ground-plane.
To elaborate on what's actually wrong with your approach: your jumps create upwards motion incremented by vel. Which is only a fraction of gravity. So pushing the character up e.g. 40 pixels, and then pull it down by 30 pixels leaves you 10 pixels above ground. Only if you manage to precisely rise exactly a multiple of gravity, you will fall back.
My solution always falls down but then limits the position to the one where the character is right on the ground level.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 20
y = 400
width = 30
height = 45
black = (0,0,0)
x1 = 20
y1 = 30
white = (255,255,255)
bottom = 472
gravity = 30
vel = 10 + gravity
run = True
while run:
pygame.time.delay(20)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x>=20:
x -= vel
if keys[pygame.K_RIGHT]and x<=450:
x += vel
if keys[pygame.K_UP] and y>=20:
y -= vel
if keys[pygame.K_DOWN] and y<=390:
y += vel
else:
y = min(bottom - height, y + gravity)
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win,white,[0,bottom],[bottom,bottom],2)
pygame.display.update()
pygame.display.flip()
pygame.quit()
This is my Code:
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("Test")
x = 50
y = 50
width = 40
height = 60
vel =5
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0,0,0))
pygame.draw.rect(win, (255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
I would like the rectangle move continuously when you hold down one of the buttons but it only moves once per press.
I'm just starting to learn Python and Pygame (as you may see) so I'm thankful for any help.
What's happening here, is that you put the code to update the position in the event loop which means that your code ment to move the object is only run when pygame detects an event like a key press. But if you keep a key pressed down pygame does not register that as an event.
Simply remove all the code from keys = pygame.key... to display.update() from the for loop and put it in the while loop.
As such:
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0,0,0))
pygame.draw.rect(win, (255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
The object that needs to move will now move continuously as long as the keys are held down!