Drawing a transparent line in pygame - python

I need a way to draw a partially transparent line in pygame. I found this answer(python - Draw a transparent Line in pygame) but it only works with straight lines and doesn't work with different line thicknesses.

You have to create new surface with any size and with alpha channel
surface = pygame.Surface((width, height)).convert_alpha()
or use main surface to create new surface with the same size
surface = screen.convert_alpha()
Fill it with transparent color (0,0,0,0). Important is last zero which means alpha channel - (R,G,B,A)
surfaces.fill([0,0,0,0])
Draw on this surface with alpha channel smaller then 255
pygame.draw.line(surface, (0, 0, 0, 32), (0, 0), (800, 600), 5)
And finally you can blit it on main page in any place
screen.blit(surface, (x, y))
For surface which has the same size as main surface it can be (0,0)
screen.blit(surface, (0,0))
Minimal example
import pygame
pygame.init()
screen = pygame.display.set_mode((800,600))#, depth=32)
surface1 = screen.convert_alpha()
surface1.fill([0,0,0,0])
pygame.draw.circle(surface1, (255, 0, 0, 128), (325, 250), 100)
surface2 = screen.convert_alpha()
surface2.fill([0,0,0,0])
pygame.draw.circle(surface2, (0, 255, 0, 128), (475, 250), 100)
surface3 = screen.convert_alpha()
surface3.fill([0,0,0,0])
pygame.draw.circle(surface3, (0, 0, 255, 128), (400, 350), 100)
surface4 = screen.convert_alpha()
surface4.fill([0,0,0,0])
pygame.draw.line(surface4, (0, 0, 0, 32), (0, 0), (800, 600), 5)
pygame.draw.line(surface4, (0, 0, 0, 32), (0, 600), (800, 0), 5)
surface5 = screen.convert_alpha()
surface5.fill([0,0,0,0])
pygame.draw.polygon(surface5, (255, 0, 0, 128), [(400, 250), (450, 300), (400, 350), (350, 300)])
screen.fill([255,255,255]) # white background
screen.blit(surface1, (0,0))
screen.blit(surface2, (0,0))
screen.blit(surface3, (0,0))
screen.blit(surface4, (0,0))
screen.blit(surface5, (0,0))
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
pygame.quit()

Related

pygame fully transparent surface

I'm trying to make a color picker that changes color over time. I have the logic but the process is really slow, the idea is to have a square that changes color and overlap a PNG grayscale gradient onto it so that the program can be faster. The problem is that I can't seem to download the gradient with the transparency.
import sys, pygame
pygame.init()
#VARIABLES
width = 255
height = 255
background = (255, 0, 0)
foreground = (230, 100, 45)
mySurf = pygame.Surface((255, 255))
mySurf.set_alpha(0)
mySurf.fill((200,0,200))
#SCREEN
screen = pygame.display.set_mode((width, height))
screen.fill((0, 0, 0))
#CODE
for x in range(255):
s = pygame.Surface((1, 255))
s.set_alpha(255-x)
s.fill((255, 255, 255))
mySurf.blit(s, (x, 0))
for y in range(255):
s = pygame.Surface((255, 1))
s.set_alpha(y)
s.fill((0, 0, 0))
mySurf.blit(s, (0, y))
pygame.image.save(mySurf, "gradient.png")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
You have to create a surface with a format that hast an alpha channel per pixel. Use the SRCALPHA flag:
mysurf = pygame.surface((255, 255))
mySurf = pygame.Surface((255, 255), pygame.SRCALPHA)
Note, with the flag each pixel has its own alpha value (RGBA format), without the flag the surfaces hast just 1 global alpha value and can not store different alpha values for the pixels (RGB format)
Complete example:
import sys, pygame
pygame.init()
#VARIABLES
width = 255
height = 255
background = (255, 0, 0)
foreground = (230, 100, 45)
mySurf = pygame.Surface((255, 255))
mySurf.set_alpha(0)
mySurf.fill((200,0,200))
#SCREEN
screen = pygame.display.set_mode((width, height), pygame.SRCALPHA)
#CODE
s = pygame.Surface((1, 255), pygame.SRCALPHA)
for x in range(255):
s.fill((255, 255, 255, 255-x))
mySurf.blit(s, (x, 0))
s = pygame.Surface((255, 1), pygame.SRCALPHA)
for y in range(255):
s.fill((0, 0, 0, y))
mySurf.blit(s, (0, y))
pygame.image.save(mySurf, "gradient.png")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()

