Blit function not working for displaying an image - python-3.x

I've currently been following along with a video over pygame and creating a space invaders type of game that I will modify for my own implementation of the game. However I've gotten to the section where you have to use the blit function in order to display an image for the background of the game and it's not working for me. Once the program is executed, the window is launched but without the image displayed for the background. I believe that I have properly loaded the image and stepped into the function that will use the blit function for displaying the background image as well. Please let me know if I have overlooked anything, any help will be greatly appreciated.
import pygame
import os
import time
import random
#Setting window frame
WIDTH, HEIGHT = 1000, 600
WINDOW = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Space Battle")
#Image Loading
RED_SPACESHIP = pygame.image.load(os.path.join("assets", "pixel_ship_red_small.png"))
GREEN_SPACESHIP = pygame.image.load(os.path.join("assets", "pixel_ship_green_small.png"))
BLUE_SPACESHIP = pygame.image.load(os.path.join("assets", "pixel_ship_blue_small.png"))
#Ship for player
YELLOW_SPACESHIP = pygame.image.load(os.path.join("assets", "pixel_ship_yellow.png"))
#Laser loading
YELLOW_LASER = pygame.image.load(os.path.join("assets", "pixel_laser_yellow.png"))
RED_LASER = pygame.image.load(os.path.join("assets", "pixel_laser_red.png"))
GREEN_LASER = pygame.image.load(os.path.join("assets", "pixel_laser_green.png"))
BLUE_LASER = pygame.image.load(os.path.join("assets", "pixel_laser_blue.png"))
Here is the code for loading in the back ground image
#Loading Backgrnd Img
BG = pygame.image.load(os.path.abspath("assets/background-black.png"))
formatedBG = pygame.transform.scale(BG, (WIDTH,HEIGHT))
Here is the code for the main function and handling background display.
def window_Redraw():
WINDOW.blit(formatedBG, (0,0))
pygame.display.update()
def main():
run = True
FPS = 60
clock = pygame.time.Clock()
while run:
clock.tick(FPS)
window_Redraw()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
main()
Here is a screenshot of the window after execution:
enter image description here

