How to fix this error with pygame and fonts [duplicate] - python

This question already has answers here:
pygame - How to display text with font & color?
(7 answers)
Closed 1 year ago.
import pygame, sys
pygame.init()
clock = pygame.time.Clock()
coordinate = pygame.mouse.get_pos()
screen = pygame.display.set_mode((1000,800), 0, 32)
pygame.display.set_caption("Mouse Tracker")
font = pygame.font.Font(None, 25)
text = font.render(coordinate, True, (255,255,255))
while True:
screen.fill((0,0,0))
screen.blit(text, (10, 10))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
clock.tick(60)
I am trying to make a program that tracks your mouse and shows the coordinates of it on the sreen. I get an error saying:
text = font.render(coordinate, True, (255,255,255))
TypeError: text must be a unicode or bytes.
I am using Python 3.9.1

There are couple of changes to be made:
coordinate = pygame.mouse.get_pos() returns a tuple which the variable coordinate is assigned to. The font.render() method takes a string as an argument not a tuple. So first you need to render the str(coordinate) and not just the coordinate which is actually a tuple. You can read more about rendering the font in pygame here
text = font.render(str(coordinate), True, (255,255,255)) #Rendering the str(coordinate)
Step one alone won't make your code functional, there are still some problems in your code. For blitting the coordinate of the mouse to the screen, you need to get the mouse coordinates at every single frame. For that to function you need to place the line coordinate = pygame.mouse.get_pos() in the while True loop, along with this you also need to place this line text = font.render(str(coordinate), True, (255,255,255)) in the while loop
import pygame,sys
#[...]#part of code
while True:
coordinate = pygame.mouse.get_pos() #Getting the mouse coordinate at every single frame
text = font.render(str(coordinate), True, (255,255,255))
#[...] other part of code
So the final working code should look somewhat like:
import pygame, sys
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1000,800), 0, 32)
pygame.display.set_caption("Mouse Tracker")
font = pygame.font.Font(None, 25)
while True:
coordinate = pygame.mouse.get_pos() #Getting the mouse coordinate at every single frame
text = font.render(str(coordinate), True, (255,255,255)) #Rendering the str(coordinate)
screen.fill((0,0,0))
screen.blit(text, (10, 10))
for event in pygame.event.get():
if event.type == pygame.QUIT:#
pygame.quit()
sys.exit()
pygame.display.update()
clock.tick(60)

Related

How can i give my image an initial position before it starts moving with the mouse?

I'm working on this pygame game and i'm just getting started but got a bit confused because i want the image to move in the x-axis along with the mouse but when i run the program i want the image to show up at the center or the 'floor' but appears at the left side instead. This is my code and a screenshot of what's happening.
import pygame
import sys
pygame.init()
pygame.mixer.init()
WIDTH, HEIGHT = 400, 500
FPS = 60
TITLE = 'FOOD DROP'
SIZE = 190
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE_SKY = (152, 166, 255)
# Display
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
# Surfaces
floor_surface = pygame.Surface((WIDTH, 100))
floor_surface.fill(BLUE_SKY)
floor_rect = floor_surface.get_rect(midbottom=(200, 500))
# Images
LOAD_DITTO = pygame.image.load('Graphics/ditto.png')
DITTO = pygame.transform.scale(LOAD_DITTO, (SIZE, SIZE))
# Time
CLOCK = pygame.time.Clock()
class Figure:
def draw_figure(self, mouse_x):
SCREEN.blit(DITTO, (mouse_x - 90, 330))
# Game loop
SCREEN_UPDATE = pygame.USEREVENT
# main_game = Main()
figure = Figure()
running = True
while running:
CLOCK.tick(FPS)
mx, my = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
When i run the program, this happens:
And i want the image to appear right at the center or the x-axis, not the border, i don't know why is this happening. Just to state, that screenshot was taken when the mouse hadn't been placed over the display.
If the mouse pointer is not in the window (out of focus), the initial position of the mouse pointer is (0, 0). Therefore pygame.mouse.get_pos returns (0, 0). It is also not possible to set the mouse position with pygame.mouse.set_pos if it is not in the window.
Initialize the variables mx and mx with the center of the window. Change the mouse position only when the mouse pointer is in the window (in focus). pygame.mouse.get_focused can be used to test whether the mouse is in the window.
mx, my = SCREEN.get_rect().center
running = True
while running:
CLOCK.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if pygame.mouse.get_focused():
mx, my = pygame.mouse.get_pos()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
pygame.quit()
sys.exit()

how to update displaying user input text in pygame?

I'm writing a basic program with pygame that in some part needs to take an text input from the user. My problem is that when the user wants to erase part of the text, the old text keeps displaying it in the pygame window.
Let's say the user types '23' and then presses backspace. The console shows 2 but the pygame window will keep displaying 23.
I'm using:
if event.key == pg.K_BACKSPACE:
text = text[:-1]
You have to (re)render the text surface after changing the text and you have to clear the display in every frame:
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((400, 200))
font = pygame.font.SysFont(None, 40)
clock = pygame.time.Clock()
text = ""
text_surf = font.render(text, True, (0, 0, 0))
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_BACKSPACE:
text = text[:-1]
else:
text += event.unicode
text_surf = font.render(text, True, (0, 0, 0))
window_center = window.get_rect().center
window.fill((255, 255, 255))
window.blit(text_surf, text_surf.get_rect(center = window_center))
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()
The typical PyGame application loop has to:
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()
limit the frames per second to limit CPU usage with pygame.time.Clock.tick

Pygame: How to catch user input after they press the ENTER key

