class MissileDefenceGame(object):
    
    if eyetrackerSupport:
        d = Dispatcher()
    
    def reset(self):
        self.background = background.StarryBackground(self.resolution)                       
        self.physics = Physics(self)        
        self.cannon = DefenceCannon(centre=(self.resolution[0] / 2,
                                            self.resolution[1] - 99),
                                    game=self)
        self.buildings = Buildings(generate_city(self.resolution),
                                   self.resolution)
        self.firing = False
        self.fixation_firing = False
        self.fire_cycle = 0
        self.shield_dome = ShieldDome(self.resolution)
        self.shield_dome.health = 2
        self.missile_threshold = 0.01
        self.projectiles = []
        self.initial_buildings_sum = self.get_buildings_sum()
        self.buildings_sum = self.initial_buildings_sum
        self.score = 0
        
        self.fix = None
        self.samp = 0
        
    def __init__(self, args):
        
        self.args = args
        
        self.buildings_colour = (0,0,10)   # blue-black
        self.auto_mode = False
        
        self.projectiles = [] 
        self.tick_count = 0
                
        pygame.init()
        pygame.surfarray.use_arraytype("numpy")        
        
#        self.score_font = pygame.font.Font(pygame.font.get_default_font(), 20)
        self.score_font = pygame.font.Font(pygame.font.match_font("Monospace", True), 20)
        
        self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        surf = self.screen.get_rect()
        self.resolution = (surf.width, surf.height)
        
        self.buildings_surface = pygame.Surface(self.resolution, 0, 8)
        self.buildings_surface.set_palette(((0,0,0), self.buildings_colour))
        self.buildings_surface.set_colorkey(0, pygame.RLEACCEL)
        
        self.reset()
        
        if self.args.eyetracker:
            self.client = iViewXClient( self.args.eyetracker, 4444 )
            self.client.addDispatcher( self.d )
            self.fp = VelocityFP()
            self.calibrator = Calibrator( self.client, self.screen, reactor = reactor )
        
    def generate_missile(self):
        p = projectiles.Missile(position=(uniform(-500, self.resolution[0] + 500), -50),
                                velocity=(uniform(-3, 3), 
                                          uniform(2, 7)))
        
        count = 0
        while p.position[1] < -20 and count < 100:
            p.apply_physics(self.physics, self.buildings)
            count += 1
            
        return p

    def handle_events(self):
        force_fire = False
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            elif event.type == pygame.KEYDOWN and event.key == ord("q"):
                self.quit()
            elif event.type == pygame.KEYDOWN and event.key == ord("s"): # screenshot
                pygame.image.save(self.screen, "screenshot.png")
            elif event.type == pygame.KEYDOWN and event.key == ord("a"): # auto mode
                self.auto_mode = not self.auto_mode
            elif event.type == pygame.KEYDOWN and event.key == ord("r"): # reset
                self.reset()
            elif event.type == pygame.KEYDOWN and event.key == ord("d"):
                self.shield_dome.health += 20
            elif event.type == pygame.MOUSEBUTTONDOWN:
                force_fire  = True # fire event if there was a mouse up too
                self.fire_cycle = 0
                self.firing = True
            elif event.type == pygame.MOUSEBUTTONUP:
                self.firing = False
       
        stuff_nearby = any(
            size_squared(array(p.position) - array(self.cannon.centre)) < p.radius * p.radius  
            for p in self.projectiles)
            
        if not self.auto_mode:
            self.cannon.target = array(pygame.mouse.get_pos())

        if not stuff_nearby:
            if self.auto_mode and self.cannon.can_fire():

                valid_targets = [p for p in self.projectiles if
                                 p.position[0] > 0 and p.position[1] > 0 and
                                 p.position[0] < self.resolution[0] and
                                 p.position[1] < self.resolution[1] - 300 and
                                 p.velocity[1] > 0 and not p.exploding]
                if len(valid_targets) > 0:
                    target = random.choice(valid_targets)
                    target_pos = array(target.position) + array(target.velocity) * 4
                    self.cannon.fire(target_pos)
                    self.cannon.target = target_pos
                    
            elif self.firing or force_fire:            
                self.cannon.fire(pygame.mouse.get_pos()) 
                
    def get_buildings_sum(self):
        # restart if most of the buildings are destroyed and no explosions in progress
        sum = 0
        for y in range(self.resolution[1] - 100, self.resolution[1]):
            sum += numpy.ma.sum(self.buildings.pixeldata[y])
        return sum
        
    def draw(self, intro=False):
        self.background.draw(self.screen)
        pygame.surfarray.blit_array(self.buildings_surface,
                                    self.buildings.pixeldata)
        
        self.screen.blit(self.buildings_surface, (0,0))

        self.shield_dome.draw(self.screen)
                
        for p in self.projectiles:
            p.draw(self.screen)
            
        self.cannon.draw(self.screen)
        
        # draw score
        score_surf = self.score_font.render(format(self.score, "08"), True, (255,255,255))
        self.screen.blit(score_surf, (30, 30))
        pygame.display.flip()
    
    
    
    def apply_physics(self):
        self.physics.update_location_cache()
        
        projectiles_keep = []  
        # process projectiles
        for p in self.projectiles:
            p.apply_physics(self.physics, self.buildings)
            
            # keep any projectiles that aren't destroyed/off-screen
            if not p.is_garbage(self.resolution):
               projectiles_keep.append(p)               
        self.projectiles = projectiles_keep        
        self.buildings.apply_physics()   
        self.cannon.apply_physics()
        
    def refresh(self):
        self.handle_events()
                        
        self.tick_count += 1

        if self.tick_count % 100 == 0:
            self.background.darken()        
            
        if self.tick_count % 30 == 0:
            self.buildings_sum   = self.get_buildings_sum()
            if float(self.buildings_sum) / self.initial_buildings_sum < 0.2:
                self.reset()
         
            self.score += 100
                       
        # randomly add more projectiles
        self.missile_threshold += 0.0001
        
        m = self.missile_threshold
        while m > 0:
            m -= random.random() 
            if m > 0:
                self.projectiles.append(self.generate_missile())
        
        self.apply_physics()
        
        self.draw()
        
    def start( self, lc, results):
        self.lc = LoopingCall( self.refresh )
        cleanupD = self.lc.start( 1.0 / 30 )
        cleanupD.addCallbacks( self.quit )

    def run( self ):
        if self.args.eyetracker:
            reactor.listenUDP( 5555, self.client )
            self.calibrator.start( self.start )
        else:
            self.start( None )
        reactor.run()
                
    def quit( self, lc=None ):
        reactor.stop()
            
    if eyetrackerSupport:
        @d.listen( 'ET_SPL' )
        def iViewXEvent( self, inSender, inEvent, inResponse ):
            t = int( inResponse[0] )
            x = float( inResponse[2] )
            y = float( inResponse[4] )
            ex = numpy.mean( ( float( inResponse[10] ), float( inResponse[11] ) ) )
            ey = numpy.mean( ( float( inResponse[12] ), float( inResponse[13] ) ) )
            ez = numpy.mean( ( float( inResponse[14] ), float( inResponse[15] ) ) )
            dia = int( inResponse[6] ) > 0 and int( inResponse[7] ) > 0 and int( inResponse[8] ) > 0 and int( inResponse[9] ) > 0
            self.fix, self.samp = self.fp.processData( t, dia, x, y, ex, ey, ez )
            
            if self.fix:
                if not self.fixation_firing and self.samp > 100:
                    self.fixation_firing = True
                    self.cannon.fire(self.fix)
            else:
                self.fixation_firing = False
