Python /Pygame blitting multiple image to list coordinates - python-3.x

So i'm making a space game where you have a open world to explore (A black Screen)
and i wanna create planets(Blit images to screen) around the universe(from a list).
This is my code currently
star = pygame.image.load("star.png")
planets = random.randrange(100,500) #<------#####NOT IMPORTANT#######
positions = [(300,50),(400,27),(900,55)] #<------
position = ()
positions has coorinates where images should be blitted
but when i blit them
for position in positions:
ikkuna.blit(star, position)
it blits the first one or nothing and does not crash
why?
################################################-
Here is the full code if it helps (there is bits of the finish language in there hope it does not bother)
"ikkuna = screen (leveys,korkeus) = (width,hight) toiminnassa = in action"
import pygame
import random
import time
import sys
import math
pygame.init()
White = (255,255,255)
red = (255,0,0)
kello = pygame.time.Clock()
star = pygame.image.load("star.png")
planets = random.randrange(100,500)
positions = [(300,50)]
position = ()
tausta_vari = (255,255,255)
(leveys, korkeus) = (1000, 1000)
ikkuna = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("SpaceGenerationTest")
######################################################################
toiminnassa = True
while toiminnassa:
for event in pygame.event.get():
if event.type == pygame.QUIT:
toiminnassa = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_g:
print("Generating World....")
print(planets)
for position in positions:
ikkuna.blit(star, position)
print("hello")

There's some problems with your code:
Your not updating the display, which means that all your changes won't be visible. Use pygame.display.update() or pygame.display.flip() at the end of the game loop to update the screen.
When you're mixing English and Finnish it becomes very inconsistent and hard to follow, especially for people who don't speak Finnish. Try to use English, even when you're just practicing.
Your full example only contain one position in the list, thus it's only creating one star at one position.
Pressing the 'g'-key won't generate any planets. You might want to introduce a boolean variable like in the example below.
I changed your code to english and made some adjustment so it's more consistent.
import pygame
import random
pygame.init()
WHITE = (255, 255, 255)
RED = (255, 0, 0)
# I changed the background color to black, because I understood it as that is what you want.
BACKGROUND_COLOR = (0, 0, 0) # tausta_vari
clock = pygame.time.Clock() # kello
star = pygame.Surface((32, 32))
star.fill((255, 255, 255))
planets = random.randrange(100, 500)
positions = [(300, 50), (400, 27), (900, 55)]
WIDTH, HEIGHT = (1000, 1000) # (leveys, korkeus)
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # ikkuna
pygame.display.set_caption("SpaceGenerationTest")
display_stars = False
running = True # toiminnassa
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_g:
print("Generating World....")
print(planets)
display_stars = True
screen.fill(BACKGROUND_COLOR)
if display_stars:
for position in positions:
# This will create 3 stars because there're 3 elements in the list positions.
# To create more stars you'll need to add more in the list positions.
screen.blit(star, position)
pygame.display.update()

Your blitting all your images to the exact same position: positions = [(300, 50)], so the last image covers all the other images up. Also, you may not know this, but to display anything in pygame you have to either call pygame.display.flip() or pygame.display.update() after you finish drawing. I made a few revisions to your code, so the stars should show-up:
import pygame
import random
import time
import sys
import math
def main():
pygame.init()
White = (255,255,255)
red = (255,0,0)
kello = pygame.time.Clock()
star = pygame.image.load("star.png")
planets = random.randrange(100,500)
positions = [(300,50), (310, 60), (320, 80), (607, 451), (345, 231)]
tausta_vari = (255,255,255)
(leveys, korkeus) = (1000, 1000)
ikkuna = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("SpaceGenerationTest")
######################################################################
toiminnassa = True
while toiminnassa:
for event in pygame.event.get():
if event.type == pygame.QUIT:
toiminnassa = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_g:
print("Generating World....")
print(planets)
ikkuna.fill((0, 0, 0)) # fill the screen with black
for position in positions:
ikkuna.blit(star, position)
print("Hello")
pygame.display.flip() # updating the screen
if __name__ == '__main__': # are we running this .py file as the main program?
try:
main()
finally:
pg.quit()
quit()
~Mr.Python

