Images not showing on surface in pygame - python

I am attempting to make a game with two surfaces. However when I try and add an image to the game layer it doesn't show up. I have tried using pygame.display.flip() which, from what I understand, should update everything on the screen.
If I try to use either Game_Layer.update() or Game_Layer.flip() as seen in the code below... (I think Game_Layer.flip() doesn't work because .flip is used to update the entire screen and thus can't be called for specific layers but correct me if I am wrong).
#game play
def Dragon():
DragonIMG=pygame.image.load("Green Dragon.gif")
DragonIMG.convert()
global Game_Layer
x=0
y=0
Game_Layer.blit(DragonIMG,(x,y))
Game_Layer.update()
Dragon()
I get the following error message:
RESTART: C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py
Traceback (most recent call last):
File "C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py", line 133, in <module>
Dragon()
File "C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py", line 131, in Dragon
Game_Layer.update()
AttributeError: 'pygame.Surface' object has no attribute 'update'
>>>
However when I try to display an image on the root layer using the code below it works.
#game play
def Dragon():
DragonIMG=pygame.image.load("Green Dragon.gif")
DragonIMG.convert()
global Base_Layer
x=0
y=0
Base_Layer.blit(DragonIMG,(x,y))
pygame.display.flip()
Dragon()
Below is the code I am using to set up the layers:
#libraries
import time, random, pygame, sqlite3, GIFimage2
pygame.init()
#screen setup
#variables
clock=pygame.time.Clock() #for use in .tick
black=pygame.color.Color("black") #set black
white=pygame.color.Color("white") #set white
#set up the base layer
Base_Layer=pygame.display.set_mode((1000,600)) #desplay setup
pygame.display.set_caption("Dragon King: Legacy") #set caption
black=(0,0,0) #colour set
Base_Layer.fill(black) #colour set
Base_Layer.convert() #converts the base layer, may have no effect in current position
icon=pygame.image.load("LOGO.png") #find logo
pygame.display.set_icon(icon) #set icon to logo
#set up the game layer
Game_Layer=pygame.Surface((600,600)) #set layer peramaters
Game_Layer.fill(white) #set layer to white
Game_Layer.convert() #converts the game layer, may have no effect in current position
Base_Layer.blit(Game_Layer, (10, 0)) #blit layer on to screen
pygame.display.flip() #get the layer to show
If anyone could explain to me why this is not working I would appreciate it. I would also appreciate if someone knows a way to display my images in the way I am currently (within a definition) without using global variables.

Pygame programs are usually structured similarly to the following example. First of all, initialize everything and load the images and other resources (do that only once ahead of the main loop), then, in the main while loop, handle the events, update the game and blit everything. Finally, call pygame.display.flip() or pygame.display.update() to make all changes visible and clock.tick(fps) to limit the frame rate.
import pygame
pygame.init()
screen = pygame.display.set_mode((1000, 600))
# Constants (use uppercase letters to signal that these shouldn't be modified).
BLACK = pygame.color.Color("black")
WHITE = pygame.color.Color("white")
GAME_LAYER = pygame.Surface((600, 600))
GAME_LAYER.fill(WHITE)
# convert() returns a new surface, so you have to assign it to a variable.
DRAGON_IMG = pygame.image.load("Green Dragon.gif").convert()
def main(screen):
clock = pygame.time.Clock()
# Variables
x = 0
y = 0
while True:
# Handle events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
# Game logic.
x += 1
# Clear the screen and blit everything.
screen.fill(BLACK)
screen.blit(GAME_LAYER, (10, 0))
screen.blit(DRAGON_IMG, (x, y))
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main(screen)
pygame.quit()
If you want to blit onto a background surface instead of the screen/display and it's unicolored, you can just fill the background surface each frame with the fill method, then blit the dragon and finally blit the background onto the screen:
game_layer.fill(WHITE)
game_layer.blit(DRAGON_IMG, (x, y))
screen.blit(game_layer, (10, 0))
Or if your background surface is an actual image, you can create a copy each frame and then blit onto this copy:
game_layer_copy = GAME_LAYER.copy()
game_layer_copy.blit(DRAGON_IMG, (x, y))
screen.blit(game_layer_copy, (10, 0))

Game_Layer is a surface, and surfaces have no update method. update is a function of pygame.display. pygame.display.update is like pygame.display.flip except you can specify what parts of the screen should be flipped.
Also, please don't use global if you have any other choice. It's considered better to wrap everything into a class, pass Game_Layer as a argument, or use pygame.display.get_surface()