class MissileDefenceGame(object):

    if eyetrackerSupport:
        d = Dispatcher()

    def reset(self):
        self.background = background.StarryBackground(self.resolution)
        self.physics = Physics(self)
        self.cannon = DefenceCannon(centre=(self.resolution[0] / 2,
                                            self.resolution[1] - 99),
                                    game=self)
        self.buildings = Buildings(generate_city(self.resolution),
                                   self.resolution)
        self.firing = False
        self.fixation_firing = False
        self.fire_cycle = 0
        self.shield_dome = ShieldDome(self.resolution)
        self.shield_dome.health = 2
        self.missile_threshold = 0.01
        self.projectiles = []
        self.initial_buildings_sum = self.get_buildings_sum()
        self.buildings_sum = self.initial_buildings_sum
        self.score = 0

        self.fix = None
        self.samp = 0

    def __init__(self, args):

        self.args = args

        self.buildings_colour = (0, 0, 10)  # blue-black
        self.auto_mode = False

        self.projectiles = []
        self.tick_count = 0

        pygame.init()
        pygame.surfarray.use_arraytype("numpy")

        #        self.score_font = pygame.font.Font(pygame.font.get_default_font(), 20)
        self.score_font = pygame.font.Font(
            pygame.font.match_font("Monospace", True), 20)

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        surf = self.screen.get_rect()
        self.resolution = (surf.width, surf.height)

        self.buildings_surface = pygame.Surface(self.resolution, 0, 8)
        self.buildings_surface.set_palette(((0, 0, 0), self.buildings_colour))
        self.buildings_surface.set_colorkey(0, pygame.RLEACCEL)

        self.reset()

        if self.args.eyetracker:
            self.client = iViewXClient(self.args.eyetracker, 4444)
            self.client.addDispatcher(self.d)
            self.fp = VelocityFP()
            self.calibrator = Calibrator(self.client,
                                         self.screen,
                                         reactor=reactor)

    def generate_missile(self):
        p = projectiles.Missile(position=(uniform(-500,
                                                  self.resolution[0] + 500),
                                          -50),
                                velocity=(uniform(-3, 3), uniform(2, 7)))

        count = 0
        while p.position[1] < -20 and count < 100:
            p.apply_physics(self.physics, self.buildings)
            count += 1

        return p

    def handle_events(self):
        force_fire = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            elif event.type == pygame.KEYDOWN and event.key == ord("q"):
                self.quit()
            elif event.type == pygame.KEYDOWN and event.key == ord(
                    "s"):  # screenshot
                pygame.image.save(self.screen, "screenshot.png")
            elif event.type == pygame.KEYDOWN and event.key == ord(
                    "a"):  # auto mode
                self.auto_mode = not self.auto_mode
            elif event.type == pygame.KEYDOWN and event.key == ord(
                    "r"):  # reset
                self.reset()
            elif event.type == pygame.KEYDOWN and event.key == ord("d"):
                self.shield_dome.health += 20
            elif event.type == pygame.MOUSEBUTTONDOWN:
                force_fire = True  # fire event if there was a mouse up too
                self.fire_cycle = 0
                self.firing = True
            elif event.type == pygame.MOUSEBUTTONUP:
                self.firing = False

        stuff_nearby = any(
            size_squared(array(p.position) -
                         array(self.cannon.centre)) < p.radius * p.radius
            for p in self.projectiles)

        if not self.auto_mode:
            self.cannon.target = array(pygame.mouse.get_pos())

        if not stuff_nearby:
            if self.auto_mode and self.cannon.can_fire():

                valid_targets = [
                    p for p in self.projectiles
                    if p.position[0] > 0 and p.position[1] > 0
                    and p.position[0] < self.resolution[0]
                    and p.position[1] < self.resolution[1] -
                    300 and p.velocity[1] > 0 and not p.exploding
                ]
                if len(valid_targets) > 0:
                    target = random.choice(valid_targets)
                    target_pos = array(
                        target.position) + array(target.velocity) * 4
                    self.cannon.fire(target_pos)
                    self.cannon.target = target_pos

            elif self.firing or force_fire:
                self.cannon.fire(pygame.mouse.get_pos())

    def get_buildings_sum(self):
        # restart if most of the buildings are destroyed and no explosions in progress
        sum = 0
        for y in range(self.resolution[1] - 100, self.resolution[1]):
            sum += numpy.ma.sum(self.buildings.pixeldata[y])
        return sum

    def draw(self, intro=False):
        self.background.draw(self.screen)
        pygame.surfarray.blit_array(self.buildings_surface,
                                    self.buildings.pixeldata)

        self.screen.blit(self.buildings_surface, (0, 0))

        self.shield_dome.draw(self.screen)

        for p in self.projectiles:
            p.draw(self.screen)

        self.cannon.draw(self.screen)

        # draw score
        score_surf = self.score_font.render(format(self.score, "08"), True,
                                            (255, 255, 255))
        self.screen.blit(score_surf, (30, 30))
        pygame.display.flip()

    def apply_physics(self):
        self.physics.update_location_cache()

        projectiles_keep = []
        # process projectiles
        for p in self.projectiles:
            p.apply_physics(self.physics, self.buildings)

            # keep any projectiles that aren't destroyed/off-screen
            if not p.is_garbage(self.resolution):
                projectiles_keep.append(p)
        self.projectiles = projectiles_keep
        self.buildings.apply_physics()
        self.cannon.apply_physics()

    def refresh(self):
        self.handle_events()

        self.tick_count += 1

        if self.tick_count % 100 == 0:
            self.background.darken()

        if self.tick_count % 30 == 0:
            self.buildings_sum = self.get_buildings_sum()
            if float(self.buildings_sum) / self.initial_buildings_sum < 0.2:
                self.reset()

            self.score += 100

        # randomly add more projectiles
        self.missile_threshold += 0.0001

        m = self.missile_threshold
        while m > 0:
            m -= random.random()
            if m > 0:
                self.projectiles.append(self.generate_missile())

        self.apply_physics()

        self.draw()

    def start(self, lc, results):
        self.lc = LoopingCall(self.refresh)
        cleanupD = self.lc.start(1.0 / 30)
        cleanupD.addCallbacks(self.quit)

    def run(self):
        if self.args.eyetracker:
            reactor.listenUDP(5555, self.client)
            self.calibrator.start(self.start)
        else:
            self.start(None)
        reactor.run()

    def quit(self, lc=None):
        reactor.stop()

    if eyetrackerSupport:

        @d.listen('ET_SPL')
        def iViewXEvent(self, inSender, inEvent, inResponse):
            t = int(inResponse[0])
            x = float(inResponse[2])
            y = float(inResponse[4])
            ex = numpy.mean((float(inResponse[10]), float(inResponse[11])))
            ey = numpy.mean((float(inResponse[12]), float(inResponse[13])))
            ez = numpy.mean((float(inResponse[14]), float(inResponse[15])))
            dia = int(inResponse[6]) > 0 and int(inResponse[7]) > 0 and int(
                inResponse[8]) > 0 and int(inResponse[9]) > 0
            self.fix, self.samp = self.fp.processData(t, dia, x, y, ex, ey, ez)

            if self.fix:
                if not self.fixation_firing and self.samp > 100:
                    self.fixation_firing = True
                    self.cannon.fire(self.fix)
            else:
                self.fixation_firing = False