Related

Pygame window is not responding after interaction with it

I need to generate circles in random place every second. Now I have this code.
import pygame as pg
from threading import Thread
import random
pg.init()
WIDTH = 600
HEIGH = 600
sc = pg.display.set_mode((WIDTH, HEIGH))
pg.display.set_caption("Bacteria")
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
sc.fill(BLACK)
pg.display.flip()
clock = pg.time.Clock()
FPS = 24
class FoodGen(Thread):
def run(self):
while 1:
clock.tick(1)
pg.draw.circle(sc, WHITE, (random.randint(10, WIDTH-10), random.randint(10, WIDTH-10)), 10)
class Main(Thread):
def run(self):
running = 1
while running:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
running = 0
break
pg.display.flip()
pg.quit()
t1 = FoodGen()
t1.start()
t2 = Main()
t2.start()
When is move mouse on the window it turns to waiting mode. The window is running until I try to move or close it. I've already red many information about this problem, but still can't fix it.
See How to run multiple while loops at a time in Python. If you want to control something over time in Pygame you have two options:
Use pygame.time.get_ticks() to measure time and and implement logic that controls the object depending on the time.
Use the timer event. Use pygame.time.set_timer() to repeatedly create a USEREVENT in the event queue. Change object states when the event occurs.
e.g.:
import pygame as pg
import random
WIDTH, HEIGH = 600, 600
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
FPS = 24
pg.init()
sc = pg.display.set_mode((WIDTH, HEIGH))
pg.display.set_caption("Bacteria")
clock = pg.time.Clock()
timer_interval = 100 # 0.1 seconds
timer_event_id = pg.USEREVENT + 1
pg.time.set_timer(timer_event_id, timer_interval)
circles = []
running = 1
while running:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
running = 0
if event.type == timer_event_id:
circles.append((random.randint(10, WIDTH-10), random.randint(10, WIDTH-10)))
sc.fill(BLACK)
for center in circles:
pg.draw.circle(sc, WHITE, center, 10)
pg.display.flip()
pg.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()

Pygame, how do you fix a part of the screen being black when i make a game?

