display issue with pygame in python3 - python

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.

Related

Trying to move image around screen, but "animation" is choppy

If I hit a key it won't show the new position until I let off it. It almost teleports to the new spot instead of seeing it move to it. I previously made a square to move around with no issue. Tried looking at that code and doing the something but I'm missing something.
import pygame
import sys
pygame.init()
window = 900, 700
screen = pygame.display.set_mode(window)
title = pygame.display.set_caption("ASTEROOOIDDD")
clock = pygame.time.Clock()
x = 340
y = 280
step = 1
background_surface = pygame.image.load('asteroid/images/background.jpg')
spaceship_surface = pygame.image.load('asteroid/images/ship.png')
spaceship_surface = pygame.transform.scale(spaceship_surface, (80,80))
while True:
for eve in pygame.event.get():
if eve.type==pygame.QUIT:
pygame.quit()
sys.exit()
screen.blit(background_surface,(0,0))
screen.blit(spaceship_surface,(x,y))
key_input = pygame.key.get_pressed()
if key_input[pygame.K_LEFT]:
x -= step
if key_input[pygame.K_UP]:
y -= step
if key_input[pygame.K_RIGHT]:
x += step
if key_input[pygame.K_DOWN]:
y += step
spaceship_surface.blit(spaceship_surface, (x,y))
pygame.display.update()
clock.tick(30)
It is a matter of Indentation. The display needs to be updated in every frame. (At least in every frame where something changes). 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()
import pygame
import sys
pygame.init()
window = 900, 700
screen = pygame.display.set_mode(window)
title = pygame.display.set_caption("ASTEROOOIDDD")
clock = pygame.time.Clock()
x = 340
y = 280
step = 1
background_surface = pygame.image.load('asteroid/images/background.jpg')
spaceship_surface = pygame.image.load('asteroid/images/ship.png')
spaceship_surface = pygame.transform.scale(spaceship_surface, (80,80))
while True:
for eve in pygame.event.get():
if eve.type==pygame.QUIT:
pygame.quit()
sys.exit()
# INDENTATION
#<--|
screen.blit(background_surface,(0,0))
screen.blit(spaceship_surface,(x,y))
key_input = pygame.key.get_pressed()
if key_input[pygame.K_LEFT]:
x -= step
if key_input[pygame.K_UP]:
y -= step
if key_input[pygame.K_RIGHT]:
x += step
if key_input[pygame.K_DOWN]:
y += step
spaceship_surface.blit(spaceship_surface, (x,y))
pygame.display.update()
clock.tick(30)
You just need to bring your screen.blit outside the event handler loop.
while True:
for eve in pygame.event.get():
if eve.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.blit(background_surface, (0, 0))
screen.blit(spaceship_surface, (x, y))
key_input = pygame.key.get_pressed()
if key_input[pygame.K_LEFT]:
x -= step
if key_input[pygame.K_UP]:
y -= step
if key_input[pygame.K_RIGHT]:
x += step
if key_input[pygame.K_DOWN]:
y += step
spaceship_surface.blit(spaceship_surface, (x, y))
pygame.display.update()
clock.tick(30)

Stop an object from glitching in pygame