示例#3
0
class MissileDefenceGame(object):
    def reset(self):
        self.background = background.StarryBackground(self.resolution)                       
        self.physics = Physics(self)        
        self.cannon = DefenceCannon(centre=(self.resolution[0] / 2,
                                            self.resolution[1] - 99),
                                    game=self)
        self.buildings = Buildings(generate_city(self.resolution),
                                   self.resolution)
        self.firing = False
        self.fire_cycle = 0
        self.shield_dome = ShieldDome(self.resolution)
        self.shield_dome.health = 2
        self.missile_threshold = 0.01
        self.projectiles = []
        self.initial_buildings_sum = self.get_buildings_sum()
        self.buildings_sum = self.initial_buildings_sum
        self.score = 0
        
    def __init__(self):
        self.buildings_colour = (0,0,10)   # blue-black
        self.resolution = (640, 480)
        self.auto_mode = False
                
        pygame.init()
        pygame.surfarray.use_arraytype("numpy")        
        
#        self.score_font = pygame.font.Font(pygame.font.get_default_font(), 20)
        self.score_font = pygame.font.Font(pygame.font.match_font("Monospace", True), 20)
        self.reset()
        
        self.screen = pygame.display.set_mode(self.resolution)
        pygame.display.set_caption("Missile defence")

