This question already has answers here:
Pygame clock and event loops
(1 answer)
Framerate affect the speed of the game
(1 answer)
Closed last year.
I recently started with pygame and im trying to create movement but when I move my rectangle the speed changes at various times. it becomes slower and faster at various times
import pygame
pygame.init() # inisializing pygame
WIN = pygame.display.set_mode((500, 500)) # the width and hieght of the window
pygame.display.set_caption('pygame tutorial') # give the window a title
x = 50
y = 50 # character x and y positions
width = 40
height = 60 # rectangle width and height
vel = 5 # velocity (speed)
run = True # boolean variable
while run: # forever loop
for event in pygame.event.get(): # specifing the event
if event.type == pygame.QUIT: # pygame.QUIT makes the red x work so you can close the window
run = False # run = false so the while loop stops
key = pygame.key.get_pressed()
if key [pygame.K_a]:
x -= vel
if key[pygame.K_d]:
x += vel
if key[pygame.K_w]:
y -= vel
if key[pygame.K_s]:
y += vel
WIN.fill((0,0,0))
pygame.draw.rect(WIN, (255, 0, 0), (x, y, width, height))
'''
create a rectangle with 3 arguements, the window, the rgb colour, and the x,y positions width and height
'''
pygame.display.update()
pygame.quit()
You have wrong indentations so some code is executed inside many times in for-loop but it should be executed only once after for-loop
After changing indentations code work too fast and I needed to add clock.tick(60) to reduce speed to max 60 frames per second. This way it should run with the same speed on computers with older and newer CPU.
WIN = pygame.display.set_mode((500, 500)) # the width and hieght of the window
pygame.display.set_caption('pygame tutorial') # give the window a title
x = 50
y = 50 # character x and y positions
width = 40
height = 60 # rectangle width and height
vel = 5 # velocity (speed)
run = True # boolean variable
clock = pygame.time.Clock()
while run: # forever loop
for event in pygame.event.get(): # specifying the event
if event.type == pygame.QUIT: # pygame.QUIT makes the red x work so you can close the window
run = False # run = false so the while loop stops
# --- after loop --
key = pygame.key.get_pressed()
if key [pygame.K_a]:
x -= vel
if key[pygame.K_d]:
x += vel
if key[pygame.K_w]:
y -= vel
if key[pygame.K_s]:
y += vel
WIN.fill((0,0,0))
pygame.draw.rect(WIN, (255, 0, 0), (x, y, width, height))
'''
create a rectangle with 3 arguments, the window, the rgb colour, and the x,y positions width and height
'''
pygame.display.update()
clock.tick(60) # reduce speed to max 60 frames per seconds
pygame.quit()
Related
This question already has answers here:
Setting up an invisible boundary for my sprite
(1 answer)
Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area
(1 answer)
How to make ball bounce off wall with PyGame?
(1 answer)
Not letting the character move out of the window
(2 answers)
Closed 10 months ago.
I just started trying out pygame, so I watched a tutorial. When the guy showed, how to create edges left and right from the screen, it just didn't work when I did it, even though I've written it 100% equal as the tutorial guy. The tutorial is already two years old, so maybe pygame just has changed. Can somebody help me?
That's my code:
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.draw.rect(screen, (0,0,0), (-2,0,2,600), 0)
right_wall = pygame.draw.rect(screen, (0,0,0), (1201,0,2,600), 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if presses[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if pressed[pygame.K_RIGHT] or pressed[pygame.K_d] and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if pressed[pygame.K_LEFT] or pressed[pygame.K_a] and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)
The following code works for me after replacing the background.png path with a picture that exists on my computer. I changed left_wall and right_wall to call pygame.Rect instead of pygame.draw.rect and copied the draw.rect calls that were previously assigned to left_wall and right_wall to draw() function, and added some needed parentheses in two of the if statements. Also fixed a typo where pressed was spelled presses.
Without the parentheses, the character would always move right when right key is pressed even past the right edge of the window. When "d" is pressed, it would check against colliderect. Same for left arrow and "a" keys. or short-circuits, so if K_RIGHT or K_LEFT is pressed, it doesn't check the right hand side of the or in the if statements. With the parentheses added, the "move right" if statement always checks colliderect when K_RIGHT or K_d is pressed, instead of only when K_d is pressed.
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.draw.rect(screen, (0,0,0), left_wall, 0)
pygame.draw.rect(screen, (0,0,0), right_wall, 0)
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.Rect(-2,0,2,600)
right_wall = pygame.Rect(1201,0,2,600)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if (pressed[pygame.K_RIGHT] or pressed[pygame.K_d]) and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if (pressed[pygame.K_LEFT] or pressed[pygame.K_a]) and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)
I was making a pygame project and i made a square move and It would summon a square every frame and there would just be a line of squares.
I tried to update the screen every frame (Because i hadn't yet), but that did not work. Here is my code:
#Import Pygame
import pygame
#screen object(width, height)
screen_x = 750
screen_y = 600
screen = pygame.display.set_mode((screen_x, screen_y))
#Set the caption of the screen
pygame.display.set_caption('Game')
#Define a velocity, x, and y variable
velocity = 2.5x = 0.0y = 0.0
#Variable to keep our game loop running
running = True
#Game loop
while running:
# Initialing Color
color = (255,0,0)
if pygame.key.get_pressed()[pygame.K_w]:
y += 2.5
if pygame.key.get_pressed()[pygame.K_s]:
y -= 2.5
if pygame.key.get_pressed()[pygame.K_a]:
x -= 2.5
if pygame.key.get_pressed()[pygame.K_d]:
x += 2.5
# Drawing Rectangle
pygame.draw.rect(screen, color, pygame.Rect(x, y, 50, 50))
pygame.display.flip()
pygame.display.update()
# for loop through the event queue
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
The entire scene is redrawn in every frame, therefore you have to clear the display in every frame:
import pygame
#screen object(width, height)
screen_x = 750
screen_y = 600
screen = pygame.display.set_mode((screen_x, screen_y))
#Set the caption of the screen
pygame.display.set_caption('Game')
#Define a velocity, x, and y variable
velocity = 2.5
x, y = 0, 0
color = (255,0,0)
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
# for loop through the event queue
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
x += (keys[pygame.K_d] - keys[pygame.K_a]) * velocity
y += (keys[pygame.K_s] - keys[pygame.K_w]) * velocity
# clear display
screen.fill((0, 0, 0))
# Drawing Rectangle
pygame.draw.rect(screen, color, pygame.Rect(x, y, 50, 50))
# update display
pygame.display.flip()
pygame.quit()
exit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
The solution is very simple. You forgot to fill the screen with a color. Because your code just draw's a square to the screen surface every frame, and that's why it's drawing a line of squares. You have to fill the screen before drawing the things, because otherwise you will see an empty screen with that color, that you filled the surface with. Hope it helped.
This is the output of my code. I can't figure out how to fix this issue.
This code is showing weird lines in the window created using Pygame.
I was learning about using arrow keys in Pygame and con not get rid of this glich in the window.
The code that I made changes to is on geeks for geeks here : https://www.geeksforgeeks.org/python-drawing-design-using-arrow-keys-in-pygame/
This works just fine but when I use a different sized window and a different shape to draw it shows the weird lines in the window.
import pygame
import tkinter
pygame.init()
# create the display surfce object of specific dimensions (1000x1000).
win = pygame.display.set_mode((500, 500))
# Setting the window name
pygame.display.set_caption("Dungen World")
# Current coordinates
x = 250
y = 250
# dimensions of the player
width = 10
height = 10
# Speed of movement
vel = 2.5
# Indicator that pygame is running
running = True
# Main game loop
while running:
# Time delay(milliseconds)
pygame.time.delay(10)
# Iterate over the list of event objects
# that was returned by the pygame.event.get()
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both
if event.type == pygame.QUIT:
# This will exit the while loop
running = False
# Stores the key pressed
keys = pygame.key.get_pressed()
# If left arrow key is pressed
if keys[pygame.K_LEFT] and x > 5:
# Decrement in x coordinates
x -= vel
# If left arrow key is pressed
if keys[pygame.K_RIGHT] and x < 500 - width:
# Decrement in x coordinates
x += vel
# If left arrow key is pressed
if keys[pygame.K_UP] and y > 5:
# Decrement in x coordinates
y -= vel
# If left arrow key is pressed
if keys[pygame.K_DOWN] and y < 500 - height:
# Decrement in x coordinates
y += vel
# drawing the square on screen
pygame.draw.circle(win, (255, 255, 255), (x, y), width/2)
# To refresh the window
pygame.display.update()
# Closes the pygame window
pygame.quit()
Add win.fill((0, 0, 0)) (or whatever background color you want) at the beginning of your game loop. For some reason, macOS freaks out if the background doesn't have a color.
Your code should look like this:
import pygame
import tkinter
pygame.init()
# create the display surfce object of specific dimensions (1000x1000).
win = pygame.display.set_mode((500, 500))
# Setting the window name
pygame.display.set_caption("Dungen World")
# Current coordinates
x = 250
y = 250
# dimensions of the player
width = 10
height = 10
# Speed of movement
vel = 2.5
# Indicator that pygame is running
running = True
# Main game loop
while running:
# Time delay(milliseconds)
pygame.time.delay(10)
# Fill entire window with black
win.fill((0, 0, 0))
# Iterate over the list of event objects
# that was returned by the pygame.event.get()
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both
if event.type == pygame.QUIT:
# This will exit the while loop
running = False
# Stores the key pressed
keys = pygame.key.get_pressed()
# If left arrow key is pressed
if keys[pygame.K_LEFT] and x > 5:
# Decrement in x coordinates
x -= vel
# If left arrow key is pressed
if keys[pygame.K_RIGHT] and x < 500 - width:
# Decrement in x coordinates
x += vel
# If left arrow key is pressed
if keys[pygame.K_UP] and y > 5:
# Decrement in x coordinates
y -= vel
# If left arrow key is pressed
if keys[pygame.K_DOWN] and y < 500 - height:
# Decrement in x coordinates
y += vel
# drawing the square on screen
pygame.draw.circle(win, (255, 255, 255), (x, y), width/2)
# To refresh the window
pygame.display.update()
# Closes the pygame window
pygame.quit()
Edit:
Without this piece of code, the player doesn't actually "move" and acts more like a drawing app than a game.
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()
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()