Why don't three R, G and B circles blend correctly?

I am trying to represent the RGB color model using python + pygame.
I wanted to get the following:
So then, I wrote the following code:
import pygame, sys
from pygame.locals import *
ALPHA = 100
TRANSPARENT = (255,0,255)
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0,100)
GREEN = (0,255,0,100)
BLUE = (0,0,255,100)
pygame.init()
size=(800,500)
screen= pygame.display.set_mode(size)
surf1 = pygame.Surface(size)
surf1.fill(TRANSPARENT)
surf1.set_colorkey(TRANSPARENT)
pygame.draw.circle(surf1, BLUE, (430, 280), 60 )
surf2 = pygame.Surface(size)
surf2.fill(TRANSPARENT)
surf2.set_colorkey(TRANSPARENT)
pygame.draw.circle(surf2, GREEN, (370, 280), 60 )
surf3 = pygame.Surface(size)
surf3.fill(TRANSPARENT)
surf3.set_colorkey(TRANSPARENT)
pygame.draw.circle(surf3, RED, (400, 220), 60 )
surf1.set_alpha(ALPHA)
surf2.set_alpha(ALPHA)
surf3.set_alpha(ALPHA)
while True :
screen.fill(WHITE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(surf1, (0,0))
screen.blit(surf2, (0,0))
screen.blit(surf3, (0,0))
pygame.display.flip()
But instead of getting the RGB color model, I got this, with colors incorrectly blended:
Does anybody know what it could be? Thanks!
This should work:
import pygame, sys
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0, 100)
GREEN = (0, 255, 0, 100)
BLUE = (0, 0, 255, 100)
pygame.init()
size = (800, 500)
screen = pygame.display.set_mode(size)
surf1 = pygame.Surface(size)
surf1.fill(BLACK)
surf1.set_colorkey(BLACK)
pygame.draw.circle(surf1, BLUE, (430, 280), 60)
surf2 = pygame.Surface(size)
surf2.fill(BLACK)
surf2.set_colorkey(BLACK)
pygame.draw.circle(surf2, GREEN, (370, 280), 60)
surf3 = pygame.Surface(size)
surf3.fill(BLACK)
surf3.set_colorkey(BLACK)
pygame.draw.circle(surf3, RED, (400, 220), 60)
surf4 = pygame.Surface(size)
surf4.set_colorkey(BLACK)
surf4.blit(surf1, (0, 0), special_flags=pygame.BLEND_RGB_ADD)
surf4.blit(surf2, (0, 0), special_flags=pygame.BLEND_RGB_ADD)
surf4.blit(surf3, (0, 0), special_flags=pygame.BLEND_RGB_ADD)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(WHITE)
screen.blit(surf4, (0, 0))
pygame.display.flip()
You want to add the colors at the intersections of the circles, hence use the BLEND_RGB_ADD flag.
I created a fourth surface since you wanted a white background.

Blending two pygame.Color objects together

I am wondering how to blend two pygame.Color objects and cannot find a solution after extensive reasearch.
I have created two pygame.Color objects and would like to create a new object who's colour value is the two colours blended together.
import pygame
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
#If I want to blend white and red with the option of how much dominace each should have what code would I write
Use the pygame.Color.lerp function to linear interpolation to the given Colors.
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
pink = white.lerp(red, 0.5)
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((500, 100))
clock = pygame.time.Clock()
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
pink25 = white.lerp(red, 0.25)
pink50 = white.lerp(red, 0.5)
pink75 = white.lerp(red, 0.75)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
pygame.draw.circle(window, white, (50, 50), 45)
pygame.draw.circle(window, pink25, (150, 50), 45)
pygame.draw.circle(window, pink50, (250, 50), 45)
pygame.draw.circle(window, pink75, (350, 50), 45)
pygame.draw.circle(window, red, (450, 50), 45)
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()

why when calling font.render () does the program return an error?

