How can i make a score increase in pygame - python

I am trying to make a score system so that whenever i click "j", the score in the top left of the screen, the score increases. It worked but the previous score stays on the screen, so to resolve this i decided to put a small Rect object over the score, then paint the new score over the Rect, but it is not working, please help. This is the function for the increasing score:
def score_increase():
global score
score += 1
font = pygame.font.SysFont("Comic Sans", 50, True, False)
surface = font.render(str(score), True, (130, 46, 75))
pygame.draw.rect(screen, ((35, 140, 120)), (0, 0, 50, 75))
screen.blit(surface, (0, 0))
This is the rest of my code if it helps:
import pygame, sys, random
from pygame.locals import *
pygame.init()
pygame.display.set_caption("waht da dog doin")
screen = pygame.display.set_mode((800, 600))
screen.fill((35, 140, 120))
dog = pygame.image.load("resources/dog.jpg").convert()
score = 0
font = pygame.font.SysFont("Comic Sans", 50, True, False)
surface = font.render(str(score), True, (130, 46, 75))
screen.blit(surface, (0, 0))
troll = ["corned", "balled", "chimkened", "torkelled", "kanaquined", "khazaqed", "bo burnam'd", "talal'd", "chammaked", "australiad", "lotto pie'd", "tetrised", "caca'd", "scrutinized", "bulbasaured"]
troll_item = random.choice(troll)
dog_y = random.randint(0, 400)
dog_x = random.randint(0, 500)
text_y = random.randint(0, 400)
text_x = random.randint(0, 500)
def score_increase():
global score
score += 1
font = pygame.font.SysFont("Comic Sans", 50, True, False)
surface = font.render(str(score), True, (130, 46, 75))
pygame.draw.rect(screen, ((35, 140, 120)), (0, 0, 50, 75))
screen.blit(surface, (0, 0))
def print_trolled():
screen.fill((35, 140, 120))
screen.blit(dog, (dog_x, dog_y))
font = pygame.font.SysFont("Comic Sans", 30, True, True)
surface_text = font.render("u have been" + " " + troll_item, True, (130, 46, 75))
screen.blit(surface_text, (text_x, text_y))
def start_print():
font = pygame.font.SysFont("Comic Sans", 50, True, False)
surface = font.render("press 'j' plsz", True, (130, 46, 75))
screen.blit(surface, (250, 250))
#def again_print():
font = pygame.font.SysFont("Comic Sans", 50, True, True)
surface = font.render("do it again", True, (130, 46, 75))
screen.blit(surface, (text_x, text_y))
start_print()
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
pass
if event.key == K_j:
print_trolled()
score_increase()
screen.blit(surface, (0, 0))
dog_y = random.randint(0, 400)
dog_x = random.randint(0, 500)
text_y = random.randint(0, 400)
text_x = random.randint(0, 500)
troll = ["corned", "balled", "chimkened", "torkelled", "kanaquined", "khazaqed", "bo burnam'd", "talal'd", "chammaked", "australiad", "lotto pie'd", "tetrised", "caca'd", "scrutinized", "bulbasaured"]
troll_item = random.choice(troll)
if event.type == QUIT:
sys.exit
if event.type == K_ESCAPE:
sys.exit
pygame.display.update()

You have to draw the scene in the application loop. Increment score and render a core_surface in score_increase
core_surface = None
def score_increase():
global score, score_surface
score += 1
font = pygame.font.SysFont("Comic Sans", 50, True, False)
score_surface = font.render(str(score), True, (130, 46, 75))
But redraw the entire scene in the a application loop in every frame:
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
pass
if event.key == K_j:
score_increase()
dog_y = random.randint(0, 400)
dog_x = random.randint(0, 500)
text_y = random.randint(0, 400)
text_x = random.randint(0, 500)
troll = ["corned", "balled", "chimkened", "torkelled", "kanaquined", "khazaqed", "bo burnam'd", "talal'd", "chammaked", "australiad", "lotto pie'd", "tetrised", "caca'd", "scrutinized", "bulbasaured"]
troll_item = random.choice(troll)
if event.type == QUIT:
sys.exit
if event.type == K_ESCAPE:
sys.exit
screen.fill(0)
start_print()
print_trolled()
score_surface = font.render(str(score), True, (130, 46, 75))
pygame.draw.rect(screen, ((35, 140, 120)), (0, 0, 50, 75))
if score_surface:
screen.blit(score_surface, (0, 0))
pygame.display.update()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()

Related

why cannot the "for" loop to get the value from the list?

