使用 PyGame 在移动表面上分配静态遮罩
Assign static Mask on moving Surface with PyGame
我昨天刚开始我的第一个 PyGame 项目,我找不到如何正确使用遮罩实体应用到移动的表面上。
我为动画表面制作了一个特定的class
class LabelObject():
def __init__(self, surface, x, y, endX, speed, idleTime):
self.surface = surface
self.x = x
self.y = y
self.endX = endX
self.speed = speed
self.idleTime = idleTime
self.alpha = 255
self.timer_start = 0
self.timer_end = 0
self.pos = self.surface.get_rect(x=self.x,y=self.y)
def move(self):
self.timer_start += 1
if self.timer_start > self.idleTime:
if self.pos.right > self.endX:
self.pos.x += self.speed
elif self.pos.x < self.x:
self.timer_end += 1
if self.timer_end > self.idleTime:
self.alpha -= 25
if self.timer_end > self.idleTime + 11:
self.pos = self.surface.get_rect(x=self.x, y=self.y)
self.timer_start = 0
self.timer_end = 0
self.alpha = 255
self.surface.set_alpha(self.alpha)
此 class 的要点是检查表面是否超过给定区域,然后向左滑动以能够完整阅读其中呈现的文本。
在我的主循环中,我可以像这样将它 blit 到屏幕上
label = LabelObject(textSurface,20,10,100,-0.5,30)
while not over:
for event in pygame.event.get():
if event.type == pygame.QUIT
over = True
screen.fill((0,0,0))
label.move()
screen.blit(label.surface, label.pos)
pygame.display.update()
这很好用,但我需要在其上应用不需要移动的遮罩。对于此示例,遮罩的矩形将为 (20, 10, 100-20, label.surface.get_height())
。在网上看到了一些关于Mask的例子,但是没找到mask静止而表面运动时的使用方法
编辑: 我尝试在 blit 函数中使用区域选项,但有些奇怪,区域和表面移动不同步。
EDIT2: 最后这里是带区域选项的良好 blit 函数。只需要制作带有静态位置的blit,以及带有动画位置的区域:
self.screen.blit(label.surface, (label.x,label.y), area=pygame.Rect(label.x-label.pos.x, 0, label.endX-label.x, label.surface.get_height()))
我尝试用 subsurface
做完整的工作示例,以切断完整图像的可见部分。 Rect (sub_image_rect) 总是一样的——画在同一个地方。我只改变偏移量来切断图像的不同部分。
我使用文本和字体生成一些图像 - 每个人都可以 运行 它没有自己的图像。
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
# --- classes ---
class Label():
def __init__(self, text, x, y, width):
font = pygame.font.SysFont(None, 35)
# generate full image
self.image = font.render(text, True, RED)
self.rect = self.image.get_rect(x=x, y=y)
self.width = width
self.speed = 1
# offset of visible part
self.offset_x = 0
self.max_offset_x = self.rect.width - self.width
# visible part of image
self.sub_image = self.image.subsurface((self.offset_x,0), (self.width, self.rect.height))
self.sub_image_rect = self.sub_image.get_rect(x=x, y=y)
def move(self):
# change offset
self.offset_x += self.speed
# change move direction
if self.offset_x < 0:
self.offset_x = 0
self.speed = -self.speed
elif self.offset_x > self.max_offset_x:
self.offset_x = self.max_offset_x
self.speed = -self.speed
print self.offset_x, self.max_offset_x
# visible part of image
self.sub_image = self.image.subsurface((self.offset_x, 0),(self.width, self.rect.height))
def draw(self, surface):
surface.blit(self.sub_image, self.sub_image_rect)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
label = Label("Hello World of Python and Pygame!", 100, 100, 200)
# --- mainloop ---
fps = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# --- updates ---
label.move()
# --- draws ---
screen.fill(BLACK)
label.draw(screen)
fps.tick(25)
pygame.display.flip()
# --- the end ---
pygame.quit()
编辑: 我在 blit
中用 area
做了例子。我只更改了 3 行 - 请参阅代码
中的 # changed
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
# --- classes ---
class Label():
def __init__(self, text, x, y, width):
font = pygame.font.SysFont(None, 35)
# generate full image
self.image = font.render(text, True, RED)
self.rect = self.image.get_rect(x=x, y=y)
self.width = width
self.speed = 1
# offset of visible part
self.offset_x = 0
self.max_offset_x = self.rect.width - self.width
# visible part of image as 'rect' - 'width' is always the same
self.sub_image_rect = self.image.get_rect(x=0, width=self.width) # changed
def move(self):
# change offset
self.offset_x += self.speed
# change move direction
if self.offset_x < 0:
self.offset_x = 0
self.speed = -self.speed
elif self.offset_x > self.max_offset_x:
self.offset_x = self.max_offset_x
self.speed = -self.speed
# visible part of image - change only `x`
self.sub_image_rect.x = self.offset_x # changed
def draw(self, surface):
surface.blit(self.image, self.rect, area=self.sub_image_rect) # changed
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
label = Label("Hello World of Python and Pygame!", 100, 100, 200)
# --- mainloop ---
fps = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# --- updates ---
label.move()
# --- draws ---
screen.fill(BLACK)
label.draw(screen)
fps.tick(25)
pygame.display.flip()
# --- the end ---
pygame.quit()
我昨天刚开始我的第一个 PyGame 项目,我找不到如何正确使用遮罩实体应用到移动的表面上。
我为动画表面制作了一个特定的class
class LabelObject():
def __init__(self, surface, x, y, endX, speed, idleTime):
self.surface = surface
self.x = x
self.y = y
self.endX = endX
self.speed = speed
self.idleTime = idleTime
self.alpha = 255
self.timer_start = 0
self.timer_end = 0
self.pos = self.surface.get_rect(x=self.x,y=self.y)
def move(self):
self.timer_start += 1
if self.timer_start > self.idleTime:
if self.pos.right > self.endX:
self.pos.x += self.speed
elif self.pos.x < self.x:
self.timer_end += 1
if self.timer_end > self.idleTime:
self.alpha -= 25
if self.timer_end > self.idleTime + 11:
self.pos = self.surface.get_rect(x=self.x, y=self.y)
self.timer_start = 0
self.timer_end = 0
self.alpha = 255
self.surface.set_alpha(self.alpha)
此 class 的要点是检查表面是否超过给定区域,然后向左滑动以能够完整阅读其中呈现的文本。
在我的主循环中,我可以像这样将它 blit 到屏幕上
label = LabelObject(textSurface,20,10,100,-0.5,30)
while not over:
for event in pygame.event.get():
if event.type == pygame.QUIT
over = True
screen.fill((0,0,0))
label.move()
screen.blit(label.surface, label.pos)
pygame.display.update()
这很好用,但我需要在其上应用不需要移动的遮罩。对于此示例,遮罩的矩形将为 (20, 10, 100-20, label.surface.get_height())
。在网上看到了一些关于Mask的例子,但是没找到mask静止而表面运动时的使用方法
编辑: 我尝试在 blit 函数中使用区域选项,但有些奇怪,区域和表面移动不同步。
EDIT2: 最后这里是带区域选项的良好 blit 函数。只需要制作带有静态位置的blit,以及带有动画位置的区域:
self.screen.blit(label.surface, (label.x,label.y), area=pygame.Rect(label.x-label.pos.x, 0, label.endX-label.x, label.surface.get_height()))
我尝试用 subsurface
做完整的工作示例,以切断完整图像的可见部分。 Rect (sub_image_rect) 总是一样的——画在同一个地方。我只改变偏移量来切断图像的不同部分。
我使用文本和字体生成一些图像 - 每个人都可以 运行 它没有自己的图像。
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
# --- classes ---
class Label():
def __init__(self, text, x, y, width):
font = pygame.font.SysFont(None, 35)
# generate full image
self.image = font.render(text, True, RED)
self.rect = self.image.get_rect(x=x, y=y)
self.width = width
self.speed = 1
# offset of visible part
self.offset_x = 0
self.max_offset_x = self.rect.width - self.width
# visible part of image
self.sub_image = self.image.subsurface((self.offset_x,0), (self.width, self.rect.height))
self.sub_image_rect = self.sub_image.get_rect(x=x, y=y)
def move(self):
# change offset
self.offset_x += self.speed
# change move direction
if self.offset_x < 0:
self.offset_x = 0
self.speed = -self.speed
elif self.offset_x > self.max_offset_x:
self.offset_x = self.max_offset_x
self.speed = -self.speed
print self.offset_x, self.max_offset_x
# visible part of image
self.sub_image = self.image.subsurface((self.offset_x, 0),(self.width, self.rect.height))
def draw(self, surface):
surface.blit(self.sub_image, self.sub_image_rect)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
label = Label("Hello World of Python and Pygame!", 100, 100, 200)
# --- mainloop ---
fps = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# --- updates ---
label.move()
# --- draws ---
screen.fill(BLACK)
label.draw(screen)
fps.tick(25)
pygame.display.flip()
# --- the end ---
pygame.quit()
编辑: 我在 blit
中用 area
做了例子。我只更改了 3 行 - 请参阅代码
# changed
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
# --- classes ---
class Label():
def __init__(self, text, x, y, width):
font = pygame.font.SysFont(None, 35)
# generate full image
self.image = font.render(text, True, RED)
self.rect = self.image.get_rect(x=x, y=y)
self.width = width
self.speed = 1
# offset of visible part
self.offset_x = 0
self.max_offset_x = self.rect.width - self.width
# visible part of image as 'rect' - 'width' is always the same
self.sub_image_rect = self.image.get_rect(x=0, width=self.width) # changed
def move(self):
# change offset
self.offset_x += self.speed
# change move direction
if self.offset_x < 0:
self.offset_x = 0
self.speed = -self.speed
elif self.offset_x > self.max_offset_x:
self.offset_x = self.max_offset_x
self.speed = -self.speed
# visible part of image - change only `x`
self.sub_image_rect.x = self.offset_x # changed
def draw(self, surface):
surface.blit(self.image, self.rect, area=self.sub_image_rect) # changed
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
label = Label("Hello World of Python and Pygame!", 100, 100, 200)
# --- mainloop ---
fps = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# --- updates ---
label.move()
# --- draws ---
screen.fill(BLACK)
label.draw(screen)
fps.tick(25)
pygame.display.flip()
# --- the end ---
pygame.quit()