Pygame Combine Sprites









up vote
0
down vote

favorite












I am trying to build a game in which combining images (pygame sprites) is an essential tool.



I have set up my code such that I can move sprites across x,y with the mouse and rotate them. The sprites are blitted to the display surface and so this motion can be seen on screen.



Once the user has arranged two sprites as they wish within a square zone, I need them to be able to save this whole zone as a new sprite.



I cannot see a way currently on pygame to capture a region of the display and store this as a sprite. Is this possible? What functions should I use for this purpose?










share|improve this question





















  • There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
    – usr2564301
    Nov 9 at 22:13










  • Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
    – Prune
    Nov 9 at 22:28














up vote
0
down vote

favorite












I am trying to build a game in which combining images (pygame sprites) is an essential tool.



I have set up my code such that I can move sprites across x,y with the mouse and rotate them. The sprites are blitted to the display surface and so this motion can be seen on screen.



Once the user has arranged two sprites as they wish within a square zone, I need them to be able to save this whole zone as a new sprite.



I cannot see a way currently on pygame to capture a region of the display and store this as a sprite. Is this possible? What functions should I use for this purpose?










share|improve this question





















  • There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
    – usr2564301
    Nov 9 at 22:13










  • Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
    – Prune
    Nov 9 at 22:28












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am trying to build a game in which combining images (pygame sprites) is an essential tool.



I have set up my code such that I can move sprites across x,y with the mouse and rotate them. The sprites are blitted to the display surface and so this motion can be seen on screen.



Once the user has arranged two sprites as they wish within a square zone, I need them to be able to save this whole zone as a new sprite.



I cannot see a way currently on pygame to capture a region of the display and store this as a sprite. Is this possible? What functions should I use for this purpose?










share|improve this question













I am trying to build a game in which combining images (pygame sprites) is an essential tool.



I have set up my code such that I can move sprites across x,y with the mouse and rotate them. The sprites are blitted to the display surface and so this motion can be seen on screen.



Once the user has arranged two sprites as they wish within a square zone, I need them to be able to save this whole zone as a new sprite.



I cannot see a way currently on pygame to capture a region of the display and store this as a sprite. Is this possible? What functions should I use for this purpose?







python pygame pygame-surface






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 9 at 22:09









Didgeridude

6




6











  • There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
    – usr2564301
    Nov 9 at 22:13










  • Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
    – Prune
    Nov 9 at 22:28
















  • There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
    – usr2564301
    Nov 9 at 22:13










  • Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
    – Prune
    Nov 9 at 22:28















There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
– usr2564301
Nov 9 at 22:13




There might be a function for it (did you check the documentation?), but why not make a custom class that stores a list of sprites to draw?
– usr2564301
Nov 9 at 22:13












Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
– Prune
Nov 9 at 22:28




Do you really need the region to be a new sprite, or do you merely need to weld the sprites together?
– Prune
Nov 9 at 22:28












1 Answer
1






active

oldest

votes

















up vote
0
down vote













You could check which sprites collide with the square area and pass them to a Combined sprite class, combine the rects with the union_ip method and create a new surface with the necessary size to blit the surfaces of the single sprites onto it. (Press C to combine the sprites.)



import pygame as pg


BLUE = pg.Color('dodgerblue1')
SIENNA = pg.Color('sienna1')
GREEN = pg.Color('green')


class Entity(pg.sprite.Sprite):

def __init__(self, pos, color):
super().__init__()
self.image = pg.Surface((42, 68))
self.image.fill(color)
self.rect = self.image.get_rect(topleft=pos)

def move(self, velocity):
self.rect.move_ip(velocity)


class Combined(pg.sprite.Sprite):

def __init__(self, sprites):
super().__init__()
# Combine the rects of the separate sprites.
self.rect = sprites[0].rect.copy()
for sprite in sprites[1:]:
self.rect.union_ip(sprite.rect)

# Create a new transparent image with the combined size.
self.image = pg.Surface(self.rect.size, pg.SRCALPHA)
# Now blit all sprites onto the new surface.
for sprite in sprites:
self.image.blit(sprite.image, (sprite.rect.x-self.rect.left,
sprite.rect.y-self.rect.top))

def move(self, velocity):
self.rect.move_ip(velocity)