#                                              pygame.FULLSCREEN)
        
        self.buildings_surface = pygame.Surface(self.resolution, 0, 8)
        self.buildings_surface.set_palette(((0,0,0), self.buildings_colour))
        self.buildings_surface.set_colorkey(0, pygame.RLEACCEL)
        
    def generate_missile(self):
        p = projectiles.Missile(position=(uniform(-500, self.resolution[0] + 500), -50),
                                velocity=(uniform(-3, 3), 
                                          uniform(2, 7)))
        
        count = 0
        while p.position[1] < -20 and count < 100:
            p.apply_physics(self.physics, self.buildings)
            count += 1
            
        return p

    def handle_events(self):
        force_fire = False
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.done = True
            elif event.type == pygame.KEYDOWN and event.key == ord("q"):
                self.done = True
            elif event.type == pygame.KEYDOWN and event.key == ord("s"): # screenshot
                pygame.image.save(self.screen, "screenshot.png")
            elif event.type == pygame.KEYDOWN and event.key == ord("a"): # auto mode
                self.auto_mode = not self.auto_mode
            elif event.type == pygame.KEYDOWN and event.key == ord("r"): # reset
                self.reset()
            elif event.type == pygame.KEYDOWN and event.key == ord("d"):
                self.shield_dome.health += 20
            elif event.type == pygame.MOUSEBUTTONDOWN:
                force_fire  = True # fire event if there was a mouse up too
                self.fire_cycle = 0
                self.firing = True
            elif event.type == pygame.MOUSEBUTTONUP:
                self.firing = False
       
        stuff_nearby = any(
            size_squared(array(p.position) - array(self.cannon.centre)) < p.radius * p.radius  
            for p in self.projectiles)
            
        if not self.auto_mode:
            self.cannon.target = array(pygame.mouse.get_pos())

        if not stuff_nearby:
            if self.auto_mode and self.cannon.can_fire():

                valid_targets = [p for p in self.projectiles if
                                 p.position[0] > 0 and p.position[1] > 0 and
                                 p.position[0] < self.resolution[0] and
                                 p.position[1] < self.resolution[1] - 300 and
                                 p.velocity[1] > 0 and not p.exploding]
                if len(valid_targets) > 0:
                    target = random.choice(valid_targets)
                    target_pos = array(target.position) + array(target.velocity) * 4
                    self.cannon.fire(target_pos)
                    self.cannon.target = target_pos
                    
            elif self.firing or force_fire:            
                self.cannon.fire(pygame.mouse.get_pos()) 
                
    def get_buildings_sum(self):
        # restart if most of the buildings are destroyed and no explosions in progress
        sum = 0
        for y in range(self.resolution[1] - 100, self.resolution[1]):
            sum += numpy.ma.sum(self.buildings.pixeldata[y])
        return sum
        
    def draw(self, intro=False):
        self.background.draw(self.screen)
        pygame.surfarray.blit_array(self.buildings_surface,
                                    self.buildings.pixeldata)
        
        self.screen.blit(self.buildings_surface, (0,0))

        self.shield_dome.draw(self.screen)
                
        for p in self.projectiles:
            p.draw(self.screen)
            
        self.cannon.draw(self.screen)
        
        # draw score
        score_surf = self.score_font.render(format(self.score, "08"), True, (255,255,255))
        self.screen.blit(score_surf, (30, 30))
        pygame.display.flip()
    
    
    
    def apply_physics(self):
        self.physics.update_location_cache()
        
        projectiles_keep = []  
        # process projectiles
        for p in self.projectiles:
            p.apply_physics(self.physics, self.buildings)
            
            # keep any projectiles that aren't destroyed/off-screen
            if not p.is_garbage(self.resolution):
               projectiles_keep.append(p)               
        self.projectiles = projectiles_keep        
        self.buildings.apply_physics()   
        self.cannon.apply_physics()
        
                
    def run(self):                
        clock = pygame.time.Clock()        

        self.projectiles = [] 
        tick_count = 0
        self.done  = False

        # Introduction
        
        #while tick_count < 30
        #    clock.tick(30)
        #    
        #    tick_count += 1
        #    self.apply_physics()
        #     self.draw()
                    
        while not self.done:
            clock.tick(30)
            self.handle_events()
                        
            tick_count += 1

            if tick_count % 100 == 0:
                self.background.darken()        
                
            if tick_count % 30 == 0:
                self.buildings_sum   = self.get_buildings_sum()
                if float(self.buildings_sum) / self.initial_buildings_sum < 0.2:
                    self.reset()
             
                self.score += 100
                           
            # randomly add more projectiles
            self.missile_threshold += 0.0001
            
            m = self.missile_threshold
            while m > 0:
                m -= random.random() 
                if m > 0:
                    self.projectiles.append(self.generate_missile())
            
            self.apply_physics()
            
            self.draw()
        
        pygame.quit()