Создание "рамки", которая скрывает все, кроме того, что содержится в Pygame
Я только начал с pyGame и хотел бы создать рамку, которая обрезает все, что я показываю на экране. т.е. независимо от того, что содержит мой мир, этот кадр должен охватывать все, кроме того, что он содержит.
Думайте об этом как о рамке, используемой для обрезки изображений на iphone (см. Рисунок ниже). В конце концов я хочу сделать фрейм интерактивным, чтобы я мог перемещать его или изменять его размер, но пока статический фрейм подойдет. И я понятия не имею, с чего начать.. любая помощь приветствуется!
[
1 ответ
Есть несколько способов сделать это; один из способов - нарисовать черное Surface
на весь экран, но есть "дыра" в этом черном Surface
,
Простой способ создать эту "дыру" - просто нарисовать прямоугольник с правой colorkey
, Что colorkey
?
При перетаскивании этой поверхности на место назначения все пиксели того же цвета, что и цветовой ключ, будут прозрачными.
Звучит полезно, поэтому давайте попробуем:
import random
import pygame as pg
IMAGE = pg.Surface((50, 50), pg.SRCALPHA)
pg.draw.polygon(IMAGE, (240, 120, 0), [(0, 50), (25, 0), (50, 50)])
class Actor(pg.sprite.Sprite):
def __init__(self, grp, bounds, pos):
self._layer = 0
pg.sprite.Sprite.__init__(self, grp)
self.image = IMAGE
self.rect = self.image.get_rect(center=pos)
self.vec = pg.math.Vector2()
# just a random directon for movement
self.vec.from_polar((10, random.randrange(0, 360)))
self.bounds = bounds
def update(self):
self.rect.move_ip(*self.vec)
# try staying on screen
if not self.bounds.contains(self.rect):
self.vec.from_polar((10, random.randrange(0, 360)))
class Cursor(pg.sprite.Sprite):
def __init__(self, grp, bounds):
self._layer = 1000
pg.sprite.Sprite.__init__(self, grp)
self.image = pg.Surface((bounds.width, bounds.height))
self.image.set_colorkey(pg.Color('yellow'))
# we start with the entire screen black
# if the screen should be fully visible at the start, we could use yellow instead
self.image.fill(pg.Color('black'))
self.rect = self.image.get_rect()
# here we store the position of the mouse when we start drawing the hole
self.start = None
# here we store the entire rect of the hole so we can later move it around
self.inner_rect = None
def mousedown(self):
self.start = pg.mouse.get_pos()
def mouseup(self):
self.start = None
def move(self, rel):
self.inner_rect.move_ip(rel)
self.recreate()
def update(self):
if not self.start:
return
pos = pg.mouse.get_pos()
p = pos[0] - self.start[0], pos[1] - self.start[1]
self.inner_rect = pg.Rect(self.start, p)
self.recreate()
def recreate(self):
# here we update our hole
self.image.fill(pg.Color('black'))
pg.draw.rect(self.image, pg.Color('yellow'), self.inner_rect)
pg.draw.rect(self.image, pg.Color('white'), self.inner_rect, 2)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.LayeredUpdates()
cursor = Cursor(all_sprites, screen.get_rect())
for _ in range(20):
Actor(all_sprites, screen.get_rect(), (random.randrange(600), random.randrange(440)))
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1:
cursor.mousedown()
if event.type == pg.MOUSEBUTTONUP:
if event.button == 1:
cursor.mouseup()
if event.type == pg.MOUSEMOTION:
if pg.mouse.get_pressed()[2]:
cursor.move(event.rel)
all_sprites.update()
screen.fill(pg.Color('darkblue'))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Используйте левую кнопку мыши, чтобы начать рисовать рамку, и используйте правую кнопку мыши, чтобы переместить ее.
Как видите, у нас есть черный Surface
с желтым цветом Когда мы хотим сделать видимой часть экрана, мы рисуем желтый прямоугольник, который, в свою очередь, будет прозрачным, делая сцену под ним видимой.