Смена атрибута класса

IgRick

Новичок
Пользователь
Июн 24, 2024
4
2
3
Добрый день. Осваиваю pygame. В данном коде есть статичный блок и тот которым можно управлять. У меня получилось реализовать следующую механику - при соприкосновении блоков статичный блок удаляется.

Хотелось бы понять, как можно сделать так, чтобы при соприкосновении блоков, статичный блок менял цвет с красного на зеленый, а при повторном соприкосновении с зеленого, ну например на желтый.

Код:
import pygame

pygame.init()

WIDTH, HEIGHT = 800, 600
FPS = 60
TILE = 50

window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

DIRECTS = [[0, -1], [1, 0], [0, 1], [-1, 0]]


class BlockGo:
    def __init__(self, color, px, py, direct, keyList, damage):
        objects.append(self)
        self.type = 'blockgo'

        self.color = color
        self.rect = pygame.Rect(px, py, TILE, TILE)
        self.direct = direct  # направление
        self.moveSpeed = 2
        self.damage = damage

        self.keyLEFT = keyList[0]
        self.keyRIGHT = keyList[1]
        self.keyUP = keyList[2]
        self.keyDOWN = keyList[3]

    def update(self):

        oldX, oldY = self.rect.topleft
        if keys[self.keyLEFT]:
            self.rect.x -= self.moveSpeed
            self.direct = 3
        elif keys[self.keyRIGHT]:
            self.rect.x += self.moveSpeed
            self.direct = 1
        elif keys[self.keyUP]:
            self.rect.y -= self.moveSpeed
            self.direct = 0
        elif keys[self.keyDOWN]:
            self.rect.y += self.moveSpeed
            self.direct = 2
        for obj in objects:
            if obj != self and self.rect.colliderect(obj.rect):
                self.rect.topleft = oldX, oldY
        for objcr in objectscrash:
            if self.rect.colliderect(objcr.rect):
                objectscrash.remove(objcr.rect)

    def draw(self):
        pygame.draw.rect(window, self.color, self.rect)
        x = self.rect.centerx + DIRECTS[self.direct][0] * 30
        y = self.rect.centerx + DIRECTS[self.direct][0] * 30

class Block:

    def __init__(self, color, px, py, size):
        objectscrash.append(self)
        self.type = 'block'
        self.color = color

        self.rect = pygame.Rect(px, py, size, size)

    def update(self):
        pass

    def draw(self):
        pygame.draw.rect(window, self.color, self.rect)


objectscrash = []
objects = []

BlockGo('blue', 100, 275, 0, (pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s), 1)

Block('red', 200, 100, TILE)

play = True
while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            play = False

    keys = pygame.key.get_pressed()
    for objcr in objectscrash: objcr.update()
    for obj in objects: obj.update()

    window.fill('black')
    for objcr in objectscrash: objcr.draw()
    for obj in objects: obj.draw()

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()
 

IgRick

Новичок
Пользователь
Июн 24, 2024
4
2
3
Всем привет!
Я вроде как сам справился(в итоге не справился, листайте ниже) с задачей по итогу. Если вдруг кого заинтересовало, ниже напишу свой вариант.
Но он не очень пайтоник=D. Если кто-то предложит более лаконичное решение, буду рад обратной связи.

Эту часть кода вообще убрал.
for objcr in objectscrash:
if self.rect.colliderect(objcr.rect):
objectscrash.remove(objcr.rect)

Далее в класс Block добавил функцию
def set_color(self, new_color):
self.color = new_color

Создал переменную block_1 = Block('green', 200, 100, TILE)

Добавил счетчик для последовательной смены цветов блока
counter = 2

И в цикл while добавил следующую структуру

Код:
for obj in objects:
        for objcr in objectscrash:
            if obj.rect.colliderect(objcr.rect) and counter == 2 and start_time == 0:
                counter -= 1
                block_1.set_color('yellow')
                start_time = end_time
            if start_time > 0:
                start_time -= 1
            if obj.rect.colliderect(objcr.rect) and counter == 1 and start_time == 0:
                counter -= 1
                block_1.set_color('red')
                start_time = end_time
            if start_time > 0:
                start_time -= 1

