How to fill shape white - python

Description
Hi, I am trying to make objects to take damage and I want to add a cool effect.
Problem
When I type this command: player.img.fill((255, 255, 255))
I get this:
and I want to get this:
Thanks!

First you have to get the mask from the image with pygame.mask.from_surface:
player_mask = pygame.mask.from_surface(player.img)
Then you can use to_surface to create an image from the mask. Make the background of the image transparent with set_colorkey():
mask_image = player_mask.to_surface(setcolor = (255, 255, 255))
mask_image.set_colorkey((0, 0, 0))
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((200, 100))
clock = pygame.time.Clock()
player_image = pygame.image.load('Bird.png')
player_mask = pygame.mask.from_surface(player_image)
mask_image = player_mask.to_surface(setcolor = (255, 255, 255))
mask_image.set_colorkey((0, 0, 0))
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill((0, 32, 64))
window.blit(player_image, player_image.get_rect(center = (50, 50)))
window.blit(mask_image, mask_image.get_rect(center = (150, 50)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()

Related

How to draw circle count down in pygame? [duplicate]

How can i make this kind of countdown in Pygame? (i'm looking for how could i make the circle's perimeter decrease, that's the issue, because displaying the time isn't hard )
Keep in mind that how long the perimeter of the circle is and the displayed time should be in proportion with each other.
Just use pygame.draw.arc and specify the stop_angle argument depending on the counter:
percentage = counter/100
end_angle = 2 * math.pi * percentage
pygame.draw.arc(window, (255, 0, 0), arc_rect, 0, end_angle, 10)
Minimal example:
import pygame
import math
pygame.init()
window = pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
counter = 100
text = font.render(str(counter), True, (0, 128, 0))
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, 1000)
def drawArc(surf, color, center, radius, width, end_angle):
arc_rect = pygame.Rect(0, 0, radius*2, radius*2)
arc_rect.center = center
pygame.draw.arc(surf, color, arc_rect, 0, end_angle, width)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == timer_event:
counter -= 1
text = font.render(str(counter), True, (0, 128, 0))
if counter == 0:
pygame.time.set_timer(timer_event, 0)
window.fill((255, 255, 255))
text_rect = text.get_rect(center = window.get_rect().center)
window.blit(text, text_rect)
drawArc(window, (255, 0, 0), (100, 100), 90, 10, 2*math.pi*counter/100)
pygame.display.flip()
pygame.quit()
exit()
Sadly the quality of pygame.draw.arc with a width > 1 is poor. However this can be improved, using cv2 and cv2.ellipse:
import pygame
import cv2
import numpy
pygame.init()
window = pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
counter = 100
text = font.render(str(counter), True, (0, 128, 0))
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, 1000)
def drawArcCv2(surf, color, center, radius, width, end_angle):
circle_image = numpy.zeros((radius*2+4, radius*2+4, 4), dtype = numpy.uint8)
circle_image = cv2.ellipse(circle_image, (radius+2, radius+2),
(radius-width//2, radius-width//2), 0, 0, end_angle, (*color, 255), width, lineType=cv2.LINE_AA)
circle_surface = pygame.image.frombuffer(circle_image.flatten(), (radius*2+4, radius*2+4), 'RGBA')
surf.blit(circle_surface, circle_surface.get_rect(center = center))
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == timer_event:
counter -= 1
text = font.render(str(counter), True, (0, 128, 0))
if counter == 0:
pygame.time.set_timer(timer_event, 0)
window.fill((255, 255, 255))
text_rect = text.get_rect(center = window.get_rect().center)
window.blit(text, text_rect)
drawArcCv2(window, (255, 0, 0), (100, 100), 90, 10, 360*counter/100)
pygame.display.flip()
pygame.quit()
exit()

Why my rectrangle does not appere(python 3.8 windoes 7) [duplicate]

This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why is nothing drawn in PyGame at all?
(2 answers)
Closed 1 year ago.
I tried to make a clone of a game but the rectangle (which is the basic shape that I will need)does not appear. What did I do wrong or its just pygame going crazy?
code:
# importing modules
import pygame
import sys
import random
# starting pygame
pygame.init()
# making a screen
(width, height) = (500, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Mincraft')
running = True
# fps counter
clock = pygame.time.Clock()
print(clock)
# geting the x button to work
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.update()
pygame.display.quit()
pygame.quit()
exit()
# colors
white = (255, 255, 255)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (4, 255, 0)
# cube
if running == True:
pygame.draw.rect(screen, blue, (395, 0, 10, 10)),
pygame.draw.rect(screen, blue, (395, 10, 10, 10)),
pygame.draw.rect(screen, blue, (395, 20, 10, 10)),
clock.tick(60)
and also how am I going to make it empty and 3d. I know I am asking for a lot but I believe someone can explain
You have to draw the scene in the application loop:
# importing modules
import pygame
import sys
import random
# colors
white = (255, 255, 255)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (4, 255, 0)
# starting pygame
pygame.init()
# making a screen
(width, height) = (500, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Mincraft')
running = True
# fps counter
clock = pygame.time.Clock()
print(clock)
# geting the x button to work
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.draw.rect(screen, blue, (395, 0, 10, 10))
pygame.draw.rect(screen, blue, (395, 10, 10, 10))
pygame.draw.rect(screen, blue, (395, 20, 10, 10))
pygame.display.update()
clock.tick(60)
pygame.display.quit()
pygame.quit()
exit()
The typical PyGame application loop has to:
handle the events by 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 either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick

Questions regarding the pygame.mask function

So I read the documentation of pygame but I could not understand it clearly. I recently asked a question about bitmap fonts and I got some code as my answer; here is the code:
import pygame
pygame.init()
win = pygame.display.set_mode((800, 600))
font = pygame.font.Font("freesansbold.ttf", 32)
i = 0
text = "hello how are you?"
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
letter = text[i]
text_1 = font.render(letter, True, (255, 255, 255))
bw, bh = font.size(letter)
glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects()
# print(glyph_rect)
if glyph_rect:
gh = glyph_rect[0].height
print(f'letter {letter} bitmap height: {bh} glyph height: {gh}')
win.fill((0, 0, 0))
win.blit(text_1, (0, 0))
pygame.display.update()
i += 1
run = i < len(text)
pygame.quit()
So, my questions are on the line glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects().
What does the pygame.mask.from_surface() function do?
What does the line glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects() do?
What arguments does the variable glyph_rect return, and what is the meaning of those arguments?
pygame.mask.from_surface creates a pygame.mask.Mask object form a pygame.Surface.
A Surface is bitmap. A Mask is an 2 dimensional array with Boolean values. The Mask created is the size of the _Surface. A field is True if the corresponding pixel in the surface is not transparent, and False if it is transparent.
pygame.mask.Mask.get_bounding_rects creates a list of pygame.Rect objects. Each rectangle describes a bounding area of connected pixles.
If the Surface contains exactly 1 connected image, you will get exactly 1 rectangle surrounding the image.
See the example. The black rectangle is the Surface rectangle and the red rectangle is the bound rectangle of the connected component:
repl.it/#Rabbid76/ImageHitbox
import pygame
def getMaskRect(surf, top = 0, left = 0):
surf_mask = pygame.mask.from_surface(surf)
rect_list = surf_mask.get_bounding_rects()
surf_mask_rect = rect_list[0].unionall(rect_list)
surf_mask_rect.move_ip(top, left)
return surf_mask_rect
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
try:
my_image = pygame.image.load('Bomb-256.png')
except:
my_image = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.circle(my_image, (0, 128, 0), (60, 60), 40)
pygame.draw.circle(my_image, (0, 0, 128), (100, 150), 40)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = window.get_rect().center
my_image_rect = my_image.get_rect(center = pos)
my_image_mask_rect = getMaskRect(my_image, *my_image_rect.topleft)
window.fill((255, 255, 255))
window.blit(my_image, my_image_rect)
pygame.draw.rect(window, (0, 0, 0), my_image_rect, 3)
pygame.draw.rect(window, (255, 0, 0), my_image_mask_rect, 3)
pygame.display.flip()
pygame.quit()
exit()

How to clear up all the text on my display

I’m the first time to ask on stack overflow! I’m a 12-year-old boy who living in Hong Kong, so if my English was wrong, please tell me and please don’t keep in mind. Apart from that, I’m a newer of Python. I don’t know that the meaning of the code. Can everyone making a # to tell me the meaning? Thank you!!
I am doing a project that use Python. Also, for the display, I use Pygame too. But there have some problem with the displays.
Here is my testing code:
# install pygame
import pygame
from pygame import *
pygame.init()
# play music
mixer.init()
mixer.music.load("game_music.mp3")
mixer.music.play()
# colour
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
grass_green = (112, 173, 71)
white = (255, 255, 255)
black = (0, 0, 0)
# screen settings
window = pygame.display.set_mode((640, 600))
window.fill(grass_green)
pygame.display.set_caption("What's Your Number?")
# fonts settings
default_font = pygame.font.get_default_font()
font_a = pygame.font.Font(default_font, 57)
font_b = pygame.font.Font(default_font, 30)
font_c = pygame.font.Font(default_font, 18)
# text
title = font_a.render("What's Your Number?", 1, white)
enter_to_start = font_b.render("Press the Enter to start", 1, white)
random_mode = font_a.render("Random Mode", 1, black)
your_mode = font_a.render("Your Mode", 1, black)
des_random_1 = font_c.render("The PC choose a random number for you to", 1, black)
des_random_2 = font_c.render("guess! Can you guess it correct?", 1, black)
des_your = font_c.render("Pick a number and let you friends to guess!", 1, black)
random_control = font_b.render("Press the up arrow", 1, black)
your_control = font_b.render("Press the down arrow", 1, black)
# image
up_arrow = pygame.image.load("up_arrow_new.png")
down_arrow = pygame.image.load("down_arrow_new.png")
def blit_img(img, x, y):
window.blit(img, (x, y))
# game
game = False
temp = True
while not game:
if temp:
window.blit(title, (10, 150))
window.blit(enter_to_start, (160, 350))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_KP_ENTER:
temp = False
window.fill(grass_green)
pygame.draw.rect(window, red, [50, 50, 540, 225])
pygame.draw.rect(window, blue, [50, 325, 540, 225])
window.blit(random_mode, (55, 65))
window.blit(des_random_1, (55, 150))
window.blit(des_random_2, (55, 200))
window.blit(random_control, (55, 240))
blit_img(up_arrow, 450, 150)
window.blit(your_mode, (55, 335))
window.blit(des_your, (55, 425))
window.blit(your_control, (55, 515))
blit_img(down_arrow, 450, 425)
pygame.display.flip()
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
if temp == False:
temp = True
window.fill(grass_green)
pygame.display.flip()
if event.key == pygame.K_ESCAPE:
game = True
if event.type == pygame.QUIT:
game = True
I want to make it just like a book or a PowerPoint to have pages. In this code, my problem is that the text which displayed cannot erase and blit the new text on it. Can someone help me? Thank you very much!!
I'd fill the window every frame and then render and blit the current text. The texts can be stored in a list and the current text can be accessed with an index variable that you increment in the event loop.
import pygame
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
window = pygame.display.set_mode((640, 600))
clock = pygame.time.Clock() # A clock to limit the frame rate.
font = pygame.font.Font(None, 57) # Use the default font.
texts = ['Hello', "what's", 'up?']
text_index = 0
done = False
while not done:
# Handle events.
for event in pygame.event.get():
# Allow the user to quit by clicking on the 'X' button.
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
# Make sure that we don't get an IndexError.
if text_index < len(texts)-1:
# Increment the index.
text_index += 1
# Insert additional game logic here.
# Finally draw everything.
window.fill(white) # Use fill to clear the window.
what_I_say = font.render(texts[text_index], True, black)
window.blit(what_I_say, (10, 150))
pygame.display.flip()
clock.tick(30) # Limit the frame rate to 30 FPS.
If you really only need to update the window when the user wants to switch to the next page (an event occurs), you could also use pygame.event.wait instead of pygame.event.get.
The way to remove previous stuff in pygame is to draw the background and everything you want to keep over it. In this case, you want to remove the Hello, so you will have to stop pygame from drawing it, and then draw the background over it
It should look like this:
import pygame
pygame.init()
#colour settings
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
#making a screen(display)
window = pygame.display.set_mode((640, 600))
window.fill(green)
# fonts settings
default_font = pygame.font.get_default_font()
font = pygame.font.Font(default_font, 57)
temp = True
#the things I want to display
while True:
if temp:
what_I_say = font.render("Hello", 1, white)
window.blit(what_I_say, (10, 150))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
temp = False
window.fill(green)
pygame.draw.rect(window, red, [50, 50, 540, 500])
The boolean temp marks whether to draw Hello. On pressing return (my keyboard doesn't have keypad enter), temp is set to false (so it will stop drawing Hello), the window is refilled with green (to cover the previous hello), and then a red rectangle is drawn.

How to make the color of a rectangle change without doing anything?

I want to draw a rectangle that changes from black to red without the user doing anything. The code below should fill the screen, draw one black rectangle then erase it and draw a red rectangle, then just keep looping. But I just get one red rectangle. What am I doing wrong?
import pygame
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while not done:
# --- Main event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(WHITE)
pygame.draw.rect(screen, BLACK, [300, 200, 100, 100],0)
screen.fill(WHITE)
pygame.draw.rect(screen, RED, [300, 200, 100, 100],0)
pygame.display.flip()
clock.tick(60)
pygame.quit()
You can use variable with color in rect(...) and ..
... use own event with pygame.time.set_timer() to change color in this variable.
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
size = (700, 500)
# --- start ---
pygame.init()
screen = pygame.display.set_mode(size)
# start color
color = RED
# define own event type
CHANGE_COLOR = pygame.USEREVENT + 1
# create event every 250ms
pygame.time.set_timer(CHANGE_COLOR, 250) # 250ms
# --- mainloop ---
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# check if get event
if event.type == CHANGE_COLOR:
# change color
if color == RED:
color = BLACK
else:
color = RED
screen.fill(WHITE)
pygame.draw.rect(screen, color, [300, 200, 100, 100],0)
pygame.display.flip()
clock.tick(60)
pygame.quit()
... or use pygame.time.get_ticks() to get current time and check if it is time to change color.
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
size = (700, 500)
# --- start ---
pygame.init()
screen = pygame.display.set_mode(size)
# start color
color = RED
# get current time
current_time = pygame.time.get_ticks()
# first change after 250 ms
change_color_time = current_time + 250
# --- mainloop ---
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# get current time
current_time = pygame.time.get_ticks()
# check if it is time to change color
if current_time >= change_color_time:
# set new time to change color again
change_color_time = current_time + 250
# change color
if color == RED:
color = BLACK
else:
color = RED
screen.fill(WHITE)
pygame.draw.rect(screen, color, [300, 200, 100, 100],0)
pygame.display.flip()
clock.tick(60)
pygame.quit()

Categories