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