Can't pass rgb value through a variable

Viewed 939

Not much to say, I create a variable

colour = (int, int, int)

and then I try to pass it in this way

self.img = self.my_font.render(self.unit_type, 1, self.colour)

the error I get is

Traceback (most recent call last):
  File "C:/Users/oricc/PycharmProjects/designAChessboardChallange/display.py", line 137, in <module>
    pw1 = Pikeman()
  File "C:/Users/oricc/PycharmProjects/designAChessboardChallange/display.py", line 90, in __init__
    self.img = self.my_font.render(self.unit_type, 1, self.colour)
TypeError: Invalid foreground RGBA argument

the complete code is the following

import pygame
import sys
from coordinator import coordinator

# Sets up the display

pygame.init()
window_size = (800, 800)
game_window = pygame.display.set_mode(size=window_size)
pygame.display.set_caption('My Game')


# Defines classes and related methods

class WhiteSquare:
    def __init__(self):
        self.height = int(window_size[0] / 8)
        self.width = int(window_size[1] / 8)
        self.white_square = pygame.Surface((self.height, self.width))
        self.white_square.fill((255, 255, 255))


class BlackSquare:
    def __init__(self):
        self.height = int(window_size[0] / 8)
        self.width = int(window_size[1] / 8)
        self.black_square = pygame.Surface((self.height, self.width))
        self.black_square.fill((0, 0, 0))


class ChessBoard:
    def __init__(self):
        self.ws = ws
        self.bs = bs
        self.white_columns = white_columns
        self.black_columns = black_columns

    def draw(self):
        for w_columns in self.white_columns:
            game_window.blit(self.ws.white_square, w_columns)

        for b_columns in self.black_columns:
            game_window.blit(self.bs.black_square, b_columns)


# class SquareNames:
#     letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
#     numbers = ['1', '2', '3', '4', '5', '6', '7', '8']
#     square_names = []
#     for letter in letters:
#         for number in numbers:
#             square_name = letter + number
#             square_names.append(square_name)
#     print((square_names))
#     # for coordinate in
#     # coordinates = (square_name : coordinate)

# TBC..........

# Background for units

class CircleSurface:
    def __init__(self):
        self.circle_surface = pygame.Surface((100, 100), flags=pygame.SRCALPHA)
        pygame.draw.circle(self.circle_surface, (0, 255, 0), (50, 50), 45)


class Unit:
    def __init__(self):
        self.surface = pygame.Surface((100, 100))
        self.my_font = pygame.font.SysFont('Time New Roman', 100)
        self.cs = cs

    def draw_circle(self, surface):
        pygame.draw.circle(self.cs.circle_surface, (0, 255, 0), (200, 200), 50)
        surface.blit(self.cs.circle_surface, (200, 200))


class Pikeman(Unit):
    unit_type = 'P'
    destination = (int, int)
    colour = (int, int, int)

    def __init__(self):
        self.r = int
        self.g = int
        self.b = int
        self.colour = (self.r, self.g, self.b)
        super().__init__()
        self.img = self.my_font.render(self.unit_type, 1, self.colour)

    def set_colour(self, colour):
        self.colour = colour

    def draw(self, surface):
        surface.blit(self.img, self.destination)


class Archer(Unit):
    unit_type = 'A'
    destination = (525, 525)

    def __init__(self):
        super().__init__()
        self.img = self.my_font.render(self.unit_type, 1, (255, 0, 0))

    def draw(self, surface):
        surface.blit(self.img, self.destination)


class Knight(Unit):
    unit_type = 'K'
    destination = (325, 525)

    def __init__(self):
        super().__init__()
        self.img = self.my_font.render(self.unit_type, 1, (255, 0, 0))

    def draw(self, surface):
        surface.blit(self.img, self.destination)

# Sets and gets the coordinates for black and white squares


coordinator = coordinator()

black_columns = coordinator[2] + coordinator[3]
white_columns = coordinator[0] + coordinator[1]

# Creates needed objects

ws = WhiteSquare()
bs = BlackSquare()
cb = ChessBoard()
cs = CircleSurface()

pw1 = Pikeman()
pw1.destination = (225, 625)
# pw1.colour = (0, 0, 255)
# print('pw1 colour' + str(pw1.colour))
pw1.set_colour((0, 0, 255))
print('colour' + str(pw1.colour))

pw2 = Pikeman()
pw2.destination = (325, 625)
pw3 = Pikeman()
pw3.destination = (425, 625)
pw4 = Pikeman()
pw4.destination = (525, 625)
kw1 = Knight()
kw1.destination = (125, 625)

kw2 = Knight()
kw2.destination = (625, 625)

aw1 = Archer()
aw1.destination = (225, 725)
aw2 = Archer()
aw2.destination = (325, 725)
aw3 = Archer()
aw3.destination = (425, 725)
aw4 = Archer()
aw4.destination = (525, 725)


# Event loop (outer)

while 1:
    # Event loop (inner)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    # Draws needed objects and updates display

    cb.draw()

    # Draws white pieces in their initial position
    pw1.draw(game_window)
    pw1.draw_circle(game_window)
    pw2.draw(game_window)
    pw2.draw_circle(game_window)
    pw3.draw(game_window)
    pw3.draw_circle(game_window)
    pw4.draw(game_window)
    pw4.draw_circle(game_window)
    kw1.draw(game_window)
    kw1.draw_circle(game_window)
    kw2.draw(game_window)
    kw2.draw_circle(game_window)
    aw1.draw(game_window)
    aw1.draw_circle(game_window)
    aw2.draw(game_window)
    aw2.draw_circle(game_window)
    aw3.draw(game_window)
    aw3.draw_circle(game_window)
    aw4.draw(game_window)
    aw4.draw_circle(game_window)

    pygame.display.update()

as you can see from this chunk of code, and from all the variables I have created inside Pikeman(), I first tried to set the value for the colour variable directly, but then I tried to create a setter, well I can't make it work.

pw1 = Pikeman()
pw1.destination = (225, 625)
# pw1.colour = (0, 0, 255)
# print('pw1 colour' + str(pw1.colour))
pw1.set_colour((0, 0, 255))
print('colour' + str(pw1.colour))
2 Answers

Sorry that does not work like that, your assumption is wrong. Of course, if the value of self.color is changed,

def set_colour(self, colour):
   self.colour = colour

then each object which is drawn with the use self.colour, would be draw with the new color set.

Sadly self.colour is never used again to render anything. Note, self.colour is used in the constructor of the object to render a pygame.Surface:

def __init__(self):
   # [...]

   self.colour = (self.r, self.g, self.b)
   self.img = self.my_font.render(self.unit_type, 1, self.colour)

If you change the color which was used to render the Surface (image), then the image doesn't change magically.

When you change the color, then you've to render the Surface again:

class Pikeman(Unit):
    unit_type = 'P'
    destination = (int, int)
    colour = (int, int, int)

    def __init__(self):
        super().__init__()
        self.set_colour((0, 0, 0))

    def set_colour(self, colour):
        self.colour = colour
        self.img = self.my_font.render(self.unit_type, 1, self.colour)

    def draw(self, surface):
        surface.blit(self.img, self.destination)

The issue is the type int of class you initialize the rgb variables. I.e. if you gave alla zeros to the initial value it would be of a convienient type so you need to handle it differently.

def __init__(self):
    self.r = 0
    self.g = 0
    self.b = 0
    self.colour = (self.r, self.g, self.b)
    super().__init__()
    self.img = self.my_font.render(self.unit_type, 1, self.colour)

I am not saying this is the solution but here is your problem.

Related