i am trying to learn some of the basics of pygame via the following pdf: https://buildmedia.readthedocs.org/media/pdf/pygame/latest/pygame.pdf
and I stopped on page 29 where it shows me that the Rect class defines 4 cornerpoints, 4 mid points and 1 centerpoint. but when I start the program it gives me an error saying No module named 'rect' and if i delete it says font is not defined what should I add to make it work correctly?
import pygame
from pygame.locals import *
from rect import *
def draw_point(text, pos):
img = font.render(text, True, BLACK)
pygame.draw.circle(screen, RED, pos, 3)
screen.blit(img, pos)
pygame.init()
GRAY = (125, 125, 125)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
screen = pygame.display.set_mode((640, 240))
rect = Rect(50, 40, 250, 80)
pts = ('topleft', 'topright', 'bottomleft', 'bottomright', 'midtop', 'midright', 'midbottom', 'midleft', 'center')
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
screen.fill(GRAY)
pygame.draw.rect(screen, GREEN, rect, 4)
for pt in pts:
draw_point(pt, eval('rect.'+pt))
pygame.display.flip()
pygame.quit()
Keep reading that book; The section 3.9 The common code contains the definition of rect.py:
import pygame
from pygame.locals import *
from random import randint
width = 500
height = 200
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
MAGENTA = (255, 0, 255)
CYAN = (0, 255, 255)
BLACK = (0, 0, 0)
GRAY = (150, 150, 150)
WHITE = (255, 255, 255)
dir = {K_LEFT: (-5, 0), K_RIGHT: (5, 0), K_UP: (0, -5), K_DOWN: (0, 5)}
pygame.init()
screen = pygame.display.set_mode((width, height))
font = pygame.font.Font(None, 24)
running = True
Once you create that file you'll be fine.
You must define a font
for example:
font = pygame.font.SysFont("arial", 35)
game_over_text = "Press Space to Start"
game_over_label = font.render(game_over_text, 1, (255,255,255))
window.blit(game_over_label, (WIDTH-550, HEIGHT-400))

How to make transparent pygame.draw.circle [duplicate]

This question already has answers here:
Draw a transparent rectangles and polygons in pygame
(4 answers)
Closed 2 years ago.
How to make pygame.draw.circle transparent (add alpha level), as for "surface" "set_alpha"?
I found a solution only in changing the color of pygame.draw.circle to less bright
You've to use a pygame.Surface. Create a Surface with a per pixel alpha image format. e.g:
radius = 100
circle = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA)
And draw a transparent circle on it. The color of the circle has to have an alpha channel < 255 (e.g. 128):
pygame.draw.circle(circle, (255, 0, 0, 128), (radius, radius), radius)
blit() the Surface to the window. e.g.:
window.blit(circle, (100, 100))
Example:
import pygame
pygame.init()
wndsize = (400, 400)
window = pygame.display.set_mode(wndsize)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
pygame.draw.rect(window, (0, 0, 255), (0, 0, 200, 400))
radius = 100
circle = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA)
pygame.draw.circle(circle, (255, 0, 0, 128), (radius, radius), radius)
window.blit(circle, (100, 100))
pygame.display.flip()
You can create surface with alpha channel
surface1 = screen.convert_alpha()
fill it with transparent color -
surface1.fill([0,0,0,0])
draw circle using color [R,G,B,Alpha]
pygame.draw.circle(surface1, (255, 0, 0, 128), (300, 300), 200)
and blit it on screen
screen.blit(surface1, (0,0))
But alpha always mix object color with background color so it makes it less bright.
import pygame
pygame.init()
screen = pygame.display.set_mode((800,600))#, depth=32)
surface1 = screen.convert_alpha()
surface1.fill([0,0,0,0])
pygame.draw.circle(surface1, (255, 0, 0, 128), (325, 250), 100)
surface2 = screen.convert_alpha()
surface2.fill([0,0,0,0])
pygame.draw.circle(surface2, (0, 255, 0, 128), (475, 250), 100)
surface3 = screen.convert_alpha()
surface3.fill([0,0,0,0])
pygame.draw.circle(surface3, (0, 0, 255, 128), (400, 350), 100)
screen.fill([255,255,255]) # white background
screen.blit(surface1, (0,0))
screen.blit(surface2, (0,0))
screen.blit(surface3, (0,0))
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
pygame.quit()
Example on GitHub: furas/python-examples/pygame/transparency

Categories

Resources