The BLEND_RGB_MULT is changing my image to be fully transparent and the transparent parts are black

36 Views Asked by At

When I use the BLEND_RGB_MULT flag to blit an image of a flashlight beam it changes the beam transparent and the transparent parts black as shown here Image of Flashlight beam Im using pygame zero as it is a school project and is what I have learned so far but I am also implementing pygame features for the flashlight.

The parts of my code that are specific to the issue are in bold.

`import pgzrun
import os
from random import *
from pgzhelper import *

WIDTH = 1980
HEIGHT = 1080
os.environ['SDL_VIDEO_CENTERED'] = '1'

#Player Actor
player = Actor('player_anim\\player-0')
player.pos = 0, 540

#Player Hp
hp = 100
dead = False


blood_overlay = Actor('bloodoverlay\\hurt1')

#Grunt Enemy Actor
grunt = Actor('enemy_anim\\pixil-frame-0')
grunt.pos = 800, 540

#Brute Enemy Actor
brute = Actor('brute_anim\\tile000')
brute.pos = 1000, 540

#Classroom Actor
classroom = Actor('map\\classroom')
map = Actor('map\\map')

room = "map"
rooms = ["classroom"]

door1 = Actor('map\\door1')
door1.left = 111
door1.bottom = 426
door2 = Actor('map\\door1')
door2.left = 483
door2.bottom = 426
door3 = Actor('map\\door1')
door3.left = 1491
door3.bottom = 426
door4 = Actor('map\\door1')
door4.left = 1737
door4.bottom = 426
door5 = Actor('map\\door2')
door6 = Actor('map\\door2')
door7 = Actor('map\\door2')
door8 = Actor('map\\door2')

border_topleft = Actor('map\\borders\\topleft')
border_topleft.left = 3
border_topleft.top = -3
border_topright = Actor('map\\borders\\topright')
border_topright.right = 1980
border_bottomleft = Actor('map\\borders\\bottomleft')
border_bottomleft.bottom = 1080
border_bottomright = Actor('map\\borders\\bottomright')
border_bottomright.right = 1980
border_bottomright.bottom = 1080

**darkener = pygame.image.load('PixelGame\\images\\map\\flashlightoff.png')
flashlightimage = pygame.image.load('PixelGame\\images\\map\\flashlight.png')
lightsurface = pygame.display.set_mode((WIDTH, HEIGHT))**
player_anim = 0
player_anim_timer = 0

enemy_anim = 3
brute_anim = 0

gift = Actor("items\\gift")
gift.pos = WIDTH/2, HEIGHT/2
gift.opened = False

gifts = []

bottle = Actor("items\\bottle")
bottle.pos = 990, 540
knife = Actor("items\\knife")
knife.pos = 990, 540
items = [bottle]

inventory = []

hotbar = Actor("hotbar\\hotbar")
hotbar.pos = 400, 970

hotbar_bottle = Actor('hotbar\\bottle')
hotbar_bottle.pos = 350, 970

flashlight = "on"

equipped = None

def damage(enemy):
    if enemy == grunt:
        hp -= 30
    elif enemy == brute:
        hp -= 100
    if hp == 0:
        dead = True
    
def enter_door():
    global room
    room = choice(rooms)
    print ("entered door", room)

def draw():
    global room
    global dead
    screen.clear()
    if room == "map":
        map.draw()
        border_topleft.draw()
        border_topright.draw()
        border_bottomleft.draw()
        border_bottomright.draw()
        door1.draw()
        door2.draw()
        door3.draw()
        door4.draw()
    if room == 'classroom':
        classroom.draw()
    if dead == False:
        player.draw()
    grunt.draw()
    brute.draw()
    if room == "map":
        door5.draw()
        door6.draw()
        door7.draw()
        door8.draw()


    if gift.opened == False:
        gift.draw()
    
    for item in inventory:
        item.draw()
    
    **#lightsurface.fill((0, 0, 0))
    if flashlight == "on":
        lightsurface.blit(flashlightimage, (player.x, player.y), special_flags = pygame.BLEND_RGB_MULT)**

    hotbar.draw()
    if len(inventory) > 0:
        if inventory[0] == bottle:
            hotbar_bottle.draw()
    
    if len(inventory) > 1:
        if inventory[1] == bottle:
            hotbar_bottle.draw()
    
    if len(inventory) > 2:
        if inventory[2] == bottle:
            hotbar_bottle.draw()
    
    if len(inventory) > 3:
        if inventory[3] == bottle:
            hotbar_bottle.draw()
    
    #blood_overlay.draw()
    

def update():
    global enemy_anim
    global brute_anim
    global player_anim
    global player_anim_timer
    global equipped
    global dead

    screen.fill('white')

    if player.colliderect(door1):
        enter_door()

    if len(inventory) > 0:
        print (inventory[0], equipped)
        if inventory[0] == bottle:
            hotbar_bottle.pos = 230, 970

    if player.colliderect(gift) and gift.opened == False:
        inventory.append(choice(items))
        gift.opened = True

    if player_anim > 15:
        player_anim = 0

    if equipped == None:
        player.image = 'player_anim\\player-' + str(player_anim)
    
    elif equipped == bottle:
        player.image = 'player_anim\\bottle\\bottle' + str(player_anim)

    player_anim_timer += 1
    if dead == False:
        if player_anim_timer >= 10:
            player_anim += 1
            player_anim_timer = 0

        if keyboard.left==True or keyboard.a==True:
            if player_anim < 8 or player_anim > 11:
                player_anim = 8
            
            if player.left>0:
                if room == "map" and player.colliderect(border_topleft) != True and player.colliderect(border_bottomleft) != True:
                    player.x-=4
                
                elif room == 'classroom':
                    player.x-=4

        elif keyboard.right==True or keyboard.d==True:
            if player_anim < 4 or player_anim > 7:
                player_anim = 4

            if player.right<1980 and player.colliderect(border_topright) != True and player.colliderect(border_bottomright) != True:
                player.x+=4

        elif keyboard.down==True or keyboard.s==True:
            if player_anim < 14 or player_anim > 15:
                player_anim = 14

            if player.bottom<1080 and player.colliderect(border_bottomright) != True and player.colliderect(border_bottomleft) != True:
                player.y+=4

        elif keyboard.up==True or keyboard.w==True:
            if player_anim < 12 or player_anim > 13:
                player_anim = 12

            if player.top>0 and player.colliderect(border_topright) != True  and player.colliderect(border_topleft) != True :
                player.y-=4

        else:
            if player_anim > 3:
                player_anim = 0

    enemy_anim -= 0.1

    if enemy_anim <= 0:
        enemy_anim = 3
    
    if enemy_anim > 2.5:
        grunt.image = 'enemy_anim\\pixil-frame-0'
    
    elif enemy_anim > 2 and enemy_anim < 2.5 or enemy_anim > 0 and enemy_anim < 0.5:
        grunt.image = 'enemy_anim\\pixil-frame-1'
    
    elif enemy_anim > 1.5 and enemy_anim < 2 or enemy_anim > 0.5 and enemy_anim < 1:
        grunt.image = 'enemy_anim\\pixil-frame-2'
    
    elif enemy_anim > 0 and enemy_anim < 1.5:
        grunt.image = 'enemy_anim\\pixil-frame-3'
    
    if grunt.distance_to(player) <= 290 and flashlight == "on":
        grunt.move_towards (player, 3)
        sounds.spaceenginesmall_004.play()
    
    elif grunt.distance_to(player) <= 100:
        grunt.move_towards (player, 3)
        sounds.spaceenginesmall_004.play()
    
    else:
        sounds.spaceenginesmall_004.stop()
    
    if grunt.colliderect(player):
        pass


    if brute.distance_to(player) <= 290 and flashlight == "on":
        if dead == False:
            brute.move_towards (player, 1)

    if brute.colliderect(player):
        dead = True
        brute_anim += 0.1
        if brute_anim <= 0.5:
            brute.image = 'brute_anim\\tile001'
        if brute_anim <= 1 and brute_anim > 0.5:
            brute.image = 'brute_anim\\tile001'
        if brute_anim <= 1.5 and brute_anim > 1:
            brute.image = 'brute_anim\\tile002'
        if brute_anim <= 2 and brute_anim > 1.5:
            brute.image = 'brute_anim\\tile003'
        if brute_anim <= 2.5 and brute_anim > 2:
            brute.image = 'brute_anim\\tile004'
        if brute_anim <= 3 and brute_anim > 2.5:
            brute.image = 'brute_anim\\tile005'
        if brute_anim <= 3.5 and brute_anim > 3:
            brute.image = 'brute_anim\\tile006'
        if brute_anim <= 4 and brute_anim > 3.5:
            brute.image = 'brute_anim\\tile007'

def on_key_down(key, mod, unicode):
    global equipped

    if key == keys.K_1: 
        if len(inventory) > 0:
            equipped = inventory[0]
    if key == keys.K_2: 
        if len(inventory) > 1:
            equipped = inventory[1]
    if key == keys.K_3: 
        if len(inventory) > 2:
            equipped = inventory[2]
    if key == keys.K_4: 
        if len(inventory) > 3:
            equipped = inventory[3]


def on_mouse_down(pos, button):
    global flashlight

    if button == mouse.LEFT:
        if flashlight == "on":
             flashlight = "off"
        
        elif flashlight == "off":
            flashlight = "on"

'''
def on_mouse_move(pos):
    if flashlight == "on":
        darkener.angle += 5
        #darkener.point_towards(pos)
'''
pgzrun.go()`

Im using a video from youtube to implement the flashlight particularly the section on BLEND_RGB_MULT.

I have tried changing the fill of the surface to be a rect instead and just removing the fill altogether but I does the same thing everytime no matter what is in the backround it doesn't blend.

1

There are 1 best solutions below

0
Scyther4545 On

I figured out the issue, the code in bold had to be changed to this

lightsurface = screen.surface.copy()
        lightsurface.fill((0, 0, 0))
        lightsurface.blit(playerlight, (player.left - 10, player.top - 30))
        lightsurface.blit(flashlightimage, (player.right, player.top - 30))
        screen.surface.blit(lightsurface, (0,0), None, special_flags = pygame.BLEND_RGB_MULT)