I am making a text based RPG as my first python/pygame project. In my game I would like to present the player with choices then ask them to type it in. I was able to download and import a module which accepts user input and displays it on the screen. However, before using it for anything like..lets say, if the user input is 'yes', then they go to a new area, I'd like the program to only accept the user input once they hit the enter key. I believe the tutorial for the textinput module I downloaded has directions to do this, but to be honest I just don't understand what it's saying. I've tried multiple types of loops but nothing is happening. Any help will be appreciated. Here is my main game code:
import pygame_textinput
import pygame
pygame.init()
#fps
clock=pygame.time.Clock()
# create font here
font_name = pygame.font.get_default_font()
WHITE_TEXT_COLOR = (255, 255, 255)
# create screen and window and display and font here
screen_width, screen_height = 800, 700
background_color_black = (0, 0, 0)
screen = pygame.display.set_mode((screen_width, screen_height))
our_game_display = pygame.Surface((screen_width, screen_height))
pygame.display.set_caption('MyRPGGame')
#create text input object
textinput = pygame_textinput.TextInput()
def draw_text(text, size, x, y):
pygame.font.init()
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, WHITE_TEXT_COLOR)
text_rect = text_surface.get_rect()
text_rect.center = (x, y)
our_game_display.blit(text_surface, text_rect)
def choose_to_play():
draw_text("You've decided to play",20,screen_width/2,screen_height/2+50)
def first_area():
our_game_display.fill(background_color_black)
draw_text('The story of this game depends on your choices. Do you wish to play?', 20, screen_width / 2,screen_height / 2 - 100)
draw_text('Type your answer and hit enter.', 20, screen_width / 2,screen_height / 2 - 50)
draw_text('Yes', 20, screen_width/2,screen_height/2+50)
draw_text('No', 20, screen_width/2,screen_height/2+100)
screen.blit(our_game_display, (0, 0))
pygame.display.update()
while True:
our_game_display.fill((background_color_black))
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
exit()
first_area()
# Feed it with events every frame
textinput.update(events)
# Blit its surface onto the screen
screen.blit(textinput.get_surface(), (10, 600))
pygame.display.update()
clock.tick(30)
Now here is the source for the pygame textinput module, figured I would link to the code so this post isn't too crowded:
https://github.com/Nearoo/pygame-text-input
You need to a variable for the state of the game. Once enter is pressed change the state. Implement different cases in the application loop depending on the state of the game::
game_state = 'start'
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
game_state = 'input'
our_game_display.fill((background_color_black))
if game_state == 'input':
textinput.update(events)
# [...]

Pygame, how to make circle disappear and appear with MOUSEBUTTONDOWN? [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
How do I detect if the mouse is hovering over a button? PyGame button class is not displaying the text or changing colour on hover
(1 answer)
Closed 2 years ago.
I'm new to using Pygame and have a question about MOUSEBUTTONDOWN and pygame.draw.circle()
When clicking the 62.5x62.5 square inside of the screen , I want it to show a green circle and when
clicking it again, I want it to disappear. I don't know how to do it and in my code I have to spam click the square for the circle to appear for a split second then it disappears again. I've also tried using a while loop but couldn't make it work.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
running = True
while running:
screen.fill((0, 0, 0))
mouse_pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN and mouse_pos[0] >= 150 and mouse_pos[0] <= 212.5 \
and mouse_pos[1] >= 425 and mouse_pos[1] <= 487.5:
pygame.draw.circle(screen, (152, 251, 152), (181.25, 393.75), 20)
pygame.display.update()
You need to draw the circle in the event loop rather than in the event loop. Add a Boolean variable draw_circle and toggle the state of the variable when you click the mouse.
You can't draw with floating point accuracy. Pixels and the mouse position have integral units.
Use a pygame.Rect object and collidepoint() for the click test. The position of the mouse click is stored in the pos attribute of the pygame.event.Event() object:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
draw_circle = False
test_rect = pygame.Rect(0, 0, 40, 40)
test_rect.center = (181, 393)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if test_rect.collidepoint(event.pos):
draw_circle = not draw_circle
screen.fill((0, 0, 0))
pygame.draw.rect(screen, (127, 127, 127), test_rect, 1) # for debugging
if draw_circle:
pygame.draw.circle(screen, (152, 251, 152), (181, 393), 20)
pygame.display.update()

Fill only one half of a display in Pygame?

I am new to Pygame and I wish to fill only certain parts of my screen, for example the half. Currently I am only able to fill the complete screen. Can someone help?
import pygame
color= (255, 0, 0)
screen = pygame.display.set_mode((740, 780))
screen.fill(color)
The 2nd parameter of .fill() is a rectangle, which defines the area to be filled.
The width and height of a pygame.Surface object can be get by .get_width() respectively .get_height():
e.g.
screen.fill(color, (0, 0, screen.get_width()// 2, screen.get_height()))
import pygame
size = w,h = 300, 400
scr = pygame.display.set_mode((w,h))
pygame.display.set_caption("Hello")
scr.fill((0,255,0), rect=(0,0,w,h/2))
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
running = False
One way to have partial fill may include "drawing" a shape (i.e. rectangle) on half of the screen.
import sys
import pygame
def half_screen():
#Initialize game and create screen object.
pygame.init()
color= (255, 0, 0)
screen = pygame.display.set_mode((200, 400))
#Draw rectangle to fill the left half of the screen.
left_half = pygame.draw.rect(screen, color,(0,0, 100, 400))
#Start loop for game- keeps screen open until you decide to quit.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#Make the current screen visible.
pygame.display.flip()
half_screen()
You can find more information on the draw module - pygame.draw - by going to https://www.pygame.org/docs/ref/draw.html

Categories

Resources