使用PyGame在移动Surface上指定静态蒙版

时间:2015-12-26 13:51:54

标签: python pygame mask pygame-surface

我昨天刚刚开始我的第一个PyGame项目,我无法找到如何正确使用Mask实体应用于移动的Surface。

我为动画Surfaces

制作了一个特定的类
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)

此类的要点是检查曲面是否超出给定区域,并向左滑动以便能够完全读取其中呈现的文本。

在我的主循环中,我可以将它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()

这样可以正常工作,但我需要在其上应用一个不需要移动的面具。对于此示例,掩码的Rect将为(20, 10, 100-20, label.surface.get_height())。我在网上看到一些关于Mask的例子,但是当面具是静态的并且表面正在移动时,我没有找到使用它的方法。

编辑:我尝试在blit功能中使用区域选项,但是有些奇怪,区域和Surface移动不同步。

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()))

1 个答案:

答案 0 :(得分:0)

我尝试使用import android.graphics.Bitmap; import android.graphics.Canvas; import android.widget.ImageView; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Response; import com.android.volley.toolbox.HttpHeaderParser; import com.android.volley.toolbox.ImageRequest; import com.caverock.androidsvg.SVG; import com.caverock.androidsvg.SVGParseException; /** * Version modifiée de ImageRequest de Volley pour gérer aussi les images SVG */ public class MultiFormatImageRequest extends ImageRequest { final String TAG = "EE." + getClass().getSimpleName(); boolean isSVG = false; public MultiFormatImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, ImageView.ScaleType scaleType, Bitmap.Config decodeConfig, Response.ErrorListener errorListener) { super(url, listener, maxWidth, maxHeight, scaleType, decodeConfig, errorListener); String extension = url.substring(url.lastIndexOf(".")); isSVG = (extension.toUpperCase().contains("SVG")); } /**** * ATTENTION : "private" Response in Volley need to be changed in protected */ @Override protected Response<Bitmap> doParse(NetworkResponse response) { Bitmap image = null; if (isSVG) { try { SVG svg = SVG.getFromString(new String(response.data)); int h = (int) svg.getDocumentHeight(); int w = (int) svg.getDocumentWidth(); image = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444); // transparent Canvas bmcanvas = new Canvas(image); svg.renderToCanvas(bmcanvas); } catch (SVGParseException ex) { ex.printStackTrace(); } if (image == null) { return Response.error(new ParseError(response)); } else { return Response.success(image, HttpHeaderParser.parseCacheHeaders(response)); } } else return super.doParse(response); // Volley default } } 做完整的工作示例,以切断完整图像的可见部分。 Rect(sub_image_rect)总是相同的 - 在同一个地方绘制。我只改变偏移量以切断图像的不同部分。

我使用文本和字体生成一些图像 - 每个人都可以在没有自己的图像的情况下运行它。

subsurface

编辑:我在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() 中使用area做了示例。我只更改了3行 - 请参阅代码中的blit

# changed