Related

why do i keep getting "video system not initialized" my pygame game? [duplicate]

So i wrote this code:
# Pygame development 4
# Focus on making code object oriented
# Introduce classes and objects into our code
# Gain access to the pygame library
import pygame
# Size of the screen
SCREEN_TITLE = 'Crossy RPG'
SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
# Colors according to RGB codes
WHITE_COLOR = (255, 255, 255)
BLACK_COLOR = (0, 0 , 0)
# Clock used to update game events and frames
clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont('comicsans', 75)
class Game:
# Typical rate of 60, equivalent to fps
TICK_RATE = 60
# Initializer for the game class to set up the width, height, and title
def __init__(self, title, width, height):
self.title = title
self.width = width
self.height = height
# Create the window of specified size in white to display the game
self.game_screen = pygame.display.set_mode((width, height))
# Set the game window color to white
self.game_screen.fill(WHITE_COLOR)
pygame.display.set_caption(title)
def run_game_loop(self):
is_game_over = False
# Main game loop, used to update all gameplay suh as movement, check, and graphics
# Runs unit is_game_over = True
while not is_game_over:
# A loop to get a;l of the events occuring at any given time
# Events are most often mouse movement, mouse and button clicks, or eit events
for event in pygame.event.get():
# If we have a quite type event(exit out) then exit out of the game loop
if event.type == pygame.QUIT:
is_game_over = True
print(event)
# Update all game graphics
pygame.display.update()
# Tick the clock to update everything within the game
clock.tick(self.TICK_RATE)
pygame.init()
new_game = Game(SCREEN_TITLE, SCREEN_WIDTH, SCREEN_HEIGHT)
new_game.run_game_loop()
pygame.quit()
quit()
Right now I am learning to code with python so im following a course online and since I couldn't get help from the forums of that website I thought I might ask the question here! So I've looked at the code multiple times to check for spelling mistakes but I couldn't find any and anyway i think that it's' not about something missing but it has something to do with pygame.display.update ! Can somebody pls help me?
Without running your code or having a stack trace of where the problem happens, we need to debug the code for you first. So it would be beneficial to add a full stack trace to your questions. I'm pretty confident however that there's two issues that you should work out.
pygame.display.update() should be correctly indented to be in the while loop of your main game event loop. Secondly, the pygame.init() should be run before any other initialization (or at least so I've been taught over the years and every example points to)
Try this out, I think it solves your problem:
# Pygame development 4
# Focus on making code object oriented
# Introduce classes and objects into our code
# Gain access to the pygame library
import pygame
pygame.init()
# Size of the screen
SCREEN_TITLE = 'Crossy RPG'
SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
# Colors according to RGB codes
WHITE_COLOR = (255, 255, 255)
BLACK_COLOR = (0, 0 , 0)
# Clock used to update game events and frames
clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont('comicsans', 75)
class Game:
# Typical rate of 60, equivalent to fps
TICK_RATE = 60
# Initializer for the game class to set up the width, height, and title
def __init__(self, title, width, height):
self.title = title
self.width = width
self.height = height
# Create the window of specified size in white to display the game
self.game_screen = pygame.display.set_mode((width, height))
# Set the game window color to white
self.game_screen.fill(WHITE_COLOR)
pygame.display.set_caption(title)
def run_game_loop(self):
is_game_over = False
# Main game loop, used to update all gameplay suh as movement, check, and graphics
# Runs unit is_game_over = True
while not is_game_over:
# A loop to get a;l of the events occuring at any given time
# Events are most often mouse movement, mouse and button clicks, or eit events
for event in pygame.event.get():
# If we have a quite type event(exit out) then exit out of the game loop
if event.type == pygame.QUIT:
is_game_over = True
print(event)
# Update all game graphics
pygame.display.update()
# Tick the clock to update everything within the game
clock.tick(self.TICK_RATE)
new_game = Game(SCREEN_TITLE, SCREEN_WIDTH, SCREEN_HEIGHT)
new_game.run_game_loop()
pygame.quit()
This also seams to be a school assignment and not a online course (but I might be wrong here), never the less I'll leave this piece of advice if I'm right. I strongly suggest that if you bump into problems, ask your teacher for guidance. As there's always a reason for teachers giving you a challenge/problem to solve. It teaches you the latest techniques you've learned in class, and if you can't solve the problem with the tools that you've been given - you've most likely haven't learned the fundamentals that has been taught out - and you should really re-do some steps.

pygame player not loading

the code might seem a bit long, but everything is well commented.
first off, the error that im getting is :
File "C:/Users/nellissery/Desktop/david/spaceinvader/main.py", line 56, in <module>
player()
File "C:/Users/nellissery/Desktop/david/spaceinvader/main.py", line 28, in player
screen.blit(plr, plr_x, plr_y)
TypeError: invalid destination position for blit
that is the error. the rest of the code is:
# screen and icon
scr_height = 600
scr_width = 800
icon_sprite = 'spaceship.png'
# title:
pygame.display.set_caption('Space Invaders')
# icon:
icon = pygame.image.load(icon_sprite)
pygame.display.set_icon(icon)
# player
plr_sprite = 'player-ship.png'
plr_x = 200
plr_y = 200
plr = pygame.image.load(plr_sprite)
def player():
# blit means to draw
screen.blit(plr, plr_x, plr_y)
# in pygame, x-y axis has origin at top, left corner
# to create a screen
screen = pygame.display.set_mode((scr_width, scr_height))
run = True
# the game loop:
while run:
# background colour
screen.fill((240,248,255))
# to go through the events
for event in pygame.event.get():
# to check if the exit button is pressed
if event.type == pygame.QUIT:
run = False
# to make sure that the changes to display are visible, we need to update display:
# to put the player on screen:
player()
pygame.display.update()
some help would be appreciated, as i've gone through the code multiple times and don't know where im going wrong. The image is a 64 * 64. it stops working for the player function. I have saved the asset correctly and it is probably loading well. i don't understand why i get the error that
The 2nd argument of pygame.Surface.blit has to be a tuple with 2 components. This tuple specifies the 2 dimensional coordinate, which specifies the top left of the source surface on the destination. Alternatively the 2nd argument can be a Rect, too.
screen.blit(plr, plr_x, plr_y)
screen.blit(plr, (plr_x, plr_y))

Image not moving in Pygame

# import pygame module in this program
import pygame
# activate the pygame library .
# initiate pygame and give permission
# to use pygame's functionality.
pygame.init()
# define the RGB value
# for white colour
white = (255, 255, 255)
# assigning values to X and Y variable
X = 800
Y = 500
xa=0
ya=0
# create the display surface object
# of specific dimension..e(X, Y).
display_surface = pygame.display.set_mode((X, Y ))
# set the pygame window name
pygame.display.set_caption('Image')
# create a surface object, image is drawn on it.
image = pygame.image.load(r'ball.png')
# infinite loop
while True :
xa+=1
ya+=1
# completely fill the surface object
# with white colour
display_surface.fill(white)
# moving the image surface object
# to the display surface object at
display_surface.blit(image, (xa, ya))
# 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 :
# deactivates the pygame library
pygame.quit()
# quit the program.
quit()
# Draws the surface object to the screen.
pygame.display.update()
I am trying to make an image move in a particular direction as I am a beginner. But the image is not moving. I am new to python so It's hard for me to figure out what's the mistake so Please tell me what's the problem.
It's a matter of Indentation. You have to update the display in the application loop rather the event loop:
# infinite loop
while True :
xa+=1
ya+=1
# completely fill the surface object
# with white colour
display_surface.fill(white)
# moving the image surface object
# to the display surface object at
display_surface.blit(image, (xa, ya))
# 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 :
# deactivates the pygame library
pygame.quit()
# quit the program.
quit()
#<--| INDENTATION
# Draws the surface object to the screen.
pygame.display.update()
Note, the application loop is executed in each frame, but the event loop is only entered when an event occurs.
Put the display.update() outside of for loop but inside while loop.
You put the update function in the wrong loop, try this code, it should work.
# import pygame module in this program
import pygame
# activate the pygame library .
# initiate pygame and give permission
# to use pygame's functionality.
pygame.init()
# define the RGB value
# for white colour
white = (255, 255, 255)
# assigning values to X and Y variable
X = 800
Y = 500
xa=0
ya=0
# create the display surface object
# of specific dimension..e(X, Y).
display_surface = pygame.display.set_mode((X, Y ))
# set the pygame window name
pygame.display.set_caption('Image')
# create a surface object, image is drawn on it.
image = pygame.image.load(r'ball.png')
# infinite loop
while True :
xa+=1
ya+=1
# completely fill the surface object
# with white colour
display_surface.fill(white)
# moving the image surface object
# to the display surface object at
display_surface.blit(image, (xa, ya))
# 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 :
# deactivates the pygame library
pygame.quit()
# quit the program.
quit()
# Draws the surface object to the screen.
pygame.display.update()

Having Trouble Blitting Image From Dictionary

So I'm trying to get into using Pygame, but all of the tutorials I can find online utilize only one file. I played around with ideas on how I can load all of the images in a single function. and decided on saving them in a Dictionary. Problem is, when I try to paste the image from the dictionary, I get the following error:
Traceback (most recent call last):
File "J:\Growth of Deities\Main.py", line 32, in <module>
pygame.Surface.blit(Sprites["TileWastelandBasic"], (0, 0))
TypeError: argument 1 must be pygame.Surface, not tuple
So I played around with the code a bit and googled it for an hour or so, but I can't figure out why I'm getting an error. I assume it's because I can't save images in dictionaries, but I'm not certain. Does anyone have any ideas on how to fix it?
My Main File:
import pygame
from Startup import LoadTextures
pygame.init()
#Sets the color White
WHITE = (255, 255, 255)
#Sets screen size Variable
size = (900, 900)
#Sets Screen Size
screen = pygame.display.set_mode(size)
#Sets name of Game
pygame.display.set_caption("Growth of Deities")
closeWindow = False
clock = pygame.time.Clock()
Sprites = LoadTextures.Load()
while not closeWindow:
#Repeat while game is playing
for event in pygame.event.get():
#Close Window if you close the window
if event.type == pygame.QUIT:
closeWindow = True
#Logic Code
#Rendering Code
pygame.Surface.blit(Sprites["TileWastelandBasic"], (0, 0))
#Clear Screen
screen.fill(WHITE)
#Update Screen
pygame.display.flip()
#Set Tick Rate
clock.tick(60)
#Closes Game
pygame.quit()
My Image Loading File:
import pygame
import os, sys
def Load():
Sprites = {}
WastelandSprites = 'Assets\Textures\Tile Sprites\Wasteland'
Sprites["TileWastelandBasic"] = pygame.image.load(os.path.join(WastelandSprites + "\WastelandBasic.png")).convert_alpha()
Sprites["TileWastelandBasic"] = pygame.transform.scale(Sprites["TileWastelandBasic"], (50, 50)).convert_alpha()
return Sprites
The problem is not because of your dictionary. The signature of blit is
blit(source, dest, area=None, special_flags = 0) -> Rect
where source must be a surface. However, this assumes that blit is being invoked with a pygame.Surface instance as the receiver. Instead, you're calling the blit function from its class, which means that its signature is effectively
blit(self, source, dest, area=None, special_flags = 0) -> Rect
where self must also be a surface. You could fix your problem by changing the call to
pygame.Surface.blit(screen, Sprites["TileWastelandBasic"], (0, 0))
but I would recommend the more idiomatic
screen.blit(Sprites["TimeWastelandBasic"], (0, 0))
instead.
See: http://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit

Resize image on mouse click in Pygame

This code displays an image and works:
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((900,900))
lion = pygame.image.load("lion.jpg")
while true:
screen.blit(lion, (0,0))
pygame.display.update()
I also want be able to right click the image to adjust its size. For example:
pygame.event.get()
buttonpress = pygame.mouse.get_pressed()
press = pygame.key.get_pressed()
screen.blit(lion,(100-(lion.get_width()/2, 100-(lion.get_height()/2))))
pygame.event.quit
However, as soon as I click on the pygame window, it stops responding and I cannot do anything to it.
screen.blit() takes two arguments, surface and destination. It seems like you are trying to use it to resize your image. You could use pygame.transform.scale() which takes the surface and size arguments. For Example:
done = False
while not done:
for event in pygame.event.get():
if event.type == QUIT: #so you can close your window without it crashing or giving an error
done = True
pressed_buttons = pygame.mouse.get_pressed() #get a tuple of boolean values for the pressed buttons
if pressed_buttons[2]: #if the right mouse button is down
adjusted_lion_image = pygame.transform.scale(lion, (lion.get_wdith() / 2, lion.get_height() / 2)) #set the adjusted image to an image equal to half the size of the original image
else: #if the right mouse button is not down
adjusted_lion_image = lion #set the adjusted image back to the lion image
screen.fill((0, 0, 0)) #fill the screen with black before we draw to make it look cleaner
screen.blit(adjusted_lion_image, (0, 0)) #blit the adjusted image
pygame.display.update() #update the screen
pygame.quit() #make sure this is OUTSIDE of the while loop.
This should accomplish what you want. You also might want to add a .convert() after loading the lion image to convert the image to one pygame can use more readily:
lion = pygame.image.load("lion.jpg").convert()

Categories

Resources