2

I have this class that call a transparency function to create a transparent inner circle behind my outer circle, the issue is that this circle opacity multiply with each objects created leading to this issue:

enter image description here

This isn't something i want and i don't have much ideas on how to call this function only once per circle, i've tried to place the functions calls in the init def itself before but it don't remember it doing what i wanted.

at the end, all circles should look like

enter image description here

Here is my class and opacity function called transparency (i know it should be called opacity instead i'm just pepega), as well as my function that call that class via another file

import pygame

def transparency(self,surface, inner_surface, size, x, y):
        self.circle = pygame.draw.circle(inner_surface, (255, 255, 255, 10), (x,y), int(size[0]/2)-5)
        surface.blit(inner_surface, (0,0))
        surface.blit(self.image,(x-((size[0])/2),y-((size[1])/2)))

class circles(pygame.sprite.Sprite): # Initalise a new circle with set position and size (defined by cs)

    def __init__(self,surface, inner_surface, x, y, cs, font):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("./assets/circle.png").convert_alpha()
        size = (int(round(2.25*(109-(9*cs)))),int(round(2.25*(109-(9*cs)))))
        self.image = pygame.transform.scale(self.image, size)
        transparency(self, surface, inner_surface, size, x, y)
        pygame.display.update()

def Place_circles(screen, curve, circle_space, font):
    inner = inner_init([GetSystemMetrics(0), GetSystemMetrics(1)])
    Circle_list = []
    idx = [0,0]
    for c in reversed(range(0,len(curve))):
        for p in reversed(range(0,len(curve[c]))):
            dist = math.sqrt(math.pow(curve[c][p][0] - curve[idx[0]][idx[1]][0],2)+math.pow(curve [c][p][1] - curve[idx[0]][idx[1]][1],2))
            if dist > circle_space:
                print(dist)
                print(idx)
                idx = [c,p]
                Circle_list.append(circles.circles(screen, inner, curve[c][p][0], curve[c][p][1], 4, font))
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Gess1t
  • 71
  • 1
  • 9

1 Answers1

0

import pygame

def transparency(self,surface, inner_surface, size, x, y): self.circle = pygame.draw.circle(inner_surface, (255, 255, 255, 10), (x,y), int(size[0]/2)-5) surface.blit(inner_surface, (0,0)) surface.blit(self.image,(x-((size[0])/2),y-((size[1])/2)))

inner_surface is the same size as the screen. All transparent circles are drawn on inner_surface. Each time you blit the inner_surface onto the screen, any circles drawn on the inner_surface become more opaque. You don't need inner_surface at all. Create a temporary Surface. Draw the circle on the temporary Surface and blit it on the screen:

def transparency(self,surface, size, x, y):
    temp_surface = pygame.Surface(size, pygame.SRCALPHA)
    self.circle = pygame.draw.circle(temp_surface, (255, 255, 255, 10), (size[0]//2, size[1]//2), int(size[0]/2)-5)
    topleft = x - size[0] // 2, y - size[1] // 2
    surface.blit(inner_surface, topleft)
    surface.blit(self.image, topleft)

See also Draw a transparent rectangle in pygame
and How to make transparent pygame.draw.circle.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • i see, this would basically be the equivalent of moving inner_surface inside my for loop that place those circles, but i guess this work, i'm gonna rework my whole code anyway as it use 25% CPU with just nothing on screen, anyway this solved my issue – Gess1t Feb 15 '21 at 16:23
  • @Gess1t Don't move `inner_surface` inside the for loop. This will cause a performance impact. `inner_surface` has the size of the screen, but you only need a _Surface_ the size of the image. – Rabbid76 Feb 15 '21 at 16:27
  • i forgot to ask, how would that do if i tried to remove a circle? wouldn't that remove the pixels behind? i'm getting some doubts about my implementation. also, even without moving my inner surface and deleting all code related for it, i still have 25% CPU usage, so like i said, i'm just going to rework everything. – Gess1t Feb 15 '21 at 16:29
  • @Gess1t You cannot remove an object form the screen. When you draw an object, it just changes the pixels on the screen. If you want to remove an object, you've redrawn the entire scene. It is common practice to redraw the entire scene in each frame. – Rabbid76 Feb 15 '21 at 16:32