[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] image & sprite module



azazel wrote:
> I've created a 600x750 image, where I've put 80 frame that represent all the
> position of a sprite(a spider for the precision), with a trasparent background.
> Every frame is 75x75
> 
> But I haven't found a way to use it with the sprite module. I use a class 
> "spider" that ihnerit from sprite.Sprite, in which I should declare two 
> variables that they will use by sprite module: self.image and self.rect. 
> Obviusly I cannot load all the image in the sellf.image variable, I need only
> a 75x75 rectangle referred to a specific frame. So I've thought this way:
> 
> Unfortunately image loses his trasparency and so it hides the display 
> background. What can I do?

this is a fairly common technique. i used it in my "Go, Go, Scarecrow" game
entry for the 48-hour competition. check out the different sprite classes,
like in s_player.py.
http://pygame.org/ludumcontest1/scarecrow-src.zip

first of all, your method to blit to a second surface is very close to
working. as you saw, the only thing you need is to handle the colorkey.
that could be done by disabling the colorkey on the loaded image, and then
setting the colorkey for each new image. like this..

 def __init__(self, ...):
   self.imagedef = pygame.image.load(filename).convert()
   colorkey = self.imagedef.get_colorkey()
   self.imagedef.set_colorkey(None)
   self.image = pygame.Surface((75, 75))
   self.image.set_colorkey(colorkey)
   self.rect = self.image.get_rect()
   self.frame = 0

 def set_frame(self, num):
   src = Rect(num*75, 0, 75, 75)
   self.image.blit(self.imagedef, (0, 0), src)

 def update(self, ...):
    self.frame += 1
    self.set_frame(self.frame)

this will work pretty well, but you are probably better off creating your
80 frames of animation into separate images ahead of time. this way you
don't have to do this internal blitting at game runtime. i usually have a
separate function with a class that preloads all the images and sounds.
this way i can call that at the beginning of the game, and don't need to
load anything while the game is running.

Spider_Anim = []
def preload_images():
   global Spider_Anim
   imagedef = pygame.image.load(filename).convert()
   colorkey = imagedef.get_colorkey()
   imagedef.set_colorkey()
   for x in range(0, imagedef.get_width(), 75):
     img = pygame.Surface((75, 75))
     src = Rect(x, 0, 75, 75)
     img.blit(imagedef, (0, 0), src)
     img.set_colorkey(colorkey)
     Spider_Anim.append(img)

class Spider(pygame.sprite.Sprite):
  def __init__(self, ...):
    self.anim = Spider_Anim
    self.frame = 0
    self.numframes = len(self.anim)
    self.image = self.anim[0]
    self.rect = self.image.get_rect()

  def update(self, ...):
    self.frame = (self.frame + 1) % self.numframes
    self.image = self.anim[self.frame]


one last thing you might want to consider. if it turns out easier to create
 the single images at runtime, you can use pygame's subsurface. this
creates a duplicate of part of another image, but they share the same pixel
data. The advantage of this is that you can create the single frame images
without needing to blit the pixels from one to another. if you preload it
doesn't matter a whole lot, but a preload using the subsurfaces looks like
this.

def preload_images():
   global Spider_Anim
   imagedef = pygame.image.load(filename).convert()
   for x in range(0, imagedef.get_width(), 75):
     src = Rect(x, 0, 75, 75)
     img = imagedef.subsurface(src)
     Spider_Anim.append(img)


anyways, you pretty much had the solution in your post, just a small
colorkey problem. hopefully these bites of code show you where you can take
it next.

____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org