def main():
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
entity = Entity((50, 80), BLUE)
entity2 = Entity((50, 180), SIENNA)
all_sprites = pg.sprite.Group(entity, entity2)
area = pg.Rect(200, 50, 200, 200)
selected = None

while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
elif event.type == pg.MOUSEBUTTONDOWN:
for sprite in all_sprites:
if sprite.rect.collidepoint(event.pos):
selected = sprite
elif event.type == pg.MOUSEBUTTONUP:
selected = None
elif event.type == pg.MOUSEMOTION:
if selected:
selected.move(event.rel)
elif event.type == pg.KEYDOWN:
if event.key == pg.K_c:
# A 'list comprehension' to find the colliding sprites.
colliding_sprites = [sprite for sprite in all_sprites
if sprite.rect.colliderect(area)]
combined = Combined(colliding_sprites)
all_sprites.add(combined)
# Kill the colliding sprites if they should be removed.
# for sprite in colliding_sprites:
# sprite.kill()

all_sprites.update()
screen.fill((30, 30, 30))
pg.draw.rect(screen, SIENNA, area, 2)
all_sprites.draw(screen)
for sprite in all_sprites: # Outlines.
pg.draw.rect(screen, GREEN, sprite.rect, 1)

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

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


Alternatively, you could try to add the combined sprites to another sprite group or a list and blit and move them together.






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233894%2fpygame-combine-sprites%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    You could check which sprites collide with the square area and pass them to a Combined sprite class, combine the rects with the union_ip method and create a new surface with the necessary size to blit the surfaces of the single sprites onto it. (Press C to combine the sprites.)



    import pygame as pg


    BLUE = pg.Color('dodgerblue1')
    SIENNA = pg.Color('sienna1')
    GREEN = pg.Color('green')


    class Entity(pg.sprite.Sprite):

    def __init__(self, pos, color):
    super().__init__()
    self.image = pg.Surface((42, 68))
    self.image.fill(color)
    self.rect = self.image.get_rect(topleft=pos)

    def move(self, velocity):
    self.rect.move_ip(velocity)


    class Combined(pg.sprite.Sprite):

    def __init__(self, sprites):
    super().__init__()
    # Combine the rects of the separate sprites.
    self.rect = sprites[0].rect.copy()
    for sprite in sprites[1:]:
    self.rect.union_ip(sprite.rect)

    # Create a new transparent image with the combined size.
    self.image = pg.Surface(self.rect.size, pg.SRCALPHA)
    # Now blit all sprites onto the new surface.
    for sprite in sprites:
    self.image.blit(sprite.image, (sprite.rect.x-self.rect.left,
    sprite.rect.y-self.rect.top))

    def move(self, velocity):
    self.rect.move_ip(velocity)


    def main():
    pg.init()
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    entity = Entity((50, 80), BLUE)
    entity2 = Entity((50, 180), SIENNA)
    all_sprites = pg.sprite.Group(entity, entity2)
    area = pg.Rect(200, 50, 200, 200)
    selected = None

    while True:
    for event in pg.event.get():
    if event.type == pg.QUIT:
    return
    elif event.type == pg.MOUSEBUTTONDOWN:
    for sprite in all_sprites:
    if sprite.rect.collidepoint(event.pos):
    selected = sprite
    elif event.type == pg.MOUSEBUTTONUP:
    selected = None
    elif event.type == pg.MOUSEMOTION:
    if selected:
    selected.move(event.rel)
    elif event.type == pg.KEYDOWN:
    if event.key == pg.K_c:
    # A 'list comprehension' to find the colliding sprites.
    colliding_sprites = [sprite for sprite in all_sprites
    if sprite.rect.colliderect(area)]
    combined = Combined(colliding_sprites)
    all_sprites.add(combined)
    # Kill the colliding sprites if they should be removed.
    # for sprite in colliding_sprites:
    # sprite.kill()

    all_sprites.update()
    screen.fill((30, 30, 30))
    pg.draw.rect(screen, SIENNA, area, 2)
    all_sprites.draw(screen)
    for sprite in all_sprites: # Outlines.
    pg.draw.rect(screen, GREEN, sprite.rect, 1)

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

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


    Alternatively, you could try to add the combined sprites to another sprite group or a list and blit and move them together.






    share|improve this answer
























      up vote
      0
      down vote













      You could check which sprites collide with the square area and pass them to a Combined sprite class, combine the rects with the union_ip method and create a new surface with the necessary size to blit the surfaces of the single sprites onto it. (Press C to combine the sprites.)



      import pygame as pg


      BLUE = pg.Color('dodgerblue1')
      SIENNA = pg.Color('sienna1')
      GREEN = pg.Color('green')


      class Entity(pg.sprite.Sprite):

      def __init__(self, pos, color):
      super().__init__()
      self.image = pg.Surface((42, 68))
      self.image.fill(color)
      self.rect = self.image.get_rect(topleft=pos)

      def move(self, velocity):
      self.rect.move_ip(velocity)


      class Combined(pg.sprite.Sprite):

      def __init__(self, sprites):
      super().__init__()
      # Combine the rects of the separate sprites.
      self.rect = sprites[0].rect.copy()
      for sprite in sprites[1:]:
      self.rect.union_ip(sprite.rect)

      # Create a new transparent image with the combined size.
      self.image = pg.Surface(self.rect.size, pg.SRCALPHA)
      # Now blit all sprites onto the new surface.
      for sprite in sprites:
      self.image.blit(sprite.image, (sprite.rect.x-self.rect.left,
      sprite.rect.y-self.rect.top))

      def move(self, velocity):
      self.rect.move_ip(velocity)


      def main():
      pg.init()
      screen = pg.display.set_mode((640, 480))
      clock = pg.time.Clock()
      entity = Entity((50, 80), BLUE)
      entity2 = Entity((50, 180), SIENNA)
      all_sprites = pg.sprite.Group(entity, entity2)
      area = pg.Rect(200, 50, 200, 200)
      selected = None

      while True:
      for event in pg.event.get():
      if event.type == pg.QUIT:
      return
      elif event.type == pg.MOUSEBUTTONDOWN:
      for sprite in all_sprites:
      if sprite.rect.collidepoint(event.pos):
      selected = sprite
      elif event.type == pg.MOUSEBUTTONUP:
      selected = None
      elif event.type == pg.MOUSEMOTION:
      if selected:
      selected.move(event.rel)
      elif event.type == pg.KEYDOWN:
      if event.key == pg.K_c:
      # A 'list comprehension' to find the colliding sprites.
      colliding_sprites = [sprite for sprite in all_sprites
      if sprite.rect.colliderect(area)]
      combined = Combined(colliding_sprites)
      all_sprites.add(combined)
      # Kill the colliding sprites if they should be removed.
      # for sprite in colliding_sprites:
      # sprite.kill()

      all_sprites.update()
      screen.fill((30, 30, 30))
      pg.draw.rect(screen, SIENNA, area, 2)
      all_sprites.draw(screen)
      for sprite in all_sprites: # Outlines.
      pg.draw.rect(screen, GREEN, sprite.rect, 1)

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

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


      Alternatively, you could try to add the combined sprites to another sprite group or a list and blit and move them together.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        You could check which sprites collide with the square area and pass them to a Combined sprite class, combine the rects with the union_ip method and create a new surface with the necessary size to blit the surfaces of the single sprites onto it. (Press C to combine the sprites.)



        import pygame as pg


        BLUE = pg.Color('dodgerblue1')
        SIENNA = pg.Color('sienna1')
        GREEN = pg.Color('green')


        class Entity(pg.sprite.Sprite):

        def __init__(self, pos, color):
        super().__init__()
        self.image = pg.Surface((42, 68))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=pos)

        def move(self, velocity):
        self.rect.move_ip(velocity)


        class Combined(pg.sprite.Sprite):

        def __init__(self, sprites):
        super().__init__()
        # Combine the rects of the separate sprites.
        self.rect = sprites[0].rect.copy()
        for sprite in sprites[1:]:
        self.rect.union_ip(sprite.rect)

        # Create a new transparent image with the combined size.
        self.image = pg.Surface(self.rect.size, pg.SRCALPHA)
        # Now blit all sprites onto the new surface.
        for sprite in sprites:
        self.image.blit(sprite.image, (sprite.rect.x-self.rect.left,
        sprite.rect.y-self.rect.top))

        def move(self, velocity):
        self.rect.move_ip(velocity)


        def main():
        pg.init()
        screen = pg.display.set_mode((640, 480))
        clock = pg.time.Clock()
        entity = Entity((50, 80), BLUE)
        entity2 = Entity((50, 180), SIENNA)
        all_sprites = pg.sprite.Group(entity, entity2)
        area = pg.Rect(200, 50, 200, 200)
        selected = None

        while True:
        for event in pg.event.get():
        if event.type == pg.QUIT:
        return
        elif event.type == pg.MOUSEBUTTONDOWN:
        for sprite in all_sprites:
        if sprite.rect.collidepoint(event.pos):
        selected = sprite
        elif event.type == pg.MOUSEBUTTONUP:
        selected = None
        elif event.type == pg.MOUSEMOTION:
        if selected:
        selected.move(event.rel)
        elif event.type == pg.KEYDOWN:
        if event.key == pg.K_c:
        # A 'list comprehension' to find the colliding sprites.
        colliding_sprites = [sprite for sprite in all_sprites
        if sprite.rect.colliderect(area)]
        combined = Combined(colliding_sprites)
        all_sprites.add(combined)
        # Kill the colliding sprites if they should be removed.
        # for sprite in colliding_sprites:
        # sprite.kill()

        all_sprites.update()
        screen.fill((30, 30, 30))
        pg.draw.rect(screen, SIENNA, area, 2)
        all_sprites.draw(screen)
        for sprite in all_sprites: # Outlines.
        pg.draw.rect(screen, GREEN, sprite.rect, 1)

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

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


        Alternatively, you could try to add the combined sprites to another sprite group or a list and blit and move them together.






        share|improve this answer












        You could check which sprites collide with the square area and pass them to a Combined sprite class, combine the rects with the union_ip method and create a new surface with the necessary size to blit the surfaces of the single sprites onto it. (Press C to combine the sprites.)



        import pygame as pg


        BLUE = pg.Color('dodgerblue1')
        SIENNA = pg.Color('sienna1')
        GREEN = pg.Color('green')


        class Entity(pg.sprite.Sprite):

        def __init__(self, pos, color):
        super().__init__()
        self.image = pg.Surface((42, 68))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=pos)

        def move(self, velocity):
        self.rect.move_ip(velocity)


        class Combined(pg.sprite.Sprite):

        def __init__(self, sprites):
        super().__init__()
        # Combine the rects of the separate sprites.
        self.rect = sprites[0].rect.copy()
        for sprite in sprites[1:]:
        self.rect.union_ip(sprite.rect)

        # Create a new transparent image with the combined size.
        self.image = pg.Surface(self.rect.size, pg.SRCALPHA)
        # Now blit all sprites onto the new surface.
        for sprite in sprites:
        self.image.blit(sprite.image, (sprite.rect.x-self.rect.left,
        sprite.rect.y-self.rect.top))

        def move(self, velocity):
        self.rect.move_ip(velocity)


        def main():
        pg.init()
        screen = pg.display.set_mode((640, 480))
        clock = pg.time.Clock()
        entity = Entity((50, 80), BLUE)
        entity2 = Entity((50, 180), SIENNA)
        all_sprites = pg.sprite.Group(entity, entity2)
        area = pg.Rect(200, 50, 200, 200)
        selected = None

        while True:
        for event in pg.event.get():
        if event.type == pg.QUIT:
        return
        elif event.type == pg.MOUSEBUTTONDOWN:
        for sprite in all_sprites:
        if sprite.rect.collidepoint(event.pos):
        selected = sprite
        elif event.type == pg.MOUSEBUTTONUP:
        selected = None
        elif event.type == pg.MOUSEMOTION:
        if selected:
        selected.move(event.rel)
        elif event.type == pg.KEYDOWN:
        if event.key == pg.K_c:
        # A 'list comprehension' to find the colliding sprites.
        colliding_sprites = [sprite for sprite in all_sprites
        if sprite.rect.colliderect(area)]
        combined = Combined(colliding_sprites)
        all_sprites.add(combined)
        # Kill the colliding sprites if they should be removed.
        # for sprite in colliding_sprites:
        # sprite.kill()

        all_sprites.update()
        screen.fill((30, 30, 30))
        pg.draw.rect(screen, SIENNA, area, 2)
        all_sprites.draw(screen)
        for sprite in all_sprites: # Outlines.
        pg.draw.rect(screen, GREEN, sprite.rect, 1)

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

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


        Alternatively, you could try to add the combined sprites to another sprite group or a list and blit and move them together.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 10 at 11:09









        skrx

        14.8k31833




        14.8k31833



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233894%2fpygame-combine-sprites%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20