pygame / examples / mask.py

illume 39e462f 
Lenard Lindstrom 4e990d6 








illume 27d57af 
illume 953eedb 


illume 5dd2dc1 
illume 27d57af 

illume 953eedb 












































Lenard Lindstrom 7076791 
illume 953eedb 






























Lenard Lindstrom 4e990d6 












Lenard Lindstrom 7076791 
illume 953eedb 


Lenard Lindstrom 4e990d6 
illume 953eedb 

illume 5dd2dc1 







Lenard Lindstrom 7076791 
illume 5dd2dc1 





Lenard Lindstrom 7076791 
illume 5dd2dc1 
illume 953eedb 

































Lenard Lindstrom 4e990d6 

Lenard Lindstrom 7076791 


Lenard Lindstrom 4e990d6 

illume 953eedb 


#!/usr/bin/env python
"""A pgyame.mask collition detection example

exports main()

This module can also be run as a stand-alone program, excepting
one or more image file names as command line arguments.

"""

import sys, random
import pygame, pygame.image, pygame.surface, pygame.time, pygame.display

def maskFromSurface(surface, threshold = 127):
    #return pygame.mask.from_surface(surface, threshold)

    mask = pygame.mask.Mask(surface.get_size())
    key = surface.get_colorkey()
    if key:
        for y in range(surface.get_height()):
            for x in range(surface.get_width()):
                if surface.get_at((x+0.1,y+0.1)) != key:
                    mask.set_at((x,y),1)
    else:
        for y in range(surface.get_height()):
            for x in range (surface.get_width()):
                if surface.get_at((x,y))[3] > threshold:
                    mask.set_at((x,y),1)
    return mask

def vadd(x,y):
    return [x[0]+y[0],x[1]+y[1]]

def vsub(x,y):
    return [x[0]-y[0],x[1]-y[1]]

def vdot(x,y):
    return x[0]*y[0]+x[1]*y[1]

class Sprite:
    def __init__(self, surface, mask = None):
        self.surface = surface
        if mask:
            self.mask = mask
        else:
            self.mask = maskFromSurface(self.surface)
        self.setPos([0,0])
        self.setVelocity([0,0])
        
    def setPos(self,pos):
        self.pos = [pos[0],pos[1]]
    def setVelocity(self,vel):
        self.vel = [vel[0],vel[1]]
    def move(self,dr):
        self.pos = vadd(self.pos,dr)
    def kick(self,impulse):
        self.vel[0] += impulse[0]
        self.vel[1] += impulse[1]

    def collide(self,s):
        """Test if the sprites are colliding and
        resolve the collision in this case."""
        offset = [int(x) for x in vsub(s.pos,self.pos)]
        overlap = self.mask.overlap_area(s.mask,offset)
        if overlap == 0:
            return
        """Calculate collision normal"""
        nx = (self.mask.overlap_area(s.mask,(offset[0]+1,offset[1])) -
              self.mask.overlap_area(s.mask,(offset[0]-1,offset[1])))
        ny = (self.mask.overlap_area(s.mask,(offset[0],offset[1]+1)) -
              self.mask.overlap_area(s.mask,(offset[0],offset[1]-1)))
        if nx == 0 and ny == 0:
            """One sprite is inside another"""
            return
        n = [nx,ny]
        dv = vsub(s.vel,self.vel)
        J = vdot(dv,n)/(2*vdot(n,n))
        if J > 0:
            """Can scale up to 2*J here to get bouncy collisions"""
            J *= 1.9
            self.kick([nx*J,ny*J])
            s.kick([-J*nx,-J*ny])
        return
        """Separate the sprites"""
        c1 = -overlap/vdot(n,n)
        c2 = -c1/2
        self.move([c2*nx,c2*ny])
        s.move([(c1+c2)*nx,(c1+c2)*ny])
        
    def update(self,dt):
        self.pos[0] += dt*self.vel[0]
        self.pos[1] += dt*self.vel[1]


def main(*args):
    """Display multiple images bounce off each other using collition detection

    Positional arguments:
      one or more image file names.

    This pygame.masks demo will display multiple moving sprites bouncing
    off each other. More than one sprite image can be provided.

    """
    
    if len(args) == 0:
        raise ValueError("Require at least one image file name: non given")
    print ('Press any key to quit')
    screen = pygame.display.set_mode((640,480))
    images = []
    masks = []
    for impath in args:
        images.append(pygame.image.load(impath).convert_alpha())
        masks.append(maskFromSurface(images[-1]))

    numtimes = 10
    import time
    t1 = time.time()
    for x in range(numtimes):
        m = maskFromSurface(images[-1])
    t2 = time.time()

    print ("python maskFromSurface :%s" % (t2-t1))

    t1 = time.time()
    for x in range(numtimes):
        m = pygame.mask.from_surface(images[-1])
    t2 = time.time()

    print ("C pygame.mask.from_surface :%s" % (t2-t1))

    sprites = []
    for i in range(20):
        j = i % len(images)
        s = Sprite(images[j],masks[j])
        s.setPos((random.uniform(0,screen.get_width()),
                  random.uniform(0,screen.get_height())))
        s.setVelocity((random.uniform(-5,5),random.uniform(-5,5)))
        sprites.append(s)
    pygame.time.set_timer(pygame.USEREVENT,33)
    while 1:
        event = pygame.event.wait()
        if event.type == pygame.QUIT:
            return
        elif event.type == pygame.USEREVENT:
            """Do both mechanics and screen update"""
            screen.fill((240,220,100))
            for i in range(len(sprites)):
                for j in range(i+1,len(sprites)):
                    sprites[i].collide(sprites[j])
            for s in sprites:
                s.update(1)
                if s.pos[0] < -s.surface.get_width()-3:
                    s.pos[0] = screen.get_width()
                elif s.pos[0] > screen.get_width()+3:
                    s.pos[0] = -s.surface.get_width()
                if s.pos[1] < -s.surface.get_height()-3:
                    s.pos[1] = screen.get_height()
                elif s.pos[1] > screen.get_height()+3:
                    s.pos[1] = -s.surface.get_height()
                screen.blit(s.surface,s.pos)
            pygame.display.update()
        elif event.type == pygame.KEYDOWN:
            return

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print ('Usage: mask.py <IMAGE> [<IMAGE> ...]')
        print ('Let many copies of IMAGE(s) bounce against each other')
        print ('Press any key to quit')
    else:
        main(*sys.argv[1:])



        
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.