A part (specifically the top middle) of the screen is black, once i have added a background, but i can see the rest of the background.
I have tried running it a few times and i have tried searching what might have caused it, i don't have a game loop yet, because nothing is supposed to happen, that might be the problem... sorry the code is long...
import pygame
SCREEN_WIDTH = 1500
SCREEN_HEIGHT = 800
SCREEN_TITLE = "road cross game thing"
WHITE_COLOR = (255,255,255)
clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont("comicsans", 75)
title = SCREEN_TITLE
width = SCREEN_WIDTH
height = SCREEN_HEIGHT
class Game:
TICK_RATE = 60
title = SCREEN_TITLE
width = SCREEN_WIDTH
height = SCREEN_HEIGHT
image = pygame.image.load("photo.jpg")
game_screen = pygame.display.set_mode((width, height))
game_screen.fill(WHITE_COLOR)
game_screen.fill(WHITE_COLOR)
game_screen.blit(image, (0, 0))
pygame.display.set_caption(title)
is_game_over = False
did_win = False
direction = 0
while not is_game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
is_game_over = True
elif event.type == pygame.MOUSEBUTTONUP:
pos= pygame.mouse.get_pos()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
direction = 0
print(event)
game_screen.fill(WHITE_COLOR)
pygame.display.update()
clock.tick(TICK_RATE)
object_image1 = pygame.image.load("photo.jpg")
image1 = pygame.transform.scale(object_image1, (50, 50))
x_pos = 50
y_pos = 50
game_screen.blit(image1,(x_pos, y_pos))
pygame.init()
Game()
pygame.quit()
quit()
i expected the code to make the whole background my picture.
Your code is mostly there, it's just a bit un-organised.
The reason the screen updating is not what you expect is because the code is drawing and then updating in out-of-order. In a nutshell, it should make all the drawing operations first, then update() them all to the display. Obviously if you draw and image, then call fill(), the first draw operation is not going to be visible, since it's been over-painted.
The image1 does not fill the entire display because it's only stretched to ( 50, 50 ) whereas the screen is 1500 x 800.
While I was debugging the code, I moved the initialisation functions into a member function Game.__init__(), and the main game loop into a Game.run() function.
The OP's indentation is a little messed-up, I expect this is caused by the paste into SO (otherwise the program would not produce the described result). But it looks like you're loading images inside the main game loop. It's best to load resources like images, sounds, etc. only once before the user-event loop begins.
import pygame
SCREEN_WIDTH = 1500
SCREEN_HEIGHT = 800
TICK_RATE = 60
SCREEN_TITLE = "road cross game thing"
WHITE_COLOR = (255,255,255)
# Initialise PyGame
pygame.init()
pygame.display.set_caption( SCREEN_TITLE )
game_screen = pygame.display.set_mode( ( SCREEN_WIDTH, SCREEN_HEIGHT ) )
clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont("comicsans", 75)
class Game:
def __init__( self, game_screen ):
self.game_screen = game_screen
self.image = pygame.image.load( "photo.jpg" )
self.object_image1 = pygame.image.load( "photo.jpg" )
#self.image1 = pygame.transform.scale( self.object_image1, (50, 50) )
# Scale to fill window
self.image1 = pygame.transform.scale( self.object_image1, ( SCREEN_WIDTH, SCREEN_HEIGHT) )
def run( self ):
is_game_over = False
did_win = False
direction = 0
while not is_game_over:
# Handle user input events
for event in pygame.event.get():
if event.type == pygame.QUIT:
is_game_over = True
elif event.type == pygame.MOUSEBUTTONUP:
pos= pygame.mouse.get_pos()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
direction = 0
print(event)
# Update the screen
#game_screen.fill( WHITE_COLOR )
#game_screen.blit( self.image, (0, 0) )
#x_pos = 50
#y_pos = 50
#game_screen.blit( self.image1, (x_pos, y_pos) )
# Fill the window with image1
game_screen.blit( self.image1, ( 0, 0 ) )
pygame.display.update()
clock.tick( TICK_RATE )
# Run the Game
game = Game( game_screen )
game.run()
pygame.quit()
quit()

Pygame is not displaying a grid or fps counter

