I am relatively new in python and started coding in pygame. For some reason, when I am rendering some images on a surface, it doesn't blit the images. But when I minimize it and then open it again, it works fine. Is there any fix to this problem? Thanks in adavance.
Non-fullscreen error: https://youtu.be/q_2FT8OD7O4
Fullscreen error: https://youtu.be/9XKnhtN5s5k
My code, just in case if something's wrong in it:
import pygame
displayWidth = 1920
displayHeight = 1080
pygame.init()
gameDisplay = pygame.display.set_mode((displayWidth,displayHeight),pygame.FULLSCREEN)
pygame.display.set_caption('Road Fighters')
clock = pygame.time.Clock()
car = pygame.image.load('Car.png')
grassLeft = pygame.image.load('Grass Left.png')
grassRight = pygame.image.load('Grass Right.png')
blank = pygame.image.load('Left.png')
lining = pygame.image.load('Lining.png')
miniMap = pygame.image.load('Progress.png')
miniCar = pygame.image.load('Small Car.png')
road = pygame.image.load('Road.png')
def car(x,y):
gameDisplay.blit(car, (x,y))
def draw():
gameDisplay.blit(blank,(0,0))
gameDisplay.blit(miniMap,(670,0))
gameDisplay.blit(grassLeft,(720,0))
gameDisplay.blit(lining,(1020,0))
gameDisplay.blit(road,(1030,0))
gameDisplay.blit(lining,(1610,0))
gameDisplay.blit(grassRight,(1620,0))
def gameloop():
while True:
for event in pygame.event.get():
## if event.type == 2 or event.type == 12:
## pygame.quit()
## quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT: dx = -3
elif event.key == pygame.K_RIGHT: dx = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT: dx += 3
elif event.key == pygame.K_RIGHT: dx += -3
draw()
gameloop()
You need to add a pygame.display.flip() to your game loop.
Related
I am new to Python and especially new to Pygame. Been working on a basic space invader type game to attempt to learn more about Pygame, but I cannot figure out the code for moving the user ship. Have looked up some tutorials on it, and I THINK my code looks good, but I might be looking over something. I am in Python version 3.8 and Pygame version 1.9.6.
'''
This script is creating a space invader type game with the Pygame module.
Tutorial following YT video from freecodecamp.org
(https://www.youtube.com/watch?v=FfWpgLFMI7w&ab_channel=freeCodeCamp.org)
'''
import sys
import pygame
# Initializing Pygame
# (ALWAYS REQUIRED)
pygame.init()
# Screen Dimensions
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
# Other Game Settings
framerate = pygame.time.Clock()
framerate.tick(60)
# Setting Title and Images
pygame.display.set_caption('Space Invaders')
icon = pygame.image.load('spaceship.png')
pygame.display.set_icon(icon)
player_ship = pygame.image.load('space-invaders.png')
def player(x,y):
'''
Draws the player's ship on the screen at (x,y) coordinates.
'''
screen.blit(player_ship,(x, y))
# Game Function
def game():
'''
Actual code for the game itself.
'''
# Sets the starting position for the player's ship
playerX = 368 # Middle of Screen (on x-axis)
playerY = 506 # 30px off bottom of the screen (y-axis)
x_change = 0
# Game Loop
game_exit = False
while not game_exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_ESCAPE:
game_exit = True
elif event.type == pygame.K_d:
x_change = 5
elif event.type == pygame.K_a:
x_change = -5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
x_change = 0
playerX += x_change
print(x_change) # Using this to see if the script is recognizing the user keystrokes
# Setting Screen RGB
screen.fill((0,0,0))
player(playerX, playerY)
# Screen Update
# (ALWAYS REQUIRED)
pygame.display.update()
game()
pygame.quit()
sys.exit()
Thanks for your help!
The issue is you're checking for an event.type of pygame.K_d, etc.
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_ESCAPE: # <-- HERE
game_exit = True
elif event.type == pygame.K_d: # <-- HERE
x_change = 5
elif event.type == pygame.K_a: # <-- AND HERE
x_change = -5
The event.type cannot be equal to both pygame.KEYDOWN and pygame.K_d at the same time!. If you check the documentation on event, notice that the key-code is sent in event.key, so it's a simple fix.
KEYDOWN key, mod, unicode, scancode
KEYUP key, mod
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: # <-- FIX HERE
game_exit = True
elif event.key == pygame.K_d: # <-- FIX HERE
x_change = 5
elif event.key == pygame.K_a: # <-- AND FIX HERE
x_change = -5
I've been following a tutorial from here to build a small python game.
This would be the code behind it:
import pygame
pygame.init()
display_width = 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Racing Game")
clock = pygame.time.Clock()
black = (0,0,0)
white = (255,255,255)
carImg = pygame.image.load("racecar.png")
def car(x,y):
gameDisplay.blit(carImg, (x,y))
x = display_width * 0.45
y = display_height * 0.8
x_change = 0
car_speed = 0
crashed = True
while crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = False
## <code to remove>
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type = pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
## </code to remove>
print(event)
x += x_change
gameDisplay.fill((255,255,255))
car(x,y)
pygame.display.update()
clock.tick(60)
pygame.display.quit()
pygame.quit()
quit()
When I try to run it the window opens and immediately closes. If I remove however the code between the two ## <code to remove> and ## </code to remove> everything works fine. What is causing in that piece of code for this to happen?
This is caused by the syntax error at if event.type = pygame.KEYUP:. Opening the file will cause it to close instantly, but running it in the interpreter (IDLE) will show you that error. Just change it to if event.type == pygame.KEYUP: and everything will work fine.
UPDATE:
Running code from the file rather than the interpreter (IDLE) won't always open. It is best to run it in IDLE.
Code:
import pygame
pygame.init()
display_width = 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Racing Game")
clock = pygame.time.Clock()
black = (0,0,0)
white = (255,255,255)
carImg = pygame.image.load("racecar.png")
def car(x,y):
gameDisplay.blit(carImg, (x,y))
x = display_width * 0.45
y = display_height * 0.8
x_change = 0
car_speed = 0
crashed = True
while crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = False
#############################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
#############################
print(event)
x += x_change
gameDisplay.fill((255,255,255))
car(x,y)
pygame.display.update()
clock.tick(60)
pygame.display.quit()
pygame.quit()
quit()
I have the game come up and the rectangle rendered.
When I press my KEYDOWN it doesn't move the rectangle, it just makes it longer.
I have tried tons of stuff. I am new to Pygame.
Any help would be amazing.
Here is the code:
import pygame
import time
import random
import math
import sys
pygame.init()
display_width = 1200
display_height = 800
white = (255,255,255)
black = (0,0,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Vertical Pong')
clock = pygame.time.Clock()
def pongBoard(x,y,):
pygame.draw.rect(gameDisplay,white,(x,y,250,25))
def gameLoop():
x = 325
y = 750
xChange = 0
inGame = True
while inGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
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
pongBoard(x,y)
x += xChange
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
So the problem is this:
The rectangle is being constantly redrawn at a different coord, but the screen is not being drawn over the rectangle to cover up the part that is not supposed to be there. In simpler terms, we need to constantly draw the background.
So now the code in the main game loop:
while inGame:
#This code below draws the background
pygame.draw.rect(gameDisplay, black, (0, 0, display_width, display_height))
That is it! The background will constantly cover up the pong ball, and the pong ball will be constantly blitted to a new position!
P.S, there is a better way to do arrow key movement here: How to get keyboard input in pygame?
it actualy does move it, but the old one just stays there, making it look like it does not move but just grows. one way to change that would be to change the old ones color to the background color
try this code it works :-)
import pygame
import time
import random
import math
import sys
pygame.init()
display_width = 1200
display_height = 800
white = (255,255,255)
black = (0,0,0)
red = (123,11,45)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Vertical Pong')
clock = pygame.time.Clock()
def pongBoard(x,y,xold):
pygame.draw.rect(gameDisplay,white,[x,y,250,25])
pygame.draw.rect(gameDisplay,red,[xold,y,250,25])
def gameLoop():
x = 325
y = 750
xChange = 0
inGame = True
while inGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
xChange = -50
pongBoard(x,y,xold)
print("Left")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 50
pongBoard(x,y,xold)
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
xold = x
x += xChange
xold = x-xChange
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
I am messing around with pygame and I am eventually working towards a pong clone. I implemented player movement with the arrow keys and when ever I switch from going up to immediately going down, my player freezes and won't move again until I press that direction key again. Here is my code:
import sys, pygame
pygame.init()
display_width = 640
display_height = 480
display = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Test Game")
black = (0,0,0)
white = (255,255,255)
clock = pygame.time.Clock()
running = True
class Player:
def __init__(self,x,y,hspd,vspd,color,screen):
self.x = x
self.y = y
self.hspd = hspd
self.vspd = vspd
self.color = color
self.screen = screen
def draw(self):
pygame.draw.rect(self.screen,self.color,(self.x,self.y,32,32))
def move(self):
self.x += self.hspd
self.y += self.vspd
player = Player(0,0,0,0,black,display)
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.hspd = 0
if event.key == pygame.K_LEFT:
player.hspd = 0
if event.key == pygame.K_UP:
player.vspd = 0
if event.key == pygame.K_DOWN:
player.vspd = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.hspd = 4
if event.key == pygame.K_LEFT:
player.hspd = -4
if event.key == pygame.K_UP:
player.vspd = -4
if event.key == pygame.K_DOWN:
player.vspd = 4
#Clear the screen
display.fill(white)
#Move objects
player.move()
#Draw objects
player.draw()
#Update the screen
pygame.display.flip()
print "I made it!"
pygame.quit()
sys.exit()
I suggest you work with key.get_pressed() to check for the current set of pressed keys.
In your scenario - when you press down and release up (in that order) - the speed is set to 0, so you need to inspect the keys pressed not just by the current event.
Here is a working version of the relevant part:
def current_speed():
# uses the fact that true = 1 and false = 0
currently_pressed = pygame.key.get_pressed()
hdir = currently_pressed[pygame.K_RIGHT] - currently_pressed[pygame.K_LEFT]
vdir = currently_pressed[pygame.K_DOWN] - currently_pressed[pygame.K_UP]
return hdir * 4, vdir * 4
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.hspd, player.vspd = current_speed()
#Clear the screen
display.fill(white)
#Move objects
player.move()
#Draw objects
player.draw()
#Update the screen
pygame.display.flip()
To expand on LPK's answer, your key down (for event.key == pygame.K_DOWN) is likely being processed before your key up (from event.key == pygame.K_UP) is processed. So while both are down (and you can confirm this), you may experience movement, until you release the up key.
your problem is here:
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.hspd = 0
if event.key == pygame.K_LEFT:
player.hspd = 0
if event.key == pygame.K_UP:
player.vspd = 0
if event.key == pygame.K_DOWN:
player.vspd = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.hspd = 4
if event.key == pygame.K_LEFT:
player.hspd = -4
if event.key == pygame.K_UP:
player.vspd = -4
if event.key == pygame.K_DOWN:
player.vspd = 4
I am guessing that your key event down is still consumed when u switch the keys immediately, meaning no other key down event is getting triggered as long as the first event didn't fire its key up event yet.
EDIT: maybe its better to check if the player is moving and if so just reverse speed . Then you would only need to check the down event.
Otherwise your event will be consumed and not checked properly.
For your method you would need to store the occurred key events since the last frame and check that list.
I did a bit of research to see if i could solve the issue that way, but didn't seem to find anything to solve my problem. I found both of these : Why isn't my pygame display displaying anything? and Confused at why PyGame display's a black screen. I tried to solve my problem with what was adviced in the comments but it didn't work, or the reason for the problem was different than mine.
When i run the code the pygame window shows, but is just completely black, but no errors are called.
so here is the code (might be a bit long).
import pygame
import time
import random
pygame.init()
display_width = 700
display_height = 900
player_width = 140
player_height = 100
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Baby shower')
clock = pygame.time.Clock()
greenkidimg = pygame.image.load('kid green.png')
bluekidimg = pygame.image.load('kid blue.png')
redkidimg = pygame.image.load('kid red.png')
catcherimg = pygame.image.load('catcher.png')
background = pygame.image.load('background.png')
#image loads
def player(x,y):
gameDisplay.blit(catcherimg,(x,y))
def bluekid(bluex, bluey, bluew, blueh):
gameDisplay.blit(bluekidimg, (bluex, bluey))
def redkid(redx, redy, redw, redh):
gameDisplay.blit(redkidimg, (redx,redy))
def greenkid(greenx, greeny, greenw, greenh):
gameDisplay.blit(greenkidimg(greenx, greeny))
def game_loop():
x = (display_width*0.45)
y = (display_height*0.8)
x_change = 0
blue_width = 66
bluex_start = random.randrange (0, display_width-blue_width)
bluey_start = -600
blue_speed = 15
blue_height = 78
green_width = 66
greenx_start = random.randrange (0, display_width-green_width)
greeny_start = -600
green_speed = 15
green_height = 78
red_width = 66
redx_start = random.randrange (0, display_width-red_width)
redy_start = -600
red_speed = 15
red_heigth = 78
#greenkid,redkid,bluekid-start,speed,h/w
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -20
elif event.type == pygame.K_RIGHT:
x_change = 20
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.blit(background(0,0))
player(x,y)
bluekid(bluex, bluey, bluew, blueh)
redkid(redx, redy, redw, redh)
greenkid(greenx, greeny, greenw, greenh)
#display
pygame.display.update()
clock.tick(30)
game_loop()
pygame.quit()
quit()
The rendering logic in the game loop just needs to be indented to it is a part of the while loop inside it, like this:
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -20
elif event.type == pygame.K_RIGHT:
x_change = 20
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.blit(background(0,0))
player(x,y)
bluekid(bluex, bluey, bluew, blueh)
redkid(redx, redy, redw, redh)
greenkid(greenx, greeny, greenw, greenh)
pygame.display.update()
clock.tick(30)