when I use "rb = random.choice(myList) and bFont", it's function.
then I use "for i in range(len(myList)) and bFont" and click,
it cannot loop, just display a fix list value, why?
import pygame
import random
import re
pygame.mixer.init()
pygame.init()
size = (1280, 580)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("1")
bg = pygame.image.load("b")
white = (0, 0, 0)
black = (230, 0, 100)
light_grey = (224, 224, 224)
dark_grey = (200, 200, 200)
text = pygame.font.SysFont("Agency FB", 20)
myList = ["a5一个5ˈei", "am5是5æm", "are5是5a:r"]
font = pygame.font.Font('./simhei.ttf', 25)
button_text = font.render("aaaaa", True, black)
button_rect = pygame.Rect(70, 350, 200, 200)
bFont = None
var = True
while var:
mouse = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
var = False
if event.type == pygame.MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
for i in range(len(myList)):
#rb = random.choice(myList)
bFont = font.render(myList[i], True, white)
bFont1 = font.render(myList[i], True, white)
#bFont = font.render(rb, True, white)
#bFont1 = font.render(rb, True, white)
screen.blit(bg, (0, 0))
if button_rect.collidepoint(mouse):
pygame.draw.rect(screen, dark_grey, (70, 350, 200, 200), 0)
else:
pygame.draw.rect(screen, light_grey, (70, 350, 200, 200), 0)
screen.blit(button_text, (90, 450))
if bFont:
screen.blit(bFont, (70, 100))
screen.blit(bFont1, (70, 220))
pygame.display.update()
\help me
\help

is there a way to clear the screen once a key has been pressed? [duplicate]