I am trying to make a rpg but i always get the issue when pygame dose not display I am using a youtube video to help my make this rpg but Its just not working the creator made a color module to help but it just dose not work I know there are better ways of making a fps counter feel free to improve it
import pygame, sys, time
from Scripts.UltraColor import *
pygame.init()
cSec = 0
cFrame = 0
FPS = 0
tile_size = 32
fps_font = pygame.font.Font("C:\\Windows\\Fonts\\Verdana.ttf", 20)
def show_fps():
fps_overlay = fps_font.render(str(FPS), True, Color.Goldenrod)
window.blit(fps_overlay, (0,0))
def create_window():
global window, window_height, window_width, window_title
window_width, window_hight = 800, 600
window_title = "RPG"
pygame.display.set_caption(window_title)
window = pygame.display.set_mode((window_width, window_hight), pygame.HWSURFACE|pygame.DOUBLEBUF)
def count_fps():
global cSec, cFrame, FPS
if cSec == time.strftime("%S"):
cFrame += 1
else:
FPS = cFrame
cFrame = 0
cSec = time.strftime("%S")
create_window()
isRunning = True
while isRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
isRunning = False
# LOGIC
count_fps()
# Render Graphics
window.fill(Color.Black)
# - Render Sinple Terrain Grid
for x in range(0, 640, tile_size):
for y in range(0, 480, tile_size):
pygame.draw.rect(window, Color.White, (x, y, tile_size + 1, tile_size + 1), 1)
show_fps()
pygame.display.update
pygame.quit()
sys.exit()
You need to add parentheses behind pygame.display.update to call this function and update the display: pygame.display.update()
I also recommend to use a pygame.time.Clock to limit the frame rate and get the fps. Calling clock.tick(FPS) makes sure that the game doesn't run faster than this frame rate. In the show_fps function you can just call clock.get_fps() to get the current frame rate.
import pygame
def show_fps(window, clock):
fps_overlay = FPS_FONT.render(str(clock.get_fps()), True, GOLDENROD)
window.blit(fps_overlay, (0, 0))
pygame.init()
FPS_FONT = pygame.font.SysFont("Verdana", 20)
GOLDENROD = pygame.Color("goldenrod")
tile_size = 32
window = pygame.display.set_mode((800, 600), pygame.HWSURFACE|pygame.DOUBLEBUF)
clock = pygame.time.Clock()
FPS = 60
isRunning = True
while isRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
isRunning = False
# Render Graphics
window.fill((50, 50, 50))
# Render Simple Terrain Grid
for x in range(0, 640, tile_size):
for y in range(0, 480, tile_size):
pygame.draw.rect(
window, (255, 255, 255),
(x, y, tile_size+1, tile_size+1), 1)
show_fps(window, clock)
clock.tick(FPS)
pygame.display.update()
pygame.quit()

Program Crashes unsure why

Hello i'm trying to make a simple program to change the background colour on key press but it just crashes. It's to do with my loop but i don't really understand why it crashes.
thanks
import sys, pygame, random, time
from threading import Thread
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
green = (0, 100, 0)
red = (255, 0, 0)
Colour = (0,0,0)
size = width, height = 350, 350
screen = pygame.display.set_mode(size)
Running = True
while True:
key = pygame.key.get_pressed()
if key[pygame.K_ESCAPE]: # Escape key
Running = False
elif key[pygame.K_DOWN]: # down key
print("down")
Colour = red
elif key[pygame.K_UP]: # up key
print("h")
Colour = black
elif key[pygame.K_RIGHT]: # right key
Colour = green
print("h")
elif key[pygame.K_LEFT]: # left key
Colour = white
print("h")
pygame.draw.rect(screen, Colour, pygame.Rect(0, 0, width, height))
pygame.display.update()
pygame.display.flip()
You're missing a way for pygame to know if you want to quit the window. Instead of doing key = pygame.key.get_pressed() use:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit
if event.key == K_UP:
Colour = black
if event.key == K_DOWN:
Colour = red
if event.key == K_LEFT:
Colour = white
if event.key == K_RIGHT:
Colour = green
You also need a way for the program to handle time e.g. not run faster than you can see. You can do this by setting this variable at the top of your code:
clock = pygame.time.Clock()
and running this at the very end of your while loop:
clock.tick(FPS)
where you set the FPS as a number equal to the desired frames per second.
You can also remove your Running = True variable from the program. That should be all you need to get it running. Good luck! Ask questions below.
Two things:
You have a bug: the while loop while go forever because you are testing while True instead of while Running. You could change to while Running or after testing for escape key, you could break to exit the while loop.
Also, all pygame examples I have looked up just now have an event checker. Without that, pygame freezes. If you add it, everything is smooth.
Here are both of those corrected:
import sys, pygame, time
pygame.init()
size = 350, 350
screen = pygame.display.set_mode(size)
Running = True
while Running: # <----- changed this from True to Running
time.sleep(0.03) # avoid blasting the CPU. I think pygame.time.Clock also exists
# this makes pygame responsive
for event in pygame.event.get():
if event.type == pygame.QUIT:
Running = False # <---- or you could just break
# from here is as you originally wrote
key = pygame.key.get_pressed()
if key[pygame.K_ESCAPE]:
print('exit')
Running = False # <---- or you could just break
pygame.quit()
sys.exit()

Resources