# 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()
Related
I am making a basic Mandelbrot zoom program using pygame that uses pillow to generate images each time a user zooms in. When this image is updated the pygame window simply loads the original image and not the updated one.
My current solution is to kill the pygame window with each zoom and reinitialize it which adds a fair amount of time to each zoom. Here is my current code
def pg_window(width, height):
pg.init()
fill_color = 255, 255, 255
window = pg.display.set_mode((width, height))
global set_image
set_img = pg.image.load('mandelbrot.png')
# The original load of the image
zoom_x = int(width * .15)
zoom_y = int(height * .15)
while True:
window.fill(fill_color)
... extra code ommitted ...
for event in pg.event.get():
if event.type == pg.QUIT:
sys.exit()
if event.type == pg.MOUSEBUTTONDOWN:
zoom(*zoom_rect.center, width, height, zoom_x, zoom_y)
# The zoom function call modifies the image directly.
set_image = pg.image.load('mandelbrot.png')
# changing the set_image variable just loads the original image, not the updated one
# My current solution involves calling pg.quit() here
# and recalling the pg_window function to reinitialize
window.fill(fill_color)
window.blit(set_img, (0, 0))
pg.display.flip()
Is there anyway to load an updated image without resetting the window?
The name of the image which is blit to the window is set_img rather than set_image.
So you've to set set_img:
while True:
window.fill(fill_color)
# [...]
for event in pg.event.get():
# [...]
if event.type == pg.MOUSEBUTTONDOWN:
# [...]
set_img = pg.image.load('mandelbrot.png') # <--- set_img
window.fill(fill_color)
window.blit(set_img, (0, 0))
pg.display.flip()
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()
I am new into Python and pyGame and i have a problem with scaling an image.
I want to zoom an image in pygame.
The pygame documentation claims that
pygame.transform.scale()
should scale to a new resolution.
But in my example below it does not work - it crops the image instead of resizing it!?
What am i doing wrong?
#!/usr/bin/env python3
# coding: utf-8
import pygame
from pygame.locals import *
# Define some colors
BLACK = (0, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
screen = pygame.display.set_mode((1920, 1080))
pic = pygame.image.load('test.jpg').convert()
pic_position_and_size = pic.get_rect()
# Loop until the user clicks the close button.
done = False
# Clear event queue
pygame.event.clear()
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == QUIT:
done = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
done = True
# background in black
screen.fill(BLACK)
# Copy image to screen:
screen.blit(pic, pic_position_and_size)
# Update the screen with what we've drawn.
pygame.display.flip()
pygame.display.update()
pygame.time.delay(10) # stop the program for 1/100 second
# decreases size by 1 pixel in x and y axis
pic_position_and_size = pic_position_and_size.inflate(-1, -1)
# scales the image
pic = pygame.transform.scale(pic, pic_position_and_size.size)
# Close the window and quit.
pygame.quit()
pygame.transform.scale() does not work very well for your case. If you shrink a Surface by such a small amount, the algorithm just crops the last column and row of pixels. If you now repeat this process over and over again with the same Surface, you get the strange behaviour you see.
A better approach would be to keep a copy of your original Surface around, and use that for creating the scaled image. Also, using smoothscale instead of scale may also lead to a better effect; it's up to you if you want to use it.
Here's a "fixed" version of your code:
#!/usr/bin/env python3
# coding: utf-8
import pygame
from pygame.locals import *
# Define some colors
BLACK = (0, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
screen = pygame.display.set_mode((1920, 1080))
org_pic = pygame.image.load('test.jpg').convert()
pic_position_and_size = org_pic.get_rect()
pic = pygame.transform.scale(org_pic, pic_position_and_size.size)
# Loop until the user clicks the close button.
done = False
# Clear event queue
pygame.event.clear()
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == QUIT:
done = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
done = True
# background in black
screen.fill(BLACK)
# Copy image to screen:
screen.blit(pic, (0,0))
# Update the screen with what we've drawn.
pygame.display.flip()
pygame.display.update()
pygame.time.delay(10) # stop the program for 1/100 second
# decreases size by 1 pixel in x and y axis
pic_position_and_size = pic_position_and_size.inflate(-1, -1)
# scales the image
pic = pygame.transform.smoothscale(org_pic, pic_position_and_size.size)
# Close the window and quit.
pygame.quit()
I will show my code below. I think when I def moveDot, something wrong I can feel it. However, I just code as my instructor's presentation. She's code can work and mine cannot. I don't know the reason. I think the order of moveDot's variances may have some problems. Is that right? I will appreciate anyone who can help me! Thanks a lot!
# Poke The Dots
# There are two dots that are moving on a 500 by 400 window
# There is a score board that displays the time in seconds
# since the game started
# If the player clicks inside the window, the dots disappear
# and reappear at some random location
# If the dots collide, the dots stop moving, the score stops
# changing and Game Over is displayed.
# Version 1
import pygame, sys, time
from pygame.locals import *
# User-defined classes
# User-defined functions
def main():
# Initialize pygame
pygame.init()
# Set window size and title, and frame delay
surfaceSize = (500, 400) # window size
windowTitle = 'Poke The Dots' #window title
frameDelay = 0.02 # smaller is faster game
# Create the window
surface = pygame.display.set_mode(surfaceSize, 0, 0)
pygame.display.set_caption(windowTitle)
# create and initialize red dot and blue dot
gameOver = False
color1=pygame.Color('red')
center1 = [50, 75]
radius1=30
speed1=[1,2]
color2=pygame.Color('blue')
center2=[200,100]
radius2=40
speed2=[2,1]
# Draw objects
pygame.draw.circle(surface, color1, center1, radius1, 0)
pygame.draw.circle(surface, color2,center2,radius2,0)
gameOver = update(surface, color1, center1, radius1, speed1, color2, center2, radius2, speed2)
# Refresh the display
pygame.display.update()
# Loop forever
while True:
# Handle events
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Handle additional events
# Update and draw objects for the next frame
#gameOver = update(center, surface)
# Refresh the display
pygame.display.update()
# Set the frame speed by pausing between frames
time.sleep(frameDelay)
def update(surface, color1, center1, radius1, speed1, color2, center2, radius2, speed2):
#Check if the game is over. If so, end the game and
#returnTrue. Otherwise, update the game objects, draw
#them, and return False.
#This is an example update function - replace it.
#- center is a list containing the x and y int coords
#of the center of a circle
#- surface is the pygame.Surface object for the window
erasecolor=pygame.Color('black')
if False: # check if the game is over
return True
else: # continue the game
surface.fill(erasecolor)
moveDot(surface, color1, center1, radius1)
moveDot(surface, color2, center2, radius2)
pygame.draw.circle(surface,color1,center1,radius1,0,0)
pygame.draw.circle(surface,color2,center2,radius2,0,0)
return False
def moveDot(surface,center,radius,speed):
size=surface.get_size()
for coord in range(0,2):
center[coord]=center[coord]+speed[coord]
if center [coord]<radius:
speed[coord]=-speed[coord]
if center[coord]+radius>size(coord):
speed[coord]=-speed[coord]
main()
The order of your arguments being passed when you call moveDot is incorrect. It should be
moveDot(surface, center1, radius1, speed)
For both statements. Speed should be the speed of movement of the circle.
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()