Your example is much more complicated that it should be. RED_SPACESHIP, BLUE_SPACESHIP... etc are irrelevant in this case and you should remove them.
You are displaying only a black background - nothing else, so it should be displayed. In order to check if everything is working, start from this example:
import pygame
# initialize the pygame module
pygame.init()
WIDTH, HEIGHT = 1000, 600
WINDOW = pygame.display.set_mode((WIDTH, HEIGHT))
formatedBG = pygame.Surface((WIDTH, HEIGHT))
formatedBG.fill(pygame.color.Color(255, 0, 0, 0))
# BG = pygame.image.load(os.path.abspath("assets/background-black.png"))
# formatedBG = pygame.transform.scale(BG, (WIDTH, HEIGHT))
run = True
while run:
WINDOW.blit(formatedBG, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
And then uncomment the background to check whether the background changed to black color.

My previous version of pygame which was 1.9.4 was causing my initial issues with displaying the background image using blit and the problem with the window not being able to display any color with the fill function. I solved these issues by running the command 'pip install==2.0.0.dev4' to upgrade pygame. Everything seems to be working properly now.

Related

How to prompt user to open a file with python3?

I'm making a game and I want the user to be able to click a button which opens the file manager and asks them to open a game save file. Is there a module / how could I put this in my game? If there's no good gui way how would I make a text input thing (without using the terminal)? Thanks!
Pygame is a low-level library, so it doesn't have the kind of built-in dialogs you're after. You can create such, but it will be quicker to use the tkinter module which is distributed with Python and provides an interface to the TK GUI libraries. I'd recommend reading the documentation, but here's a function that will pop up a file selection dialog and then return the path selected:
def prompt_file():
"""Create a Tk file dialog and cleanup when finished"""
top = tkinter.Tk()
top.withdraw() # hide window
file_name = tkinter.filedialog.askopenfilename(parent=top)
top.destroy()
return file_name
Here's a small example incorporating this function, pressing Spacebar will popup the dialog:
import tkinter
import tkinter.filedialog
import pygame
WIDTH = 640
HEIGHT = 480
FPS = 30
def prompt_file():
"""Create a Tk file dialog and cleanup when finished"""
top = tkinter.Tk()
top.withdraw() # hide window
file_name = tkinter.filedialog.askopenfilename(parent=top)
top.destroy()
return file_name
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
f = "<No File Selected>"
frames = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
f = prompt_file()
# draw surface - fill background
window.fill(pygame.color.Color("grey"))
## update title to show filename
pygame.display.set_caption(f"Frames: {frames:10}, File: {f}")
# show surface
pygame.display.update()
# limit frames
clock.tick(FPS)
frames += 1
pygame.quit()
Notes: This will pause your game loop, as indicated by the frame counter but as events are being handled by the window manager, this shouldn't be an issue.
I'm not sure why I needed the explicit import tkinter.filedialog, but I get an AttributeError if I don't.
As for string entry in pygame, you might want to do this natively, in which case you'd be handling KEYUP events for letter keys to build the string and perhaps finishing when the user presses Enter or your own drawn button. You could continue down the tk path, in which case you'll want to use something like tkinter.simpledialog.askstring(…)
It is possible to make a file dialogue (though not using the native file explorer) using the pygame_gui module.
Simply create an instance of UIFileDialog and grab the path when the user hits 'ok':
file_selection = UIFileDialog(rect=Rect(0, 0, 300, 300), manager=manager, initial_file_path='C:\\')
if event.ui_element == file_selection.ok_button:
file_path = file_selection.current_file_path
If you want to allow selecting a directory set allow_picking_directories to True, but note that it does not allow picking an initial_file_path.
file_selection = UIFileDialog(rect=Rect(0, 0, 300, 300), manager=manager, allow_picking_directories=True)
Here's the above code in a simple program that allows you to pick a file when the button is clicked:
#!/usr/bin/env python
import pygame
import pygame_gui
from pygame_gui.windows.ui_file_dialog import UIFileDialog
from pygame_gui.elements.ui_button import UIButton
from pygame.rect import Rect
pygame.init()
window_surface = pygame.display.set_mode((800, 600))
background = pygame.Surface((800, 600))
background.fill(pygame.Color('#000000'))
manager = pygame_gui.UIManager((800, 600))
clock = pygame.time.Clock()
file_selection_button = UIButton(relative_rect=Rect(350, 250, 100, 100),
manager=manager, text='Select File')
while 1:
time_delta = clock.tick(60) / 1000.0
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
if event.type == pygame.USEREVENT:
if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
if event.ui_element == file_selection_button:
file_selection = UIFileDialog(rect=Rect(0, 0, 300, 300), manager=manager, allow_picking_directories=True)
if event.ui_element == file_selection.ok_button:
print(file_selection.current_file_path)
manager.process_events(event)
manager.update(time_delta)
window_surface.blit(background, (0, 0))
manager.draw_ui(window_surface)
pygame.display.update()

How to use pygame and vlc with supervisor? [duplicate]

I'm having a problem. I want to load and play a video in pygame but it doesn't start. The only thing that I am seeing is a black screen. Here is my code:
import pygame
from pygame import display,movie
pygame.init()
screen = pygame.display.set_mode((1024, 768))
background = pygame.Surface((1024, 768))
screen.blit(background, (0, 0))
pygame.display.update()
movie = pygame.movie.Movie('C:\Python27\1.mpg')
mrect = pygame.Rect(0,0,140,113)
movie.set_display(screen, mrect.move(65, 150))
movie.set_volume(0)
movie.play()
Can you help me??
The pygame.movie module is deprecated and not longer supported.
If you only want to show the video you can use MoviePy (see also How to be efficient with MoviePy):
import pygame
import moviepy.editor
pygame.init()
video = moviepy.editor.VideoFileClip("video.mp4")
video.preview()
pygame.quit()
An alternative solution is to use the OpenCV VideoCapture. Install OpenCV for Python (cv2) (see opencv-python). However, it should be mentioned that cv2.VideoCapture does not provide a way to read the audio from the video file.
This is only a solution to show the video but no audio is played.
Opens a camera for video capturing:
video = cv2.VideoCapture("video.mp4")
Get the frames per second form the VideoCapture object:
fps = video.get(cv2.CAP_PROP_FPS)
Create a pygame.time.Clock:
clock = pygame.time.Clock()
Grabs a video frame and limit the frames per second in the application loop:
clock.tick(fps)
success, video_image = video.read()
Convert the camera frame to a pygame.Surface object using pygame.image.frombuffer:
video_surf = pygame.image.frombuffer(video_image.tobytes(), video_image.shape[1::-1], "BGR")
See also Video:
Minimal example:
import pygame
import cv2
video = cv2.VideoCapture("video.mp4")
success, video_image = video.read()
fps = video.get(cv2.CAP_PROP_FPS)
window = pygame.display.set_mode(video_image.shape[1::-1])
clock = pygame.time.Clock()
run = success
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
success, video_image = video.read()
if success:
video_surf = pygame.image.frombuffer(
video_image.tobytes(), video_image.shape[1::-1], "BGR")
else:
run = False
window.blit(video_surf, (0, 0))
pygame.display.flip()
pygame.quit()
exit()
You are not actually blitting it to a screen. You are also not utilizing a clock object so it will play as fast as possible. Try this:
# http://www.fileformat.info/format/mpeg/sample/index.dir
import pygame
FPS = 60
pygame.init()
clock = pygame.time.Clock()
movie = pygame.movie.Movie('MELT.MPG')
screen = pygame.display.set_mode(movie.get_size())
movie_screen = pygame.Surface(movie.get_size()).convert()
movie.set_display(movie_screen)
movie.play()
playing = True
while playing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
movie.stop()
playing = False
screen.blit(movie_screen,(0,0))
pygame.display.update()
clock.tick(FPS)
pygame.quit()
I just got that MELT.MPG from the link provided in the comment. You should be able to simply switch out that string for your actual MPG you want to play and it will work... maybe.
As you probably know, the pygame.movie module is deprecated and no longer exists in the latest version of pygame.
An alternative would be to read in frames of the video one by one and blit them onto the pygame screen using the the cv2 module (OpenCV), that can be installed with the command prompt command:
pip install opencv-python
Then, you can run the code:
import cv2
import pygame
cap = cv2.VideoCapture('video.mp4')
success, img = cap.read()
shape = img.shape[1::-1]
wn = pygame.display.set_mode(shape)
clock = pygame.time.Clock()
while success:
clock.tick(60)
success, img = cap.read()
for event in pygame.event.get():
if event.type == pygame.QUIT:
success = False
wn.blit(pygame.image.frombuffer(img.tobytes(), shape, "BGR"), (0, 0))
pygame.display.update()
pygame.quit()

name 'win' is not defined - pygame

I'm trying to implement some text into my game. I've followed a tutorial that has led me to this
pygame.font.init()
gamefont = pygame.font.SysFont('Bahnschrift', 16)
text = gamefont.render("Round: ", 1, (0,0,0))
win.blit(text, (390, 10))
However, when I run my code, it says that the name 'win' is not defined. I was wondering if anyone knew how to fix this?
win is the pygame.Surface object which is associated to the window.
Somewhere you have t o initialize pygame (pygame.init()) and to create the window Surface (pygame.display.set_mode):
Minimal applicaiton:
import pygame
# initializations
pygame.init()
win = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
# create font ad render text
pygame.font.init()
gamefont = pygame.font.SysFont('Bahnschrift', 16)
text = gamefont.render("Round: ", 1, (0,0,0))
# main application loop
run = True
while run:
clock.tick(60)
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# clear the display
win.fill((255, 255, 255))
# draw the text
win.blit(text, (390, 10))
# update the display
pygame.display.flip()

Image could not be opened through Pygame's Image.load()

My pygame program does not seems to load images. I tried image.load() by directly entering the image path as well by joining directories. I tried the code on Sublime Text as well as IDLE.
File Source: C:\Users\Aich\Documents\PythonProjects\Trial
Image Source: C:\Users\Aich\Desktop\Sprite1.png
(I've currently kept image and file in different locations but keeping them at same location did not yield anything)
I am using Windows 8.1.
import pygame
pygame.init()
white = (255, 255, 255)
x = 500
y = 400
display_surface = pygame.display.set_mode((x,y))
pygame.display.set_caption('Image')
image = pygame.image.load(r'C:\Users\Aich\Desktop\Sprite1.png').convert()
while True:
display_surface.fill(white)
display_surface.blit(image , (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.display.update()

pygame graphics grid

Hello, I am new to Python and graphics programming in general. At present I am messing around with creating grids as practice, and I am having problems with getting pygame to put objects on top of the surface window.
Below is my code with comments. I reckon that the problem may be to do with the blit function but I am unsure. Any help would be appreciated. Also, the Python shell does not highlight any exceptions or errors, but the program does not run.
import sys, random, pygame
from pygame.locals import *
def main():
#settings
boardDims = (20,20) #number of cells on board
#pygame settings
cellDims = (20,20) #number of pixels on cells
framerate = 50
colours = {0:(0,0,0), 1:(255,255,255)}
#pygame
pygame.init()
#sets x and y pixels for the window
dims = (boardDims[0] * cellDims[0],
boardDims[1] * cellDims[1])
#sets window, background, and framrate
screen = pygame.display.set_mode(dims)
background = screen.convert()
clock = pygame.time.Clock()
#create new board
board = {}
#iterates over x and y axis of the window
for x in range(boardDims[0]):
for y in range(boardDims[1]):
board[(x,y)] = 0 #sets whole board to value 0
board[(1,1)] = 1 #sets one square at co-ordinates x=1,y=1 to cell
# value 1
return board
running = 1
while running:
# 1 PYGAME
#get input
for event in pygame.event.get():
if event.type == QUIT or \
(event.type == KEYDOWN and event.key == K_ESCAPE):
running = 0
return
#link pygames clock to set framerate
clock.tick(framerate)
for cell in board:
#adds cells dimensions and co-ordinates to object rectangle
rectangle = (cell[0]*cellDims[0], cell[1]* cellDims[1],
cellDims[0], cellDims[1])
#pygame draws the rectabgle on the background using the relevant
#colour and dimensions and co-ordinates outlined in 'rectangle'
square = pygame.draw.rect(background, colours[board[cell]],
rectangle)
#blits and displays object on the background
background.blit(square)
screen.blit(background, (0,0))
pygame.display.flip()
if __name__ == "__main__":
main()
The "return board" statement is exiting your program before any blitting is done.
Also, you can blit the squares directly on the screen variable, ie: you don't need the background variable.

Resources