Pygame is not displaying a grid or fps counter - python-3.x

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()

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()

Add object every 100 points [duplicate]

I'm a beginner programmer who is starting with python and I'm starting out by making a game in pygame.
The game basically spawns circles at random positions and when clicked, it gives you points.
Recently I've hit a roadblock when I want to spawn multiple instances of the same object (in this case circles) at the same time.
I've tried stuff like sleep() and some other code related to counters, but it always results in the next circle spawned overriding the previous one (i.e the program spawns circle 1, but when circle 2 comes in, circle 1 disappears).
Does anyone know a solution to this? I would really appreciate your help!
import pygame
import random
import time
pygame.init()
window = pygame.display.set_mode((800,600))
class circle():
def __init__(self, color, x, y, radius, width,):
self.color = color
self.x = x
self.y = y
self.radius = radius
self.width = width
def draw(self, win, outline=None):
pygame.draw.circle(win, self.color, (self.x, self.y, self.radius, self.width), 0)
run=True
while run:
window.fill((0, 0, 0))
pygame.draw.circle(window, (255, 255, 255), (random.randint(0, 800),random.randint(0, 600)), 20, 20)
time.sleep(1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
pygame.quit()
quit()
It does not work that way. time.sleep, pygame.time.wait() or pygame.time.delay is not the right way to control time and gameplay within an application loop. The game does not respond while you wait. The application loop runs continuously. You have to measure the time in the loop and spawn the objects according to the elapsed time.
pygame.Surface.fill clears the entire screen. Add the newly created objects to a list. Redraw all of the objects and the entire scene in each frame.
See also Time, timer event and clock
You have 2 options. Use pygame.time.get_ticks() to measure the time. Define a time interval after which a new object should appear. Create an object when the point in time is reached and calculate the point in time for the next object:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
next_object_time = 0
while run:
# [...]
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
Minimal example:
repl.it/#Rabbid76/PyGame-TimerSpawnObjects
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
next_object_time = 0
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()
The other option is to use the pygame.event module. Use pygame.time.set_timer() to repeatedly create a USEREVENT in the event queue. The time has to be set in milliseconds. e.g.:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
Note, in pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to be between pygame.USEREVENT (24) and pygame.NUMEVENTS (32). In this case pygame.USEREVENT+1 is the event id for the timer event.
Receive the event in the event loop:
while run:
for event in pygame.event.get():
if event.type == timer_event:
object_list.append(Object())
The timer event can be stopped by passing 0 to the time argument of pygame.time.set_timer.
Minimal example:
repl.it/#Rabbid76/PyGame-TimerEventSpawn
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == timer_event:
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()

Pygame, A Bit Racey tutorial: Calling the same function to draw the same object multiple times [duplicate]

I'm a beginner programmer who is starting with python and I'm starting out by making a game in pygame.
The game basically spawns circles at random positions and when clicked, it gives you points.
Recently I've hit a roadblock when I want to spawn multiple instances of the same object (in this case circles) at the same time.
I've tried stuff like sleep() and some other code related to counters, but it always results in the next circle spawned overriding the previous one (i.e the program spawns circle 1, but when circle 2 comes in, circle 1 disappears).
Does anyone know a solution to this? I would really appreciate your help!
import pygame
import random
import time
pygame.init()
window = pygame.display.set_mode((800,600))
class circle():
def __init__(self, color, x, y, radius, width,):
self.color = color
self.x = x
self.y = y
self.radius = radius
self.width = width
def draw(self, win, outline=None):
pygame.draw.circle(win, self.color, (self.x, self.y, self.radius, self.width), 0)
run=True
while run:
window.fill((0, 0, 0))
pygame.draw.circle(window, (255, 255, 255), (random.randint(0, 800),random.randint(0, 600)), 20, 20)
time.sleep(1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
pygame.quit()
quit()
It does not work that way. time.sleep, pygame.time.wait() or pygame.time.delay is not the right way to control time and gameplay within an application loop. The game does not respond while you wait. The application loop runs continuously. You have to measure the time in the loop and spawn the objects according to the elapsed time.
pygame.Surface.fill clears the entire screen. Add the newly created objects to a list. Redraw all of the objects and the entire scene in each frame.
See also Time, timer event and clock
You have 2 options. Use pygame.time.get_ticks() to measure the time. Define a time interval after which a new object should appear. Create an object when the point in time is reached and calculate the point in time for the next object:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
next_object_time = 0
while run:
# [...]
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
Minimal example:
repl.it/#Rabbid76/PyGame-TimerSpawnObjects
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
next_object_time = 0
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()
The other option is to use the pygame.event module. Use pygame.time.set_timer() to repeatedly create a USEREVENT in the event queue. The time has to be set in milliseconds. e.g.:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
Note, in pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to be between pygame.USEREVENT (24) and pygame.NUMEVENTS (32). In this case pygame.USEREVENT+1 is the event id for the timer event.
Receive the event in the event loop:
while run:
for event in pygame.event.get():
if event.type == timer_event:
object_list.append(Object())
The timer event can be stopped by passing 0 to the time argument of pygame.time.set_timer.
Minimal example:
repl.it/#Rabbid76/PyGame-TimerEventSpawn
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == timer_event:
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()

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()

FPS loose in Pygame

So there is my previous code that I corrected myself, but there is another problem. The 'game' is running at 60 FPS, but when I wanna blit a background instead of a black screen, the game slows down to 30 fps.. Is there a way to fix this ?
import math
import pygame
class Planete:
def __init__(self,rayon,periode,envergure,couleur):
self.rayon = rayon
self.periode = periode
self.couleur = couleur
self.envergure = envergure
self.omega = (2*math.pi)/self.periode
self.i = 0
def tourner(self) :
self.x = self.rayon*math.cos(self.omega*self.i)
self.x2 = int(self.x)+500
self.y = self.rayon*math.sin(self.omega*self.i)
self.y2 = int(self.y)+200
self.i = self.i + 1
def dessiner(self):
pygame.draw.circle(gameDisplay,(self.couleur),((self.x2, self.y2)), self.envergure)
pygame.init()
Terre = Planete(149, 65.25,9,(25,0,250))
Mars = Planete(227, 86.98,8,(250,25,0))
#Wuut = Planete(195,206,7,(15,30,70))
#Jupiter = Planete(80,800,12,(150,50,15))
gameDisplay = pygame.display.set_mode((1280,720))
background = pygame.image.load("Ecran titre\\principal\\background.jpg")
menu = pygame.image.load("Ecran titre\\principal\\menu.png")
clock = pygame.time.Clock()
gameExit = False
while not gameExit :
Terre.tourner()
Mars.tourner()
#Wuut.tourner()
#Jupiter.tourner()
for event in pygame.event.get():
if (event.type == pygame.QUIT):
gameExit = True
gameDisplay.fill(0)
#gameDisplay.blit(background,(0,0))
Terre.dessiner()
Mars.dessiner()
#Wuut.dessiner()
#Jupiter.dessiner()
pygame.display.update()
clock.tick(60)
pygame.display.set_caption("fps: " + str(clock.get_fps()))
pygame.quit()
quit()
Blitting an image that has transparency is really slow. If you call .convert() after loading it, it'll make it blit faster. This will convert it to a faster opaque format.
background = pygame.image.load("Ecran titre\\principal\\background.jpg").convert()

Resources