Issue
I am making an illustrator n pygame and now i need to color my shapes. I need to make an color picker like this:
The idea is that the user will scroll on the bar and select an color then it will return the program an rgb value or you can say the color that will tell which color is selected.
How can i make this possible.
Should i have to use surface.set_at()
and make this my setting the color of each pixel or there an alternate way of doing this.
This is my code:
import pygame
import math
pygame.init()
HEIGHT = 700
WIDTH = 1000
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
AQUA = "aqua"
shapes = []
window = pygame.display.set_mode((WIDTH, HEIGHT), pygame.RESIZABLE)
pygame.display.set_caption("Illustrator")
window.fill(WHITE)
class Square:
def __init__(self, square_x, square_y, square_width, square_height):
self.square_x = square_x
self.square_y = square_y
self.square_width = square_width
self.square_height = square_height
class Circle:
def __init__(self, circle_x, cirlce_y, circle_radius):
self.circle_x = circle_x
self.circle_y = cirlce_y
self.circle_radius = circle_radius
class Button:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def clicked(self):
mouse_x, mouse_y = pygame.mouse.get_pos()
if self.x <= mouse_x <= self.x + self.width and self.y <= mouse_y <= self.y + self.height:
return True
square_button = Button(10, 10, 50, 30)
circle_button = Button(10, 50, 50, 30)
def buttons(window):
pygame.draw.rect(window, BLACK, pygame.Rect(square_button.x, square_button.y, square_button.width, square_button.height))
pygame.draw.rect(window, BLACK, pygame.Rect(circle_button.x, circle_button.y, circle_button.width, circle_button.height))
def draw_square(window, x, y, width, height):
color = "black"
pygame.draw.rect(window, color, pygame.Rect(x, y, width, height))
def draw_circle(window, x, y, radius):
pygame.draw.circle(window, AQUA, (x, y), radius)
def square_logic(mouse_x_button_down, mouse_y_button_down, mouse_x_button_up, mouse_y_button_up, delta_x, delta_y):
if delta_x > 0 and delta_y > 0:
shapes.append(Square(mouse_x_button_down, mouse_y_button_down, delta_x, delta_y))
elif delta_x < 0 and delta_y < 0 :
shapes.append(Square(mouse_x_button_up, mouse_y_button_up, abs(delta_x), abs(delta_y)))
elif delta_x < 0 and delta_y > 0:
shapes.append(Square(mouse_x_button_up, mouse_y_button_down, abs(delta_x), delta_y))
elif delta_x > 0 and delta_y < 0:
shapes.append(Square(mouse_x_button_down, mouse_y_button_up, delta_x, abs(delta_y)))
def square_logic_for_drag(mouse_x_button_down, mouse_y_button_down, mouse_x, mouse_y, delta_x, delta_y):
if delta_x > 0 and delta_y > 0:
draw_square(window, mouse_x_button_down, mouse_y_button_down, delta_x, delta_y)
elif delta_x < 0 and delta_y < 0 :
draw_square(window, mouse_x, mouse_y, abs(delta_x), abs(delta_y))
elif delta_x < 0 and delta_y > 0:
draw_square(window, mouse_x, mouse_y_button_down, abs(delta_x), delta_y)
elif delta_x > 0 and delta_y < 0:
draw_square(window, mouse_x_button_down, mouse_y, delta_x, abs(delta_y))
def circle_logic(delta_x, delta_y, mouse_x_button_down, mouse_y_button_down, radius):
if delta_x > 0 and delta_y > 0 or delta_x < 0 and delta_y > 0 or delta_x > 0 and delta_y < 0 or delta_x < 0 and delta_y < 0:
shapes.append(Circle(mouse_x_button_down + delta_x/2, mouse_y_button_down + delta_y/2, radius))
def circle_logic_for_drag(delta_x, delta_y, mouse_x_button_down, mouse_y_button_down, radius):
if delta_x > 0 and delta_y > 0 or delta_x < 0 and delta_y > 0 or delta_x > 0 and delta_y < 0 or delta_x < 0 and delta_y < 0:
draw_circle(window, mouse_x_button_down + delta_x/2, mouse_y_button_down + delta_y/2, radius)
def draw_previous_shapes():
for j in range(len(shapes)):
if type(shapes[j]) == Square:
draw_square(window, shapes[j].square_x, shapes[j].square_y, shapes[j].square_width, shapes[j].square_height)
if type(shapes[j]) == Circle:
draw_circle(window, shapes[j].circle_x, shapes[j].circle_y, shapes[j].circle_radius)
def main():
run = True
mouse_button_down = False
mouse_button_up = False
shape = "square"
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_x_button_down, mouse_y_button_down = pygame.mouse.get_pos()
print(mouse_x_button_down, mouse_y_button_down)
mouse_button_down = True
if square_button.clicked():
shape = "square"
if circle_button.clicked():
shape = "circle"
if event.type == pygame.MOUSEBUTTONUP:
mouse_x_button_up, mouse_y_button_up = pygame.mouse.get_pos()
print(mouse_x_button_up, mouse_y_button_up)
mouse_button_up = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_z and (pygame.key.get_mods() == 64 or pygame.key.get_mods() == 128):
try:
shapes.pop(len(shapes) - 1)
window.fill(WHITE)
draw_previous_shapes()
except:
pass
buttons(window)
if mouse_button_down == True :
if mouse_button_up == True:
mouse_button_down = False
mouse_button_up = False
delta_x = mouse_x_button_up - mouse_x_button_down
delta_y = mouse_y_button_up - mouse_y_button_down
radius = math.sqrt(delta_x*delta_x + delta_y*delta_y) /2
print( delta_x, delta_y)
if shape == "square":
square_logic(mouse_x_button_down, mouse_y_button_down, mouse_x_button_up, mouse_y_button_up, delta_x, delta_y)
if shape == "circle":
circle_logic(delta_x, delta_y, mouse_x_button_down, mouse_y_button_down, radius)
else:
window.fill(WHITE)
buttons(window)
draw_previous_shapes()
mouse_x, mouse_y = pygame.mouse.get_pos()
delta_x = mouse_x - mouse_x_button_down
delta_y = mouse_y - mouse_y_button_down
radius = math.sqrt(delta_x*delta_x + delta_y*delta_y) /2
if shape == "square":
square_logic_for_drag(mouse_x_button_down, mouse_y_button_down, mouse_x, mouse_y, delta_x, delta_y)
if shape == "circle":
circle_logic_for_drag(delta_x, delta_y, mouse_x_button_down, mouse_y_button_down, radius)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
For further explaination comment me?
Solution
The pygame.Color
object can be used to convert between the RGB and [HSL/HSV](HSL and HSV) color schemes.
The hsla
property:
The HSLA representation of the Color. The HSLA components are in the ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100].
Create a pygame.Surface
and use the function `hsla to create an image for the color picker:
class ColorPicker:
def __init__(self, x, y, w, h):
self.rect = pygame.Rect(x, y, w, h)
self.image = pygame.Surface((w, h))
self.image.fill((255, 255, 255))
self.rad = h//2
self.pwidth = w-self.rad*2
for i in range(self.pwidth):
color = pygame.Color(0)
color.hsla = (int(360*i/self.pwidth), 100, 50, 100)
pygame.draw.rect(self.image, color, (i+self.rad, h//3, 1, h-2*h//3))
Calculation of the relative position in the coller picker when the mouse button is held down:
class ColorPicker:
# [...]
def update(self):
moude_buttons = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
if moude_buttons[0] and self.rect.collidepoint(mouse_pos):
self.p = (mouse_pos[0] - self.rect.left - self.rad) / self.pwidth
self.p = (max(0, min(self.p, 1)))
Determine the color from the relative position in the color picker:
class ColorPicker:
# [...]
def get_color(self):
color = pygame.Color(0)
color.hsla = (int(self.p * self.pwidth), 100, 50, 100)
return color
Minimal example:
import pygame
class ColorPicker:
def __init__(self, x, y, w, h):
self.rect = pygame.Rect(x, y, w, h)
self.image = pygame.Surface((w, h))
self.image.fill((255, 255, 255))
self.rad = h//2
self.pwidth = w-self.rad*2
for i in range(self.pwidth):
color = pygame.Color(0)
color.hsla = (int(360*i/self.pwidth), 100, 50, 100)
pygame.draw.rect(self.image, color, (i+self.rad, h//3, 1, h-2*h//3))
self.p = 0
def get_color(self):
color = pygame.Color(0)
color.hsla = (int(self.p * self.pwidth), 100, 50, 100)
return color
def update(self):
moude_buttons = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
if moude_buttons[0] and self.rect.collidepoint(mouse_pos):
self.p = (mouse_pos[0] - self.rect.left - self.rad) / self.pwidth
self.p = (max(0, min(self.p, 1)))
def draw(self, surf):
surf.blit(self.image, self.rect)
center = self.rect.left + self.rad + self.p * self.pwidth, self.rect.centery
pygame.draw.circle(surf, self.get_color(), center, self.rect.height // 2)
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
cp = ColorPicker(50, 50, 400, 60)
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
cp.update()
window.fill(0)
cp.draw(window)
pygame.display.flip()
pygame.quit()
exit()
Answered By - Rabbid76
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.