I have made a class and in the draw function, I draw a textarea, some static text, and color the screen. The draw function is in a while loop. I want the whole pygame screen to clear except for the input box and I want the screen to change color. How do I do that? My code is below:
import pygame
from Settings import *
from TextInput import *
from Draw import *
pygame.init()
pygame.font.init()
class Txt():
def __init__(self):
self.running = True
pygame.display.set_caption('TruTxt')
self.input_box = InputBox(50, 550, 1200, 300)
def run(self):
while self.running:
self.events()
self.draw()
def events(self):
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.K_RETURN:
pass
self.input_box.handle_event(event)
def draw(self):
start()
self.input_box.draw(screen)
pygame.display.flip()
t = Txt()
while t.running:
t.run()
pygame.quit()
def start():
screen.fill((0, 0, 255))
myfont = pygame.font.SysFont('Comic Sans MS', 64, True)
displaytxt = myfont.render(hellotxt , True, (255, 255, 255))
screen.blit(displaytxt, (300, 30))
myfont = pygame.font.SysFont('Comic Sans MS', 24)
displaytxt = myfont.render(wlcmtxt , True, (255, 215, 0))
screen.blit(displaytxt, (30, 200))
myfont = pygame.font.SysFont('Comic Sans MS', 39, True)
displaytxt = myfont.render(strttxt , True, (255, 255, 255))
screen.blit(displaytxt, (28, 370))
myfont = pygame.font.SysFont('Comic Sans MS', 28, False, True)
displaytxt = myfont.render(destxt , True, (255, 215, 0))
screen.blit(displaytxt, (165, 450))`
from your summary at the top of your post i can conclude that what you need to do is simply redraw the screen at every iteration of the loop
screen.fill(color)
#redraw screen

How to update text appearing on button click in pygame module

I was making a code where on clicking a button, a string will be chosen randomly from myList and be displayed. I am doing this using pygame module. The problem here is that the text does not remain, it just flashes for one frame.
Here's the code:
import pygame
import random
pygame.init()
size = (500, 400)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Project")
bg = pygame.image.load("bg.jpg")
# declaring variables and lists
white = (255, 255, 255)
black = (0, 0, 0)
light_grey = (224, 224, 224)
dark_grey = (200, 200, 200)
text = pygame.font.SysFont("Agency FB", 20)
myList = ["China", "Italy", "Russia", "India", "USA", "Canada", "France", "Japan", "Brazil", "Egypt"]
# text for button
button_text = text.render("Country", True, black)
rb = random.choice(myList)
font = pygame.font.SysFont("Agency FB", 50)
bFont = font.render(str(rb), True, white)
var = True
while var:
screen.blit(bg, (0, 0))
# store mouse position
mouse = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
var = False
# button click
if event.type == pygame.MOUSEBUTTONDOWN:
# pick one from list and blit
if 50 <= mouse[0] <= 50 + 75 and 350 <= mouse[1] <= 350 + 35:
screen.blit(bFont, (50, 100))
# make button
if 50 <= mouse[0] <= 50 + 75 and 350 <= mouse[1] <= 350 + 35:
pygame.draw.rect(screen, dark_grey, (50, 350, 75, 35), 0)
else:
pygame.draw.rect(screen, light_grey, (50, 350, 75, 35), 0)
screen.blit(button_text, (55, 355))
pygame.display.update()
How can I get the text to be there and not vanish in the next frame?
Do not create bFont before the main application loop, but initialize it with None:
bFont = None
Choose and render a random string when the button is pressed:
while var:
# [...]
for event in pygame.event.get():
# [...]
# button click
if event.type == pygame.MOUSEBUTTONDOWN:
# pick one from list and blit
button_rect = pygame.Rect(50, 350, 75, 35)
if button_rect.collidepoint(event.pos):
rb = random.choice(myList)
bFont = font.render(str(rb), True, white)
Draw the text in the main application loop if bFont is set:
var = True
while var:
# [...]
if bFont:
screen.blit(bFont, (50, 100))
pygame.display.update()
Complete example:
import pygame
import random
pygame.init()
size = (500, 400)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Project")
bg = pygame.image.load("bg.jpg")
# declaring variables and lists
white = (255, 255, 255)
black = (0, 0, 0)
light_grey = (224, 224, 224)
dark_grey = (200, 200, 200)
text = pygame.font.SysFont("Agency FB", 20)
myList = ["China", "Italy", "Russia", "India", "USA", "Canada", "France", "Japan", "Brazil", "Egypt"]
# text for button
button_text = text.render("Country", True, black)
button_rect = pygame.Rect(50, 350, 75, 35)
font = pygame.font.SysFont("Agency FB", 50)
bFont = None
var = True
while var:
# store mouse position
mouse = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
var = False
# button click
if event.type == pygame.MOUSEBUTTONDOWN:
# pick one from list and blit
if button_rect.collidepoint(event.pos):
rb = random.choice(myList)
bFont = font.render(str(rb), True, white)
screen.blit(bg, (0, 0))
# make button
if button_rect.collidepoint(mouse):
pygame.draw.rect(screen, dark_grey, (50, 350, 75, 35), 0)
else:
pygame.draw.rect(screen, light_grey, (50, 350, 75, 35), 0)
screen.blit(button_text, (55, 355))
if bFont:
screen.blit(bFont, (50, 100))
pygame.display.update()
Try using another boolean var
if event.type == pygame.MOUSEBUTTONDOWN:
if 50 <= mouse[0] <= 50 + 75 and 350 <= mouse[1] <= 350 + 35:
show_text = True
if show_text:
time_check = pygame.time.get_ticks ()
b_font = font.render (random.choice (my_list), True,(255,255,255))
screen.blit (b_font, (50, 100)
if time_check >= 2000: #2000 miliseconds
show_text = False
time_check = 0
Here it will display your text for two seconds

How do you stop a method from running when you call another one?

When calling win.instructionScreen(screen, win), the instructions screen appears but the text from startScreen remains. Using screen.fill(BLACK) does not work because the main loop causes the text in startScreen to reappear, and using return to stop the startScreen method does not work.
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
class Game:
def __init__(self):
self.tickets = 0
def startScreen(self, screen, win):
titleText = pygame.font.SysFont('Showcard Gothic', 60)
subText = pygame.font.SysFont('Showcard Gothic', 20)
text = titleText.render("Our Game", True, WHITE)
cs = subText.render("Final Project", True, WHITE)
names = subText.render("Name 1, Name 2, Name 3, Name 4", True, WHITE)
screen.blit(text, [220, 200])
screen.blit(cs, [310, 265])
screen.blit(names, [150, 290])
mouse = pygame.mouse.get_pos()
if 493 > mouse[0] > 343 and 461 > mouse[1] > 411:
pygame.draw.rect(screen, RED, (343, 411, 150, 50))
else:
pygame.draw.rect(screen, GREEN, (343, 411, 150, 50))
buttonText = pygame.font.SysFont('Showcard Gothic', 30)
start = buttonText.render("Start!", True, WHITE)
screen.blit(start, [365, 425])
for event in pygame.event.get():
if 494 > mouse[0] > 343 and 461 > mouse[1] > 411:
if event.type == pygame.MOUSEBUTTONDOWN:
win.instructionScreen(screen, win)
pygame.display.update()
return
pygame.display.update()
def instructionScreen(self, screen, win):
background = pygame.image.load("background.png").convert()
screen.blit(background, [0, 0])
caption = pygame.image.load("caption.png").convert()
oak = pygame.image.load("oak.png").convert()
oak.set_colorkey(BLACK)
screen.blit(oak, [570, 130])
titleText = pygame.font.SysFont('Showcard Gothic', 60)
subText = pygame.font.SysFont('Showcard Gothic', 25)
text = titleText.render("Instructions", True, WHITE)
captionText = subText.render("Hey! Welcome to our game! Start by walking up", True, BLACK)
captionText2 = subText.render("to and playing Higher or Lower and racking up", True, BLACK)
captionText3 = subText.render("tickets. Then, when you get enough tickets,", True, BLACK)
captionText4 = subText.render("different games will be unlocked. Have fun!", True, BLACK)
screen.blit(text, [200, 80])
mouse = pygame.mouse.get_pos()
if 480 > mouse[0] > 325 and 550 > mouse[1] > 500:
pygame.draw.rect(screen, RED, (325, 500, 150, 50))
else:
pygame.draw.rect(screen, GREEN, (325, 500, 150, 50))
buttonText = pygame.font.SysFont('Showcard Gothic', 30)
screen.blit(caption, [3, 300])
pygame.draw.rect(screen, WHITE, (45, 320, 670, 110))
screen.blit(captionText, [45, 325])
screen.blit(captionText2, [45, 350])
screen.blit(captionText3, [45, 375])
screen.blit(captionText4, [45, 400])
play = buttonText.render("Play!", True, WHITE)
screen.blit(play, [357, 515])
#if 480 > mouse[0] > 325 and 550 > mouse[1] > 500:
# if event.type == pygame.MOUSEBUTTONDOWN:
# from gamescreen.py import gamescreen
pygame.display.update()
def clearScreen(self, screen):
screen.fill(WHITE)
def main():
pygame.init()
size = [800, 600]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Arcade City")
done = False
clock = pygame.time.Clock()
win = Game()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
done = True
win.startScreen(screen, win)
clock.tick(60)
if __name__ == "__main__":
main()
It's easier if you don't use nested functions. Call win.InstructionScreen() from the main function instead of from the method win.startScreen(). Use state variables to control the flow and return which state it should be from the methods.
win = Game()
current_screen = 'start'
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
done = True
if current_screen == 'start':
current_screen = win.startScreen(screen, win)
elif current_screen == 'instruction':
current_screen = win.instructionScreen(self, screen, win)
clock.tick(60)
This is just a mock-up, so you'll you have to change the methods after your own fittings. Put a return statement in both methods so they always return what the current screen should be.
TIP:
Instead of loading in your images and fonts every frame you could load them in the __init__ method and save them in a attribute variable.
EDIT:
To answer your actual question: You cannot stop an outer method to run. Think of it this way: You have a box in a room; can you get the box without entering the room? No. You have an inner method inside an outer method; can you get the inner method without entering the outer method? No.
If you only want the inner method to run without the outer method to be run, you have to call the inner method directly and not call the outer method.

Why is the Python/ Pygame program not running?

So, i'm developing a game for a school project. I'm sort of new to Python/ Pygame so there's still some stuff I don't understand. I made my whole project, without defining functions, I then learned about them and added them in. Ever since I added them, the Pygame window doesn't even show up. What's wrong?
I'm new to StackOverflow and don't know how to add this to a code sample. Could someone please do this for me? Thanks.
import pygame, math, sys, random
pygame.init()
#Variables
darkYellow = 204,204,0
grey = 102, 102, 102
black = 0, 0, 0
white = 255, 255, 255
red = 255,0,0
marroon = 120, 0, 0
green = 0,255,0
blue = 0,0,255
darkBlue = 0,0,128
resolution = 650, 600
myFont = pygame.font.SysFont("Times New Roman", 30)
myFont2 = pygame.font.SysFont("Times New Roman", 15)
myFont3 = pygame.font.SysFont("Times New Roman", 60)
redLeft = 150, 575
redRight = 280, 575
blackLeft = 370, 575
blackRight = 500, 575
radius = 20
def main():
global window
window = pygame.display.set_mode(resolution)
pygame.display.set_caption('Harrys Game')
window.fill(grey)
pygame.display.update()
#Main menu
def mainMenu():
rectWidth = 150
rectHeight = 40
#Draw buttons
pygame.draw.rect(window, (white),(250, 150, rectWidth, rectHeight),0)
pygame.draw.rect(window, (white),(250, 225, rectWidth, rectHeight),0)
pygame.draw.rect(window, (white),(250, 300, rectWidth, rectHeight),0)
highlight = pygame.draw.rect(window, (darkYellow),(250, 150, rectWidth, rectHeight),0)
pygame.display.update()
playGameText = myFont.render("Play Game", 1, red)
window.blit(playGameText, (260, 150))
optionsText = myFont.render("Options", 1, red)
window.blit(optionsText, (275, 225))
exitText = myFont.render("Exit", 1, red)
window.blit(exitText, (300, 300))
pygame.display.update()
def grid():
startBar = pygame.draw.lines(window, black, False, [(0,545.46),(541.7,545.46)], 5)
bar2 = pygame.draw.lines(window, black, False, [(0,490.92),(541.7,490.92)], 5)
bar3 = pygame.draw.lines(window, black, False, [(0,436.38),(541.7,436.38)], 5)
bar4 = pygame.draw.lines(window, black, False, [(0,381.84),(541.7,381.84)], 5)
bar5 = pygame.draw.lines(window, black, False, [(0,327.3),(541.7,327.3)], 5)
bar6 = pygame.draw.lines(window, black, False, [(0,272.76),(541.7,272.76)], 5)
bar7 = pygame.draw.lines(window, black, False, [(0,218.22),(541.7,218.22)], 5)
bar8 = pygame.draw.lines(window, black, False, [(0,163.68),(541.7,163.68)], 5)
bar9 = pygame.draw.lines(window, black, False, [(0,109.14),(541.7,109.14)], 5)
bar10 = pygame.draw.lines(window, black, False, [(0,54.6),(541.7,54.6)], 5)
#Draw side columns
rightBar = pygame.draw.lines(window, black, False, [(541.7,600),(541.7,0)], 5)
leftBar = pygame.draw.lines(window, black, False, [(108.3,600),(108.3,0)], 5)
centreBar = pygame.draw.lines(window, black, False, [(325,0),(325,600)], 5)
#Right column text
label1 = myFont2.render("You rolled a:", 1, black)
window.blit(label1, (545, 20))
rollLabel = myFont2.render("Hit space", 1, black)
window.blit(rollLabel, (545, 100))
rollLabel2 = myFont2.render("to roll again", 1, black)
window.blit(rollLabel2, (545, 117))
#Display column numbers
start1 = myFont.render("START", 1, black)
window.blit(start1, (8, 545.46))
side2 = myFont.render("2", 1, black)
window.blit(side2, (54.15, 490.92))
side3 = myFont.render("3", 1, black)
window.blit(side3, (54.15, 436.38))
side4 = myFont.render("4", 1, black)
window.blit(side4, (54.15, 381.84))
side5 = myFont.render("SAFE 5", 1, black)
side6 = myFont.render("6", 1, black)
window.blit(side6, (54.15, 272.76))
side7 = myFont.render("7", 1, black)
window.blit(side7, (54.15, 218.22))
side8 = myFont.render("8", 1, black)
window.blit(side8, (54.15, 163.68))
side9 = myFont.render("9", 1, black)
window.blit(side9, (54.15, 109.14))
side10 = myFont.render("10", 1, black)
window.blit(side10, (54.15, 54.6))
finish11 = myFont.render("FINISH", 1, black)
window.blit(finish11, (8, 0))
def counters():
redCountLeft = pygame.draw.circle(window, marroon, redLeft, radius)
redCountRight = pygame.draw.circle(window, marroon, redRight, radius)
blackCountLeft = pygame.draw.circle(window, black, blackLeft, radius)
blackCountRight = pygame.draw.circle(window, black, blackRight, radius)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); sys.exit();
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
#Dice roll
diceRoll = random.randint(1, 4)
diceRollLabel = myFont3.render(str(diceRoll), 1, black)
window.blit(diceRollLabel, (580, 35))
print("Dice roll test", diceRoll)
pygame.display.update()
You need to call your functions. When a function is defined, the interpreter does not execute that code. You need to call it later when you want that block of code to run, for example:
>>> def main():
... print('hi')
...
>>> # nothing printed
...
>>> main()
hi
Typically in Python, you will have a statement like:
if __name__ == '__main__':
main()
This means if this file is called as the main python module (passed to the python executable with python blah.py) then run the main() function. The main() function will contain the full program logic, calling out to other functions as needed.
For you code, you probably want something like (untested)
if __name__ == '__main__':
main() # initialise the window
while True:
mainMenu() # draw the mainMenu
grid() # draw the grid
counters() # draw the counters
# process events in this loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); sys.exit();
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
#Dice roll
diceRoll = random.randint(1, 4)
diceRollLabel = myFont3.render(str(diceRoll), 1, black)
window.blit(diceRollLabel, (580, 35))
print("Dice roll test", diceRoll)
pygame.display.update()
def grid() shouldn't be indented or the lines that should be a part of the grid() function need to be indented 4 spaces

Categories