I am trying to make a game like pong using pygame I currently have the two rectangles however one glitches I dont know why, I commented win.fill((0, 0, 0)) and it stops one of the rectangles from glitching but the other one does not this is what I have:
# import pygame module in this program
import pygame
# activate the pygame library .
# initiate pygame and give permission
# to use pygame's functionality.
pygame.init()
# create the display surface object
# of specific dimension..e(500, 500).
win = pygame.display.set_mode((1280, 720))
# set the pygame window name
pygame.display.set_caption("Pong")
# object1 current co-ordinates
x = 15
y = 280
# object2 current co-ordinates
x1 = 1245
y1 = 280
# dimensions of the object1
width = 20
height = 130
# dimensions of the object2
width1 = 20
height1 = 130
# velocity / speed of movement
vel = 10
# Indicates pygame is running
run = True
# infinite loop
while run:
# creates time delay of 10ms
pygame.time.delay(0)
# iterate over the list of Event objects
# that was returned by pygame.event.get() method.
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both.
if event.type == pygame.QUIT:
# it will make exit the while loop
run = False
# stores keys pressed
keys = pygame.key.get_pressed()
# if left arrow key is pressed
if keys[pygame.K_w] and y > 0:
# decrement in y co-ordinate
y -= vel
# if left arrow key is pressed
if keys[pygame.K_s] and y < 720-height:
# increment in y co-ordinate
y += vel
# completely fill the surface object
# with black colour
win.fill((0, 0, 0))
# drawing object on screen which is rectangle here
pygame.draw.rect(win, (0, 0, 255), (x, y, width, height))
# it refreshes the window
pygame.display.update()
keys2 = pygame.key.get_pressed()
# if left arrow key is pressed
if keys2[pygame.K_UP] and y1 > 0:
# decrement in y co-ordinate
y1 -= vel
# if left arrow key is pressed
if keys2[pygame.K_DOWN] and y1 < 720-height:
# increment in y co-ordinate
y1 += vel
# completely fill the surface object
# with black colour
win.fill((0, 0, 0))
# drawing object on screen which is rectangle here
pygame.draw.rect(win, (255, 255, 255), (x1, y1, width1, height1))
# it refreshes the window
pygame.display.update()
# closes the pygame window
pygame.quit()
Call pygame.disaply.update() only once at the end of the application loop. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering. See Why is the PyGame animation is flickering. Also clear the display only once per frame.
You are actually drawing on a Surface object. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visible, when the display is updated with either pygame.display.update() or pygame.display.flip().
If you clear the display, all previously drawn elements become invisible. Therefore, clear the display once at the beginning of the frame and update it once at the end of the frame.
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()
clock = pygame.time.Clock()
run = True
# application loop
while run:
# limit the frames per second to limit CPU usage
clock.tick(100)
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# update the game states and positions of objects
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and y > 0:
y -= vel
if keys[pygame.K_s] and y < 720-height:
y += vel
if keys[pygame.K_UP] and y1 > 0:
y1 -= vel
if keys[pygame.K_DOWN] and y1 < 720-height:
y1 += vel
# clear the display
win.fill((0, 0, 0))
# draw the entire scene
pygame.draw.rect(win, (0, 0, 255), (x, y, width, height))
pygame.draw.rect(win, (255, 255, 255), (x1, y1, width1, height1))
# update the display
pygame.display.update()

Pygame player movement is being weird

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.

pygame movement speed is not constant [duplicate]

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()

How to change direction of a circle in pygame when hitting a "wall"

I'd like to know how to change directions of a square when it hits a "wall" with pygame. Below is my code:
"""
Date: Nov 4, 2020
Description: Animating Shapes with pygame
"""
import pygame
def main():
'''This function defines the 'mainline logic' for our game.'''
# I - INITIALIZE
pygame.init()
# DISPLAY
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Crazy Shapes Animation")
# ENTITIES
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255, 255, 255)) # white background
# Make a red 25 x 25 box
red_box = pygame.Surface((25, 25))
red_box = red_box.convert()
red_box.fill((255, 0, 0))
# A - ACTION (broken into ALTER steps)
# ASSIGN
clock = pygame.time.Clock()
keepGoing = True
red_box_x = 0 # Assign starting (x,y)
red_box_y = 200 # for our red box
# LOOP
while keepGoing:
# TIMER
clock.tick(30)
# EVENT HANDLING
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
# change x coordinate of box
red_box_x += 5
# check boundaries, to reset box to left-side
if red_box_x > screen.get_width():
red_box_x = 0
# REFRESH (update window)
screen.blit(background, (0, 0))
screen.blit(red_box, (red_box_x, red_box_y)) # blit box at new (x,y) location
pygame.display.flip()
# Close the game window
pygame.quit()
# Call the main function
main()
When it hits the far right wall, I want it to reverse direction and go back towards the far left wall. Then it continues hitting the walls infinitely. This is kind of for a school assignment, and I couldn't find any solutions online, so it'd be great if you could help me out!
Use a variable for the movement (move_x) instead of the constant. Invert the value of the variable (move_x *= -1) when the object hits a wall:
def main():
# [...]
move_x = 5
# LOOP
while keepGoing:
# [...]
# change x coordinate of box
red_box_x += move_x
# check boundaries, to reset box to left-side
if red_box_x >= screen.get_width():
red_box_x = screen.get_width()
move_x *= -1
if red_box_x <= 0:
red_box_x = 0
move_x *= -1
# [...]

Categories

Resources