I have done research and none of it has helped me. Whenever I run my code, pygame just displays a black screen and I don't know how to fix it.
This is my code:
# importing required librarys
import pygame
import sys
import chess
import math
import os
os.chdir('/Users/stella/Desktop/comp sci NEA/ChessGame/images')
#initialise display
X = 800
Y = 800
scrn = pygame.display.set_mode((X, Y))
pygame.init()
#basic colours
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
YELLOW = (204, 204, 0)
BLUE = (50, 255, 255)
BLACK = (0, 0, 0)
#initialise chess board
b = chess.Board()
#load piece images
pieces = {'p': pygame.image.load('bp.png').convert(),
'n': pygame.image.load('bN.png').convert(),
'b': pygame.image.load('bB.png').convert(),
'r': pygame.image.load('bR.png').convert(),
'q': pygame.image.load('bQ.png').convert(),
'k': pygame.image.load('bK.png').convert(),
'P': pygame.image.load('wp.png').convert(),
'N': pygame.image.load('wK.png').convert(),
'B': pygame.image.load('wB.png').convert(),
'R': pygame.image.load('wR.png').convert(),
'Q': pygame.image.load('wQ.png').convert(),
'K': pygame.image.load('wK.png').convert(),
}
def update(scrn,board):
'''
updates the screen basis the board class
'''
for i in range(64):
piece = board.piece_at(i)
if piece == None:
pass
else:
scrn.blit(pieces[str(piece)],((i%8)*100,700-(i//8)*100))
for i in range(7):
i=i+1
pygame.draw.line(scrn,WHITE,(0,i*100),(800,i*100))
pygame.draw.line(scrn,WHITE,(i*100,0),(i*100,800))
pygame.display.flip()
def main_one_agent(BOARD,agent,agent_color):
'''
for agent vs human game
color is True = White agent
color is False = Black agent
'''
#make background black
scrn.fill(BLACK)
#name window
pygame.display.set_caption('Chess')
#variable to be used later
index_moves = []
status = True
while (status):
#update screen
update(scrn,BOARD)
if BOARD.turn==agent_color:
BOARD.push(agent(BOARD))
scrn.fill(BLACK)
else:
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both.
if event.type == pygame.QUIT:
status = False
# if mouse clicked
if event.type == pygame.MOUSEBUTTONDOWN:
#reset previous screen from clicks
scrn.fill(BLACK)
#get position of mouse
pos = pygame.mouse.get_pos()
#find which square was clicked and index of it
square = (math.floor(pos[0]/100),math.floor(pos[1]/100))
index = (7-square[1])*8+(square[0])
# if we have already highlighted moves and are making a move
if index in index_moves:
move = moves[index_moves.index(index)]
#print(BOARD)
#print(move)
BOARD.push(move)
index=None
index_moves = []
# show possible moves
else:
piece = BOARD.piece_at(index)
if piece == None:
pass
else:
all_moves = list(BOARD.legal_moves)
moves = []
for m in all_moves:
if m.from_square == index:
moves.append(m)
t = m.to_square
TX1 = 100*(t%8)
TY1 = 100*(7-t//8)
pygame.draw.rect(scrn,BLUE,pygame.Rect(TX1,TY1,100,100),5)
#print(moves)
index_moves = [a.to_square for a in moves]
# deactivates the pygame library
if BOARD.outcome() != None:
print(BOARD.outcome())
status = False
print(BOARD)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
When I run it, all that is displayed is a black screen. No errors are called.
Some of the answers I found suggested indentation but I don't know where that would be as I am fairly new to coding.
Related
I'm trying to make a Cookie Clicker type game using PyGame, but when I use this bit of code:
def display(thing: pygame.Surface, where: tuple=(0, 0), center=False):
WIN.blit(thing, where if center == False else thing.get_rect(center = (WIN.get_width() // 2, WIN.get_height() // 2)))
def font(font: pygame.font.Font, text: str, colour: tuple=(255, 255, 255)):
return font.render(text, False, colour)
def main():
cookies = 0
cps = 1
clock = pygame.time.Clock()
tim = time.time()
run = True
while run:
clock.tick(FPS)
if time.time() - tim > 1:
tim = time.time()
cookies += cps
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
t = font(CFONT64, f"{cookies} Cookies")
display(t, t.get_rect(center = (WIN.get_width() // 2, WIN.get_height() * .07)))
pygame.display.update()
quitPy()
(not full code)
It'll do this:
and overlap the text when it next updates.
How do I clear the text/change the text?
Everything that is drawn is drawn on the target Surface. The entire scene has to be redrawn in each frame. Therefore, the display must be cleared at the beginning of each frame in the application loop:
while run:
# [...]
# clear display
WIN.fill((0, 0, 0))
# draw scene
display(t, t.get_rect(center = (WIN.get_width() // 2, WIN.get_height() * .07)))
# update disaply
pygame.display.update()
I have a single battery image appearing once here and it moves from right to left then goes away. I want batteries constantly coming and going until the player hits one of them.
My question is how do I get the batteries to keep on coming until a player hits it? I want them to appear maybe 100 units apart.
from pygame import *
import os
import random
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 0)
init()
#set screen size
size = width, height = 800, 600
screen = display.set_mode(size)
#set fonts
fontGame=font.SysFont("Times New Roman", 30)
fontBack=font.SysFont("Ariel", 30)
fontTitle=font.SysFont("Ariel", 100)
fontResearch=font.SysFont ("Times New Roman", 18)
#set button and page to 0
button = 0
page=0
#setting colours
BLACK = (0, 0, 0)
RED = (255,0,0)
GREEN = (0, 255, 0)
BLUE = (106,186,232)
#loading image
backgroundPic=image.load("Background.jpg")
backgroundGame=image.load("gameBackground.jpg")
backgroundGame=transform.scale(backgroundGame,(800,600))
battery=image.load("Battery.png")
battery=transform.scale(battery,(100,100))
backgroundx=0
playerPic=image.load("player.png")
playerPic=transform.scale(playerPic,(70,70))
batteryx=[]
#defining what is going to be shown on the screen
def drawScene(screen, button,page,locationx,locationy):
global batteryx
mx, my = mouse.get_pos() #will get where the mouse is
#if the user does nothing
if page==0:
draw.rect(screen, BLACK, (0,0, width, height))
screen.fill(BLACK)
rel_backgroundx= backgroundx % backgroundGame.get_rect().width
screen.blit(backgroundGame, (rel_backgroundx - backgroundGame.get_rect().width,0))
if rel_backgroundx < width:
screen.blit (backgroundGame, (rel_backgroundx,0))
screen.blit(playerPic,(locationx,locationy))
screen.blit(battery,(batteryx,420))
batteryx-=1
display.flip()
return page
#def collision (battery, playerPic):
#if battery.colliderect(playerPic):
#return True
#return False
running = True
myClock = time.Clock()
KEY_LEFT= False
KEY_RIGHT= False
KEY_UP= False
KEY_DOWN= False
locationx=0
jumping=False
accel=20
onGround= height-150
locationy=onGround
batteryx=random.randrange(50,width,10)
# Game Loop
while running:
button=0
print (KEY_LEFT, KEY_RIGHT)
for evnt in event.get(): # checks all events that happen
if evnt.type == QUIT:
running=False
if evnt.type == MOUSEBUTTONDOWN:
mx,my=evnt.pos
button = evnt.button
if evnt.type== KEYDOWN:
if evnt.key==K_LEFT:
KEY_LEFT= True
KEY_RIGHT= False
if evnt.key==K_RIGHT:
KEY_RIGHT= True
KEY_LEFT= False
if evnt.key==K_UP and jumping==False:
jumping=True
accel=20
if evnt.key== K_DOWN:
KEY_DOWN= True
KEY_UP= False
if evnt.type==KEYUP:
if evnt.key==K_LEFT:
KEY_LEFT= False
if evnt.key==K_RIGHT:
KEY_RIGHT= False
if evnt.key==K_DOWN:
KEY_DOWN=False
if KEY_LEFT== True:
locationx-=10
backgroundx+=10
if KEY_RIGHT== True:
locationx+=10
backgroundx-=10
if jumping==True:
locationy-=accel
accel-=1
if locationy>=onGround:
jumping=False
locationy=onGround
#player cannot move off screen
if locationx<0:
locationx=0
if locationx>400:
locationx=400
#if collision(battery, playerPic)==True:
#screen.fill(BLACK)
page=drawScene(screen,button,page,locationx,locationy)
myClock.tick(60) # waits long enough to have 60 fps
if page==6: #if last button is clicked program closes
running=False
quit()
Create a list of rects which serve as the positions of the batteries. Use for loops to update the rects and blit the battery image at the rects. Remove rects that have left the screen and append new rects to create new batteries
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
battery_image = pg.Surface((30, 50))
battery_image.fill(pg.Color('sienna1'))
# Append pygame.Rect objects to this list.
batteries = []
batteries.append(battery_image.get_rect(topleft=(700, 100)))
battery_speed = -5
battery_timer = 40
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# A simple frame based timer.
battery_timer -= 1
if battery_timer <= 0:
battery_timer = 40
# After 40 frames a new rect gets appended to the list.
batteries.append(battery_image.get_rect(topleft=(700, 100)))
temp_list = []
# Iterate over the rects to update them.
for battery_rect in batteries:
battery_rect.x += battery_speed
# Rects with x <= 50 won't be appended to the temp_list.
if battery_rect.x > 50:
temp_list.append(battery_rect)
# Assign the list with the remaining rects to the batteries variable.
batteries = temp_list
# Blit everything.
screen.fill(BG_COLOR)
for battery_rect in batteries:
screen.blit(battery_image, battery_rect)
pg.display.flip()
clock.tick(30)
pg.quit()
I am creating a flashcard game for my kid. Its about Dinos. I am having trouble making "Congrats, You got it right" appear on the screen. I have moved my code all over the place but no luck. Can someone please help me out.
To be clear, What I want to happen is when the user presses the number 1,2,3 on the keypad, and if the key is the correct answer that correlates to the question, the message "Congrats, You got it right!" should appear on the screen.
I know the keydown event right now is the return key, but I did that for testing purposes only. This is also the same for testtext variable. I was using that variable to see if I could print "Hello WOrld" to the screen.
I do have a feeling it has something to do with the loop that is running. My guess would be is that it does show up for a fraction of a second but disappears before anyone can see it.
import pygame, random
pygame.font.init()
pygame.init()
font = pygame.font.Font(None, 48)
#Created the window display
size = width, height = 800,800
screen = pygame.display.set_mode(size)
#Loads the images of the starting game Trex
#t_rex = pygame.image.load('trex1.png')
##Places the image on the screen
#screen.blit(t_rex,(150,50))
count = 0
score = 0
active = False
testtext = font.render("Hello WOrld", True, (250, 250, 250))
#The below code keeps the display window open until user decides to quie app
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
screen.blit(testtext, (200,699))
while count < 2:
screen.fill(0)
dinoQuestions = ["Does a t-rex eat meat?\n","Does a trycerotopes have 3 horns?\n"]
dinoAnswer = ["Yes\n", "No\n","Maybe\n"]
wordnum = random.randint(0, len(dinoQuestions)-1)
mainpic = pygame.image.load("trex1.png")
screen.blit(mainpic, (150, 20))
options = [random.randint(0, len(dinoAnswer)-1),random.randint(0, len(dinoAnswer)-1)]
options[random.randint(0,1)] = wordnum
question_display = font.render(dinoQuestions[wordnum].rstrip('\n'),True, (255, 255, 255))
text1 = font.render('1 - ' + dinoAnswer[options[0]].rstrip('\n'),True, (255, 255, 255))
text2 = font.render('2 - ' + dinoAnswer[options[1]].rstrip('\n'),True, (255, 255, 255))
#the below code is for testing purposes only
screen.blit(question_display,(200, 590))
screen.blit(text1, (200, 640))
screen.blit(text2, (200, 690))
count = count + 1
pygame.display.flip()
The blit to your screen surface you perform when handling a Return key down event is overwritten when you later call screen.fill(0).
I've rearranged your code a little and added displaying a result on appropriate key press.
import pygame
import random
pygame.init()
pygame.font.init()
font = pygame.font.Font(None, 48)
size = width, height = 800,800
screen = pygame.display.set_mode(size) #Created the window display
count = 0
score = 0
active = False
white = pygame.color.Color("white")
black = pygame.color.Color("black")
green = pygame.color.Color("green")
# load/create static resources once
mainpic = pygame.image.load("trex1.png")
testtext = font.render("Hello World", True, (250, 250, 250))
correct_text = font.render("Correct! Well Done!", True, green)
clock = pygame.time.Clock() # for limiting FPS
dinoQuestions = ["Does a t-rex eat meat?","Does a triceratops have 3 horns?"]
dinoAnswer = ["Yes", "No","Maybe"]
# initialise state
show_hello = False
show_correct = False
update_questions = True # need to update questions on the first iteration
finished = False
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finished = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
show_hello = not show_hello # toggle flag for later display
elif event.key == pygame.K_SPACE:
update_questions = True
elif event.key in [pygame.K_1, pygame.K_2]:
# an answer has been selected
# pygame.K_1 is 0, pygame.K_2 is 1
if dinoAnswer[event.key - pygame.K_1] == "Yes":
show_correct = True
count += 1
else:
show_correct = False
screen.fill(black)
screen.blit(mainpic, (150, 20))
if show_hello:
screen.blit(testtext, (200,199))
if show_correct:
screen.blit(correct_text, (200, 300))
if update_questions:
random.shuffle(dinoQuestions)
random.shuffle(dinoAnswer)
question_display = font.render(dinoQuestions[0],True, white)
text1 = font.render('1 - ' + dinoAnswer[0],True, white)
text2 = font.render('2 - ' + dinoAnswer[1],True, white)
update_questions = False
show_correct = False
# Display the Question
screen.blit(question_display,(200, 590))
screen.blit(text1, (200, 640))
screen.blit(text2, (200, 690))
# count = count + 1
pygame.display.flip()
clock.tick(60)
Hopefully this is enough of a framework for you to extend.
Let me know if you have any questions about any portions of the code.
I am a bit confused about what your exact problem is, so I'm going to try to answer. You say that you want the words "Congrats, , you got it right!", so I can help you with what went wrong. You blit the testtext before you color the screen, so each time the loop loops, it displays the testtext but then almost instantly covers it up with screen.fill(0). To make it better, you should put the blitting of the text after the screen is colored. The best way to do this is to put it right at the start of the loop, or making another event detector after the current position of the screen.fill in the code.
Also, I would get rid of the stacked while loop, and instead replace it with if statement because it is already in the while loop.
Is this what you were looking for?
I'm making a basic game where I have a surface and everytime I click on the surface it moves 5 pixels to the right. The program is working just fine without the checkCollide(event) function, but when I put the that condition it doesn't move. What is wrong?
My code until now is this
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((300,300))
def checkCollide(event):
k = 0
a,b = event.pos
x = P1[0].get_rect()
if x.collidepoint(a,b):
return True
return False
CP1 = [(150, 150)
,(155, 150)
,(160, 150)
,(165, 150)
,(170, 150)
,(175, 150)
,(180, 150)
,(185, 150)
,(190, 150)]
statp1_1 = 0
WHITE = (255,255,255)
DISPLAYSURF.fill(WHITE)
while True: # the main game loop
P1 = [pygame.image.load('PAzul.png'),CP1[statp1_1],statp1_1]
DISPLAYSURF.blit(P1[0], P1[1])
e = pygame.event.get()
for event in e:
if event.type == MOUSEBUTTONUP:
a = checkCollide(event)
if a:
DISPLAYSURF.fill(WHITE)
statp1_1 +=1
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
Thank you
Check your logic in these lines of your function:
x = P1[0][0].get_rect()
if x.collidepoint(a,b):
return True
return False
Your code hinges on this bit:
a = checkCollide(event)
if a:
DISPLAYSURF.fill(WHITE)
So you're never evaluating this piece to be true.
I just realized what was wrong. When I do x = P1[0].get_rect() it creates a surface with topleft at (0,0).
What I needed to do was change the position of the rectangle using x.topleft = P1[1]
I've got some tips for you. First store the rect in the P1 list (it contains only the image and the rect in the following example, but maybe you could also add the statp1_1 index to it). Now we can just move this rect, if the user clicks on it (in the example I set the topleft attribute to the next point). Read the comments for some more tips. One thing you need to fix is to prevent the game from crashing when the statp1_1 index gets too big.
import sys
import pygame
pygame.init()
DISPLAYSURF = pygame.display.set_mode((300, 300))
WHITE = (255, 255, 255)
# Don't load images in your while loop, otherwise they have to
# be loaded again and again from your hard drive.
# Also, convert loaded images to improve the performance.
P1_IMAGE = pygame.image.load('PAzul.png').convert() # or .convert_alpha()
# Look up `list comprehension` if you don't know what this is.
CP1 = [(150+x, 150) for x in range(0, 41, 5)]
statp1_1 = 0
# Now P1 just contains the image and the rect which stores the position.
P1 = [P1_IMAGE, P1_IMAGE.get_rect(topleft=CP1[statp1_1])]
clock = pygame.time.Clock() # Use this clock to limit the frame rate.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONUP:
if P1[1].collidepoint(event.pos):
print('clicked')
statp1_1 += 1
# Set the rect.topleft attribute to CP1[statp1_1].
P1[1].topleft = CP1[statp1_1]
DISPLAYSURF.fill(WHITE)
DISPLAYSURF.blit(P1[0], P1[1]) # Blit image at rect.topleft.
pygame.display.update()
clock.tick(30) # Limit frame rate to 30 fps.
I'm new to Pygame and I'm trying to move my sprite on my background image.
My sprite is not re appearing after it moves? Any ideas?
This is most of the program without some screens.
I have been trying to get this to work for many hours,
#dependencies
import pygame as P
import random as R
def welcome(screen):
#load background
bg = P.image.load("space-wallpaper.jpg")
screen.blit(bg,[0,0])
#set fonts etc
font = P.font.Font("Space_Age.ttf",60)
width, height = screen.get_size()
#play button
message = "PLAY "
text = font.render(message,1,[255 , 0, 0])
rect = text.get_rect()
x, y = text.get_size()
rect = rect.move((width - x)/2, (height - y)/2)
screen.blit(text,rect)
#high_score button
message = "HIGH SCORE "
text = font.render(message,1,[255 , 0, 0])
rect = text.get_rect()
x, y = text.get_size()
rect = rect.move((width - x)/2, (height - y)/2 +100)
screen.blit(text,rect)
def play_button(screen):
"""launch welcome screen.
"""
#welcome screen play button
font = P.font.Font("Space_Age.ttf",60)
message = "PLAY "
play_x,play_y = font.size(message)
play_text = font.render(message,1,[255 , 0, 0])
width, height = 800,600
screen.blit(play_text,[(width - play_x)/2, (height - play_y)/2])
play_rect = play_text.get_rect().move((width - play_x)/2, (height - play_y)/2)
P.display.flip()
return(play_rect)
def welcome_background(screen):
# Welcome screen background
bg = P.image.load("space-wallpaper.jpg")
screen.blit(bg,[0,0])
P.display.update()
def high_score_screen(screen):
"""opens the highscore screen"""
high_score_bg = P.image.load("bg_game.jpg")
screen.blit(high_score_bg,[0,0])
P.display.update()
def splash_screen(screen):
"""loads the first screen in the game with a 3 sec wait"""
splash_image = P.image.load('splash.jpg')
screen.blit(splash_image,[0,0])
P.display.update()
P.time.wait(2001)
def play_game(screen):
"""loads the play game screen"""
game_bg = P.image.load("bg_game.jpg")
screen.blit(game_bg,[0,0])
P.display.update()
def move_right(screen,x_cord,flagship):
dist = 20
play_game(screen)
x_cord = x_cord + dist
print(x_cord)
screen.blit(flagship,[x_cord])
P.display.update()
def key_detection(screen,flagship,x_cord):
key = P.key.get_pressed()
if key[P.K_RIGHT]:
move_right(screen,x_cord,flagship)
#move_right()
elif key[P.K_LEFT]:
print("left")
class Sprite():
def __init__(self,screen):
""" The constructor of the class """
self.flagship = P.image.load("sprite2.png")
self.x = 0
self.y = 0
def display(self,screen):
#screen.blit(self.sprite,[self.x,self.y]) changed by geoff
screen.blit(self.flagship,[self.x,self.y])
P.display.update()
_init_
# dependencies
from mods import *
import pygame as P
#initialise pygame
P.init()
def main():
# parameters to control pygame basics
screen_size = width, height = 800,600 #sixe of playing screen
P.display.set_caption('Space Smasher!')
screen = P.display.set_mode(screen_size)
clock = P.time.Clock() # timer used to control rate of looping
loop_rate = 20 #number of times per second does loop
play = True #control the playing of the actual game
splash_screen(screen)
welcome(screen)
P.display.flip()
rect_play = play_button(screen)
flagship = Sprite(screen)
while play:
key_detection(screen,flagship.image,flagship.x)
# for event in P.event.poll(): changed by geoff
event = P.event.poll() #did the player do something?
if event.type == P.QUIT:
play = False
if event.type == P.MOUSEBUTTONDOWN:
player_position = P.mouse.get_pos()
if rect_play.collidepoint(player_position):
play_game(screen)
flagship.display(screen)
P.quit()
if __name__ == '__main__':
main()
You are not calling either of your functions or your classes anywhere. You need a while loop that is similarly structured to this:
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#Do your movements
With the following imports at the top:
import pygame, sys
from pygame.locals import *
Here is an example of moving an object with the keys:
import pygame, sys
from pygame.locals import *
pygame.init()
WIDTH=1439
HEIGHT=791
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Hello Pygame World!')
pygame.key.set_repeat(1, 10)
circx, circy = 200, 150
CIRWIDTH=20
while True: # main game loop
if pygame.key.get_pressed()[pygame.K_UP]:
circy-=5
if pygame.key.get_pressed()[pygame.K_DOWN]:
circy+=5
if pygame.key.get_pressed()[pygame.K_RIGHT]:
circx+=5
if pygame.key.get_pressed()[pygame.K_LEFT]:
circx-=5
try:
for event in pygame.event.get():
if event.type == QUIT or event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
pygame.quit()
sys.exit()
except AttributeError:
pass
DISPLAYSURF.fill((0, 0, 0))
pygame.draw.circle(DISPLAYSURF, (158, 219, 222), (circx, circy), CIRWIDTH)
pygame.display.flip()
Main loop should be similar to:
while True:
# events - check keyboad and mouse and change player direction or speed
# move - move sprite with speed and direction
# check collison
# draw background, all objects and all sprites
# clock - to keep constant speed - FPS (Frames Per Seconds)
So you have to move sprites in every loop and draw them.