Как рассчитать пиксель перекрытия 2 поверхностей? - PullRequest
0 голосов
/ 27 августа 2018

Я хочу написать программу, которая делает область перекрытия двух поверхностей пигмеев полупрозрачной ...
Я использую pygame.mask для столкновения.

import pygame as pg
from pygame.locals import *

bg_surface = pg.Surface((400, 400), pg.SRCALPHA)
rect = Rect((0, 0), (400, 400))
pg.draw.rect(bg_surface, (30, 90, 200), rect)

rect_surface = pg.Surface((50, 50), pg.SRCALPHA)
rect = Rect((0, 0), (50, 50))
pg.draw.rect(rect_surface, (160, 250, 0), rect)


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    bg_mask = pg.mask.from_surface(bg_surface)
    rect_mask = pg.mask.from_surface(rect_surface)

    bg_rect = bg_surface.get_rect(center=(320, 240))
    triangle_rect = rect_surface.get_rect(center=(0, 0))

    done = False

    while not done:
        clock.tick(30)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.MOUSEMOTION:
                triangle_rect.center = event.pos
        pg.draw.rect(rect_surface, (160, 250, 0), rect)
        offset_x = bg_rect.x - triangle_rect.x
        offset_y = bg_rect.y - triangle_rect.y
        print(offset_x, offset_y)
        overlap = rect_mask.overlap(bg_mask, (offset_x, offset_y))
        if overlap:
            print('The two masks overlap!', rect_mask.overlap_area(bg_mask, (offset_x, offset_y)))
            overlap_mask = rect_mask.overlap_mask(bg_mask, (offset_x, offset_y))
            print(overlap_mask.count())
            array = pg.surfarray.pixels_alpha(rect_surface)
            width, height = overlap_mask.get_size()
            for y in range(height):
                for x in range(width):
                    if overlap_mask.get_at((x, y)):
                        array[x, y] = 127
            del array
        screen.fill((130, 130, 130))
        screen.blit(bg_surface, bg_rect)
        screen.blit(rect_surface, triangle_rect)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

enter image description here

overlap_area() и overlap_mask.count() не совпадают!

версия Pygame: 1.9.4

1 Ответ

0 голосов
/ 28 августа 2018

К черту overlap_mask, это работает:

import pygame as pg
from pygame.locals import *

bg_surface = pg.Surface((400, 400), pg.SRCALPHA)
rect = Rect((0, 0), (400, 400))
pg.draw.rect(bg_surface, (30, 90, 200), rect)

rect_surface = pg.Surface((50, 50), pg.SRCALPHA)
rect = Rect((0, 0), (50, 50))
pg.draw.rect(rect_surface, (160, 250, 0), rect)


def main():
    screen = pg.display.set_mode((800, 800))
    clock = pg.time.Clock()

    bg_mask = pg.mask.from_surface(bg_surface)
    rect_mask = pg.mask.from_surface(rect_surface)
    bg_rect = bg_surface.get_rect(center=(320, 240))
    small_rect = rect_surface.get_rect(center=(0, 0))

    done = False

    while not done:
        clock.tick(30)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.MOUSEMOTION:
                small_rect.center = event.pos
        pg.draw.rect(rect_surface, (160, 250, 0), rect)
        offset_x = bg_rect.x - small_rect.x
        offset_y = bg_rect.y - small_rect.y
        if rect_mask.overlap(bg_mask, (offset_x, offset_y)):
            array = pg.surfarray.pixels_alpha(rect_surface)
            width, height = rect_mask.get_size()
            w, h = bg_mask.get_size()
            for y in range(height):
                for x in range(width):
                    if rect_mask.get_at((x, y)) and (0 <= x - offset_x < w and 0 <= y - offset_y < h and bg_mask.get_at((x - offset_x, y - offset_y))):
                        array[x, y] = 127
            del array
        screen.fill((130, 130, 130))
        screen.blit(bg_surface, bg_rect)
        screen.blit(rect_surface, small_rect)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
...