Да и как можно увидеть выше, реализовал 5ти секундный таймер, для задержки переключений цветов, по средствам переменных:
start_time = 0
end_time = 300
 
Последнее редактирование:
  • Мне нравится
Реакции: regnor

IgRick

Новичок
Пользователь
Июн 24, 2024
4
2
3
Вот весь код программы с реализованной механикой
Код:
import pygame

pygame.init()

WIDTH, HEIGHT = 800, 600
FPS = 60
TILE = 50

window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

DIRECTS = [[0, -1], [1, 0], [0, 1], [-1, 0]]


class BlockGo:
    def __init__(self, color, px, py, direct, keyList, damage):
        objects.append(self)
        self.type = 'blockgo'

        self.color = color
        self.rect = pygame.Rect(px, py, TILE, TILE)
        self.direct = direct  # направление
        self.moveSpeed = 2
        self.damage = damage

        self.keyLEFT = keyList[0]
        self.keyRIGHT = keyList[1]
        self.keyUP = keyList[2]
        self.keyDOWN = keyList[3]

    def update(self):

        oldX, oldY = self.rect.topleft
        if keys[self.keyLEFT]:
            self.rect.x -= self.moveSpeed
            self.direct = 3
        elif keys[self.keyRIGHT]:
            self.rect.x += self.moveSpeed
            self.direct = 1
        elif keys[self.keyUP]:
            self.rect.y -= self.moveSpeed
            self.direct = 0
        elif keys[self.keyDOWN]:
            self.rect.y += self.moveSpeed
            self.direct = 2
        for obj in objects:
            if obj != self and self.rect.colliderect(obj.rect):
                self.rect.topleft = oldX, oldY


    def draw(self):
        pygame.draw.rect(window, self.color, self.rect)
        x = self.rect.centerx + DIRECTS[self.direct][0] * 30
        y = self.rect.centerx + DIRECTS[self.direct][0] * 30

class Block:

    def __init__(self, color, px, py, size):
        objectscrash.append(self)
        self.type = 'block'
        self.color = color
        self.rect = pygame.Rect(px, py, size, size)

    def update(self):
        pass

    def draw(self):
        pygame.draw.rect(window, self.color, self.rect)

    def set_color(self, new_color):
        self.color = new_color

objectscrash = []
objects = []

BlockGo('blue', 100, 275, 0, (pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s), 1)
block_1 = Block('green', 200, 100, TILE)
counter = 2
start_time = 0
end_time = 300

play = True
while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            play = False

    keys = pygame.key.get_pressed()
    for objcr in objectscrash: objcr.update()
    for obj in objects: obj.update()

    window.fill('black')
    for objcr in objectscrash: objcr.draw()
    for obj in objects: obj.draw()

    for obj in objects:
        for objcr in objectscrash:
            if obj.rect.colliderect(objcr.rect) and counter == 2 and start_time == 0:
                counter -= 1
                block_1.set_color('yellow')
                start_time = end_time
            if start_time > 0:
                start_time -= 1
            if obj.rect.colliderect(objcr.rect) and counter == 1 and start_time == 0:
                counter -= 1
                block_1.set_color('red')
                start_time = end_time
            if start_time > 0:
                start_time -= 1

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()
 
  • Мне нравится
Реакции: regnor

IgRick

Новичок
Пользователь
Июн 24, 2024
4
2
3
Я решил немного доработать данную механику.
Может быть кто-нибудь знает как сделать следующее?

Допустим блок которым мы управляем наехал на статичный блок и статичный блок поменял цвет с зеленого на желтый.
Далее пока подвижный блок находиться на статичном, цвет не меняется.
Потом подвижный блок съезжает со статичного и больше его не касается
Но при повторном соприкосновении блоков, статичный меняет цвет на красный.

Ко мне в голову решение пока-что не приходит
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 645
472
83
проверять координаты сторон блоков

при столкновении меняем цвет, ставим флаг true
пока флаг true, идет столкновение
если есть общие точки, значит есть соприкосновение, подвижный блок на статичном
если нет общих точек, значит они разъехались, ставим флаг false
далее снова проверяем общие точки, как только появились общие точки, значит произошло столкновение, снова меняем цвет, ставим флаг true

это первое что пришло в голову
 

Форум IT Специалистов