def __init__(self): self.r = Room(options.xmin,options.xmax,options.ymin,options.ymax) self.fs = fluidsynth.Synth() self.fs.start(driver="coreaudio") self.sfid = self.fs.sfload("./FluidR3_GM.sf2") self.notes = [69, 81, 74, 79, 57, 62, 67, 93, 86, 91] self.r.partition(options.partition,self.notes) try: self.pt = PanTilt() # set to max speed self.pt.set_max_speed() except: print "Couldn't initialize pan-tilt unit" self.pt = None pass if simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: try: self.vp = ViconProxy() except: print "Couldn't initialize Vicon Proxy" self.vp = 0 pass self.m = Mapper(options.netfile) self.graphics = Graphics(self.r) self.graphics.DrawBall()
def __init__(self,options): self.options = options self.game_time = self.options.game_time self.last_updated = time.time() # self.pos is a numobjects x 2 numpy array # which represents the x,y position of the objects # self.pos = np.zeros((numobjects,2)) self.postime = 0.0 self.negtime = 0.0 self.gameovertext=False #whether we have written GAME OVER on screen if self.options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" self.graphics = Graphics(self.options) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() ## self.balls = [] ## for o in self.vicon_objects: ## self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) self.sounds = Sounds()
def __init__(self,options): print "init game" self.options = options # Related to writing game state self.clock = pygame.time.Clock() # currently this clock is only used for game state writes self.accumulator = 0 # used for game state writes self.write_game_state(0,0,0,0,0,0) # dummy game state means we are waiting # Global scores self.pos_global=0 self.neg_global=0 self.game_time = self.options.game_time self.last_updated = time.time() # self.pos is a numobjects x 2 numpy array # which represents the x,y position of the objects # self.pos = np.zeros((numobjects,2)) self.postime = 0.0 self.negtime = 0.0 self.bias = 0.0 # positive means x side has an advantage self.minarea=100 self.maxarea=5000 self.gameovertext=False #whether we have written GAME OVER on screen if self.options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" #self.simulation_mode = True # Currently our graphics implementation (matplotlib + pygame) is a bit hacky # Matplotlib is set to have equal axes (in terms of units) # Therefore the aspect ratio of the room must equal the aspect ratio of the fixed # Screen resolution for matplotlib and pygame to line up # So here we make sure that aspect ratios are the same aspect = float(self.options.height)/self.options.width print "DEBUG: screen aspect %f" % aspect # keep x, but change y roomw = (self.options.xmax-self.options.xmin) roomh = (self.options.ymax-self.options.ymin) targetroomh = roomw*aspect print "DEBUG: room w: %f, target room h: %f" % (roomw,targetroomh) roomhcenter = self.options.ymin+roomh/2.0 # update room y to match target aspect ratio self.options.ymin = roomhcenter - targetroomh/2.0 self.options.ymax = roomhcenter + targetroomh/2.0 print "DEBUG: new ymin: %f, new ymax: %f" % (self.options.ymin,self.options.ymax) self.graphics = Graphics(self.options) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() ## self.balls = [] ## for o in self.vicon_objects: ## self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) self.sounds = Sounds()
class Game: """Handles timing, score, game objects and gameplay.""" def __init__(self,options): print "init game" self.options = options # Related to writing game state self.clock = pygame.time.Clock() # currently this clock is only used for game state writes self.accumulator = 0 # used for game state writes self.write_game_state(0,0,0,0,0,0) # dummy game state means we are waiting # Global scores self.pos_global=0 self.neg_global=0 self.game_time = self.options.game_time self.last_updated = time.time() # self.pos is a numobjects x 2 numpy array # which represents the x,y position of the objects # self.pos = np.zeros((numobjects,2)) self.postime = 0.0 self.negtime = 0.0 self.bias = 0.0 # positive means x side has an advantage self.minarea=100 self.maxarea=5000 self.gameovertext=False #whether we have written GAME OVER on screen if self.options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" #self.simulation_mode = True # Currently our graphics implementation (matplotlib + pygame) is a bit hacky # Matplotlib is set to have equal axes (in terms of units) # Therefore the aspect ratio of the room must equal the aspect ratio of the fixed # Screen resolution for matplotlib and pygame to line up # So here we make sure that aspect ratios are the same aspect = float(self.options.height)/self.options.width print "DEBUG: screen aspect %f" % aspect # keep x, but change y roomw = (self.options.xmax-self.options.xmin) roomh = (self.options.ymax-self.options.ymin) targetroomh = roomw*aspect print "DEBUG: room w: %f, target room h: %f" % (roomw,targetroomh) roomhcenter = self.options.ymin+roomh/2.0 # update room y to match target aspect ratio self.options.ymin = roomhcenter - targetroomh/2.0 self.options.ymax = roomhcenter + targetroomh/2.0 print "DEBUG: new ymin: %f, new ymax: %f" % (self.options.ymin,self.options.ymax) self.graphics = Graphics(self.options) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() ## self.balls = [] ## for o in self.vicon_objects: ## self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) self.sounds = Sounds() # for user keyboard input # cv.NamedWindow( "Status", 1) def start_clock(self): self.clock_started = time.time() self.last_updated = self.clock_started def time_elapsed(self): return time.time()-self.clock_started def time_left(self): return self.game_time - self.time_elapsed() def update(self): self.last_updated = time.time() def sincelastupdate(self): return time.time()-self.last_updated def isgameover(self): return self.time_elapsed() >= self.game_time def gameover(self,posscore,negscore): self.graphics.erase_clock() print "Game is over, here are some stats:" # print "postime: %6.2f" % (postime/len(vicon_objects)) # print "negtime: %6.2f" % (negtime/len(vicon_objects)) if self.postime+self.negtime > 0: print "postime: %6.2f" % posscore # (100*postime/(postime+negtime)) print "negtime: %6.2f" % negscore # (100*negtime/(postime+negtime)) else: print "No time recorded" if negscore>posscore: print "Negative side wins!" self.neg_global+=1 elif posscore>negscore: print "Positive side wins!" self.pos_global+=1 else: print "Tie" self.pos_global+=1 self.neg_global+=1 self.graphics.gameover(posscore,negscore,(self.pos_global,self.neg_global)) self.gameovertext=True # self.sounds.play("gameover") self.sounds.gameover_sound.play() print "Press 'g' to play again" def getready(self): # self.sounds.play("start") self.accumulator = 0 # used for game state writes self.graphics.instructions() self.sounds.start_sound.play() self.graphics.countdown() def handle_events(self): global width_factor, height_factor, floor_offset # Event handling through pygame # Currently only two keystrokes: ESC and 'g' for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == KEYUP) or (event.type == KEYDOWN): print event if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_a: print "f" if self.graphics.fullscreen: self.graphics.fullscreen=0 window = pygame.display.set_mode(self.graphics.resolution) else: self.graphics.fullscreen=1 window = pygame.display.set_mode(self.graphics.resolution, pygame.FULLSCREEN) if hasattr(event, 'key') and event.type == pygame.KEYDOWN: # For some reason pygame.K_PLUS doesn't work if event.key == 61: self.bias += 0.1 print "bias %f" % self.bias elif event.key == pygame.K_MINUS: self.bias -= 0.1 print "bias %f" % self.bias elif event.key == pygame.K_0: self.bias = 0 print "bias reset" if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_1: print "timing 10" self.game_time = 10.0 elif event.key == pygame.K_3: print "timing 30" self.game_time = 30.0 elif event.key == pygame.K_6: print "timing 60" self.game_time = 60.0 elif event.key == pygame.K_9: print "timing 90" self.game_time = 90.0 print event, dir(event) if (event.type == KEYDOWN and event.key == K_w and event.mod == 0 ): width_factor *= 0.98 if (event.type == KEYDOWN and event.key == K_w and event.mod == 1 ): width_factor *= 1.02 if (event.type == KEYDOWN and event.key == K_h and event.mod == 0 ): height_factor *= 0.98 if (event.type == KEYDOWN and event.key == K_h and event.mod == 1 ): height_factor *= 1.02 if (event.type == KEYDOWN and event.key == K_f and event.mod == 0 ): floor_offset -= 0.01*height_factor if (event.type == KEYDOWN and event.key == K_f and event.mod == 1 ): floor_offset += 0.01*height_factor if (event.type == KEYDOWN and event.key == K_ESCAPE): if self.simulation_mode: self.f.close() else: self.vp.close() done = True # Delete game state file if os.path.isfile(options.game_state_file): print "Removing game state" os.remove(options.game_state_file) else: print "No game state found" if (self.mode==WAITING and event.type == KEYUP and event.key == K_g): self.mode=GAMEON print "Game ON" self.graphics.set_caption("Possession") if self.gameovertext: self.graphics.remove_gameover_text() self.gameovertext=False self.getready() self.postime = 0.0 self.negtime = 0.0 self.graphics.draw_clock(360) self.start_clock() def write_game_state(self,*state): """Writes the game state to a text file at a specific period. Name of file and period are set by command-line. """ #print "Considering game state write" timeChange = self.clock.tick() self.accumulator += timeChange #print "Accumulator: %f" % self.accumulator if self.accumulator > options.game_state_period: self.accumulator = self.accumulator - options.game_state_period #print "Writing game state" f = open(options.game_state_file, 'w') for s in state[:-1]: f.write('%f,' % s) f.write('%f\n' % state[-1]) f.close() def run(self): """ Main game loop """ global side_count, last_side_count self.mode = WAITING self.graphics.set_caption("Possession: Press 'g' to start") print "Press 'g' to start play" #mode = GAMEON # debug #reset_clock() done = False while not done: if self.simulation_mode: # read from file obj = get_now_file(self.f,debug=self.options.debug) else: # read from vicon_proxy obj = get_now(self.vp) ## for b in self.balls: ## b.set_pos(obj) markers = get_vicon_raw(obj) # if we couldn't get a proper object (i.e. tracking mode) # then markers will be none # just wait for data but still handle events if markers is None: # maybe not raw mode, keep trying #print "Still waiting for data..." self.handle_events() continue # time.sleep(1.0/60) # If there are no markers, then markers will be an empty list # we cannot convert to array # So we create a single dummy neutral point far, far away if len(markers)>0: if options.swap: # use x and z #gw #self.pos = np.array(markers)[:,0:3:2] # extracts x,z #self.area = np.array(markers)[:,1] # extracts y (stores area) self.pos = np.array(markers)[:,0:3:1] # extracts x,z print "pos->",self.pos #transform the points new_coords = [] for pos in self.pos: coord = [ pos[0]*width_factor, pos[1]*height_factor + floor_offset, pos[2] ] new_coords.append( coord ) for i in range( len(self.pos) ): self.pos[i][0] = new_coords[i][0] self.pos[i][1] = new_coords[i][1] self.pos[i][2] = new_coords[i][2] self.area = np.array(markers)[:,2] # extracts y (stores area) #gw #self.area = np.random.uniform(low=self.minarea,high=self.maxarea,size=len(self.pos)) # DEBUG # rescale area to be on 10,300 # note use of np.maximum (not np.max) to do element-wise maximum to threshold self.area=100+(np.maximum(0,self.area-self.minarea))*1.0/(self.maxarea-self.minarea)*(300-100) # don't let final area go above self.maxarea self.area=np.minimum(self.maxarea,self.area) #print self.area # DEBUG else: self.pos = np.array(markers)[:,0:2] # only take x,y else: print "NO MARKERS" if options.axis==0: self.pos = np.array([[0,1000000]]) else: self.pos = np.array([[1000000,0]]) self.area = np.array([0]) ## c=0 ## for b in self.balls: ## pos = b.get_pos() ## # update position for display ## self.pos[c,:] = b.pos[0:2] # only take x,y ## c+=1 # regardless of whether we're playing game # update ball position on display #self.graphics.update_ballpos(self.pos) if options.swap: self.graphics.draw_markers(self.pos,self.area) else: self.graphics.draw_markers(self.pos) # accumulate time on each side if self.mode==GAMEON: s = self.sincelastupdate() # time since last update for m in markers: if m[self.options.axis]>(FUDGE + 0): self.postime+=s elif m[self.options.axis]<(FUDGE + 0): self.negtime+=s #gw #for m in markers: # pos=b.get_pos() # changed=b.changed(self.options.axis) # did it change sides? # ## if pos[self.options.axis] > 0: ## if self.options.debug: ## print "%s + " % b.objectname ## self.postime += s ## elif pos[self.options.axis] < 0: ## if self.options.debug: ## print "%s - " % b.objectname ## self.negtime += s # # play sounds if ball changed sides # if changed==1: # # self.sounds.play("swoosh1") # self.sounds.swoosh1_sound.play() # elif changed==2: # # self.sounds.play("swoosh2") # self.sounds.swoosh2_sound.play() # if ( side_count != last_side_count ): self.sounds.swoosh2_sound.play() last_side_count = side_count self.update() #update clock # update text if game is on if self.mode==GAMEON: timeleft = self.time_left() #posscore=100-round(100*self.postime/(self.postime+self.negtime+1e-9)) #negscore=100-round(100*self.negtime/(self.postime+self.negtime+1e-9)) #posscore=100-round(100*self.postime/(self.postime+self.negtime+1e-9)) #negscore=100-round(100*self.negtime/(self.postime+self.negtime+1e-9)) # sigmoid approach # p(pos wins) = sigmoid( negfrac-posfrac+bias) posfrac = self.postime/(self.postime+self.negtime+1e-9) negfrac = self.negtime/(self.postime+self.negtime+1e-9) posscore = 1/(1+np.exp(-(negfrac-posfrac+self.bias))) # on 0,1 negscore = 100*(1-posscore) posscore = 100*posscore # I don't see a set_radius command # So I just remove the patch collection, recreate wedge, collection # and add collection again self.graphics.erase_clock() # clock takes a single argument - hand position in degrees self.graphics.draw_clock(360*timeleft/self.game_time) self.graphics.update_scores(posscore,negscore) # regardless of whether we are playing or not, update plot self.graphics.redraw() if self.mode==GAMEON and g.isgameover(): self.mode=GAMEDONE self.gameover(posscore,negscore) # do one last write self.write_game_state(posscore,negscore,self.time_elapsed(),self.game_time,self.pos_global,self.neg_global) self.mode=WAITING self.graphics.set_caption("Possession: Press 'g' to start") if self.mode==GAMEON: self.write_game_state(posscore,negscore,self.time_elapsed(),self.game_time,self.pos_global,self.neg_global) self.handle_events() # Outside while loop pygame.quit()
def __init__(self): self.TARGET_FPS = 30 cam_w,cam_h=(640,480) timer_w=480 self.resolution = (cam_w+timer_w,cam_h) pygame.init() pygame.mouse.set_visible(False) self.sounds = Sounds() try: assert(options.objects is not None) except: print "Make sure you define 1 or more vicon objects through -o" sys.exit(1) if options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" #window = pygame.display.set_mode((w,h), DOUBLEBUF) #window = pygame.display.set_mode((w,h), FULLSCREEN) if options.startfullscreen: window = pygame.display.set_mode(self.resolution,pygame.FULLSCREEN) self.fullscreen = 1 else: window = pygame.display.set_mode(self.resolution) # do not start full self.fullscreen = 0 # surface representing cam view self.camsurface = pygame.Surface((cam_w,cam_h)) # surface representing entire display self.screen = pygame.display.get_surface() self.cameras = [] for c in options.cameras: self.cameras.append(Camera(c,fps=self.TARGET_FPS)) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() self.balls = [] for o in options.objects: self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) # set up team colors if options.boygirl: # we know there are only two teams self.teamcolors = [cm.hsv(0.61),cm.hsv(0.86)] else: self.teamcolors = [cm.jet(x) for x in np.linspace(0.2,0.8,options.numteams)] # set up object colors (using a different colormap) # self.objectcolors = [cm.spring(x) for x in np.linspace(0,1,len(options.objects))] self.objectcolors = [cm.summer(x) for x in np.linspace(0,1,len(options.objects))] self.score = [0]*options.numteams self.update_score() self.accumulator = 0 self.digit = options.game_time self.clock = pygame.time.Clock() self.update_digit()
class Game: def __init__(self): self.TARGET_FPS = 30 cam_w,cam_h=(640,480) timer_w=480 self.resolution = (cam_w+timer_w,cam_h) pygame.init() pygame.mouse.set_visible(False) self.sounds = Sounds() try: assert(options.objects is not None) except: print "Make sure you define 1 or more vicon objects through -o" sys.exit(1) if options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" #window = pygame.display.set_mode((w,h), DOUBLEBUF) #window = pygame.display.set_mode((w,h), FULLSCREEN) if options.startfullscreen: window = pygame.display.set_mode(self.resolution,pygame.FULLSCREEN) self.fullscreen = 1 else: window = pygame.display.set_mode(self.resolution) # do not start full self.fullscreen = 0 # surface representing cam view self.camsurface = pygame.Surface((cam_w,cam_h)) # surface representing entire display self.screen = pygame.display.get_surface() self.cameras = [] for c in options.cameras: self.cameras.append(Camera(c,fps=self.TARGET_FPS)) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() self.balls = [] for o in options.objects: self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) # set up team colors if options.boygirl: # we know there are only two teams self.teamcolors = [cm.hsv(0.61),cm.hsv(0.86)] else: self.teamcolors = [cm.jet(x) for x in np.linspace(0.2,0.8,options.numteams)] # set up object colors (using a different colormap) # self.objectcolors = [cm.spring(x) for x in np.linspace(0,1,len(options.objects))] self.objectcolors = [cm.summer(x) for x in np.linspace(0,1,len(options.objects))] self.score = [0]*options.numteams self.update_score() self.accumulator = 0 self.digit = options.game_time self.clock = pygame.time.Clock() self.update_digit() def get_cam(self): p = np.random.permutation(range(len(self.cameras))) cam = self.cameras[p[0]] # select 1 camera print "camera %s" % cam.name pygame.display.set_caption(cam.name) return cam def advance(self): """Advances cameras.""" # GrabFrame in every camera # Strange things happen if we only grab in the active camera for c in self.cameras: cv.GrabFrame(c.capture) def hit(self,team,mode): """Handles a hit of target.""" print "HIT" if mode==GAMEON: self.score[team]+=1 self.update_score() self.sounds.swoosh1_sound.play() def reset(self): """Choose a new random camera and random target.""" cam = self.get_cam() targets = [Target(cam,radius=options.radius) for t in xrange(options.numteams)] return cam,targets def tick(self,timeChange): """Updates timer display.""" self.accumulator += timeChange if self.accumulator > 1000: self.accumulator = self.accumulator - 1000 self.digit-=1 self.update_digit() def update_score(self): # want to blank out the score area # so we are not writing scores on top of scores screen_w,screen_h = self.screen.get_size() cam_w,cam_h = self.camsurface.get_size() score_rec = pygame.Rect(cam_w,(2.0/3)*screen_h,(screen_w-cam_w),(1.0/3)*screen_h) if options.boygirl: #extra space for icons #score_rec = pygame.Rect(cam_w,(7.0/9)*screen_h,(screen_w-cam_w),(2.0/9)*screen_h) font = pygame.font.SysFont("Menlo",100) else: font = pygame.font.SysFont("Menlo",150) self.screen.fill((0,0,0),score_rec) #font = pygame.font.Font(None,440) # linspace including last elements for xpositioning buf=100 # pixel buffer on each side #xlinspace = np.linspace(cam_w,screen_w,options.numteams+2)[1:options.numteams+1] xlinspace = np.linspace(cam_w+buf,screen_w-buf,options.numteams) print xlinspace for t in xrange(options.numteams): font_color = (np.array(self.teamcolors[t])*255).tolist() image = font.render(str(self.score[t]), True, font_color) rect = image.get_rect() x = xlinspace[t] print x y = (5.0/6)*screen_h rect.center = (x,y) self.screen.blit(image,rect) def update_digit(self): # want to blank out the digit area # so we are not writing digits on top of digits screen_w,screen_h = self.screen.get_size() cam_w,cam_h = self.camsurface.get_size() digit_rec = pygame.Rect(cam_w,0,(screen_w-cam_w),(2.0/3)*screen_h) self.screen.fill((0,0,0),digit_rec) #font = pygame.font.Font(None,440) font = pygame.font.SysFont("Menlo",300) # now draw the new digit font_color = (255,255,255) image = font.render(str(self.digit), True, font_color) rect = image.get_rect() x = cam_w + (screen_w-cam_w)/2 y = screen_h/3 rect.center = (x,y) self.screen.blit(image,rect) def draw(self,frame,cam,targets): m = cv.GetMat(frame) arr = np.asarray(m) pygame.surfarray.blit_array(self.camsurface,arr.transpose(1,0,2)[:,:,::-1]) # draw target for i,t in enumerate(targets): target_color = (np.array(self.teamcolors[i])*255).tolist() pygame.draw.circle(self.camsurface, target_color, (t.x,t.y), t.radius, 0) pygame.draw.circle(self.camsurface, (255,255,255,0.1), (t.x,t.y), t.radius, 4) # draw markers cam_w,cam_h = self.camsurface.get_size() for j,b in enumerate(self.balls): ball_color = (np.array(self.objectcolors[j])*255).tolist() x,y = (cam.image_points[j,0],cam.image_points[j,1]) # note use of half radius (display size) to prevent circle going into clock display if x > 0 and x < cam_w-(t.radius/2.0) and y > 0 and y < cam_h: pygame.draw.circle(self.camsurface, ball_color, (x,y), int(t.radius/2.0), 0) pygame.draw.circle(self.camsurface, (0,0,0), (x,y), int(t.radius/2.0), 3) # optionally, flip the camera view (and targets,balls) horizontally to get mirror # then blit to screen if cam.mirrored: self.screen.blit(pygame.transform.flip(self.camsurface,True,False),(0,0)) else: self.screen.blit(self.camsurface,(0,0)) if options.boygirl: self.screen.blit(maleimage,(800,(4.0/6)*480)) self.screen.blit(femaleimage,(1075,(4.0/6)*480)) pygame.display.flip() def run(self): mode = WAITING cam,targets = self.reset() done = False while not done: timeChange = self.clock.tick(self.TARGET_FPS) self.advance() if self.simulation_mode: # read from file obj = get_now_file(self.f,debug=True) else: # read from vicon_proxy obj = get_now(self.vp) # only retrieve from chosen cam frame = cv.RetrieveFrame(cam.capture) if not frame: print "Frame is None" sys.exit(1) for j,b in enumerate(self.balls): b.set_pos(obj) p = b.get_pos() cam.object_points[j,0]=p[0] cam.object_points[j,1]=p[1] cam.object_points[j,2]=p[2] cam.project() # determine whether any of the balls have made the target for i,t in enumerate(targets): for j,b in enumerate(self.balls): if cam.match(t,j): self.hit(i,mode) cam,targets = self.reset() # update screen if mode==GAMEON: self.tick(timeChange) self.draw(frame,cam,targets) if mode==GAMEON and self.digit==0: print "GAME OVER" self.sounds.gameover_sound.play() mode=WAITING for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == KEYUP) or (event.type == KEYDOWN): print event if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_f: print "f" if self.fullscreen: self.fullscreen=0 window = pygame.display.set_mode(self.resolution) self.update_score() self.update_digit() else: self.fullscreen=1 window = pygame.display.set_mode(self.resolution, pygame.FULLSCREEN) self.update_score() self.update_digit() if (event.type == KEYDOWN and event.key == K_ESCAPE): if self.simulation_mode: self.f.close() else: self.vp.close() done = True if (event.type == KEYDOWN and event.key == K_SPACE): # select new camera, target cam,targets = self.reset() if (event.type == KEYDOWN and event.key == K_g): print "GO!" mode=GAMEON self.score = [0]*options.numteams self.update_score() self.clock = pygame.time.Clock() self.digit = options.game_time self.update_digit() # Outside while loop pygame.quit()
class Game: def __init__(self): self.r = Room(options.xmin,options.xmax,options.ymin,options.ymax) self.fs = fluidsynth.Synth() self.fs.start(driver="coreaudio") self.sfid = self.fs.sfload("./FluidR3_GM.sf2") self.notes = [69, 81, 74, 79, 57, 62, 67, 93, 86, 91] self.r.partition(options.partition,self.notes) try: self.pt = PanTilt() # set to max speed self.pt.set_max_speed() except: print "Couldn't initialize pan-tilt unit" self.pt = None pass if simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: try: self.vp = ViconProxy() except: print "Couldn't initialize Vicon Proxy" self.vp = 0 pass self.m = Mapper(options.netfile) self.graphics = Graphics(self.r) self.graphics.DrawBall() def show_sequence(self): self.fs.program_select(0,self.sfid,0,103) for p in self.s.partitions: pc = p.get_center() print pc ptmap = self.m.map(pc) # map to pan-tilt pan,tilt = ptmap[0] if self.pt: self.pt.go_block(pan,tilt,True) self.fs.noteon(0,p.note,127) self.graphics.HighlightPatch(p.idx) # raw_input("Press Enter to continue...") time.sleep(options.show_sleep) self.fs.noteoff(0,p.note) self.graphics.RestorePatch(p.idx) def run(self): # could adjust game params here (sequence length, etc.) # set up ball self.b = Ball(self.f if simulation_mode else self.vp,options.object) L = options.length T = options.max_time while True: print "Sequence length: %d, Time: %fs" % (L,T) WON_GAME = False p = self.b.get_pos() print "Initializing sequence" self.s = Sequence(L,T,self.r.partitions,\ self.r.get_partition(p[0],p[1])) print "Displaying sequence" self.show_sequence() print "GAME ON" self.s.start() while not self.s.isover(): if simulation_mode: # read from file obj = get_now_file(self.f,debug=True) else: # read from vicon_proxy obj = get_now(self.vp) self.b.set_pos(obj) p = self.b.get_pos() #print "ball: %s time left: %f" % (p,self.s.timeleft()) #print "ball in partition: %d" % self.r.get_partition(p[0],p[1]) v = self.b.get_vel() self.graphics.UpdateBall(p[0],p[1]) #print "velocity: %f" % v #only look for matches if the ball has approximately stopped if self.s.partitions[0].isin(p[0],p[1]): print "IN REGION" if v<options.min_vel: p = self.s.partitions[0] self.fs.noteon(0,p.note,127) self.graphics.HighlightPatch(p.idx) print "MATCH" # play the note for 1s then note off # this is a bit stupid though since everything stops time.sleep(1) self.fs.noteoff(0,p.note) self.graphics.RestorePatch(p.idx) self.s.match() if len(self.s.partitions)<1: WON_GAME = True break; time.sleep(1.0/10) if WON_GAME: print "SUCCESS! : time elapsed %fs" % (time.time()-self.s.start_time) # Applause self.fs.program_select(0,self.sfid,0,126) self.fs.noteon(0,60,127) time.sleep(1) self.fs.noteon(0,72,127) time.sleep(1) self.fs.noteon(0,84,127) time.sleep(3) self.fs.noteoff(0,60) self.fs.noteoff(0,72) self.fs.noteoff(0,84) # Adjust level if not options.crowd: L = L+1 else: print "Try again" # Buzzer sound self.fs.program_select(0,self.sfid,0,61) self.fs.noteon(0,36,127) time.sleep(1) self.fs.noteoff(0,36) time.sleep(3) # reset length of sequence to base L = options.length if simulation_mode: self.f.close() else: self.vp.close() if self.pt: self.pt.close() self.fs.delete()
class Game: """Handles timing, score, game objects and gameplay.""" def __init__(self,options): self.options = options self.game_time = self.options.game_time self.last_updated = time.time() # self.pos is a numobjects x 2 numpy array # which represents the x,y position of the objects # self.pos = np.zeros((numobjects,2)) self.postime = 0.0 self.negtime = 0.0 self.gameovertext=False #whether we have written GAME OVER on screen if self.options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" self.graphics = Graphics(self.options) if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() ## self.balls = [] ## for o in self.vicon_objects: ## self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) self.sounds = Sounds() # for user keyboard input # cv.NamedWindow( "Status", 1) def start_clock(self): self.clock_started = time.time() self.last_updated = self.clock_started def time_elapsed(self): return time.time()-self.clock_started def time_left(self): return self.game_time - self.time_elapsed() def update(self): self.last_updated = time.time() def sincelastupdate(self): return time.time()-self.last_updated def isgameover(self): return self.time_elapsed() >= self.game_time def gameover(self,posscore,negscore): self.graphics.erase_clock() self.graphics.gameover() self.gameovertext=True # self.sounds.play("gameover") self.sounds.gameover_sound.play() print "Game is over, here are some stats:" # print "postime: %6.2f" % (postime/len(vicon_objects)) # print "negtime: %6.2f" % (negtime/len(vicon_objects)) if self.postime+self.negtime > 0: print "postime: %6.2f" % posscore # (100*postime/(postime+negtime)) print "negtime: %6.2f" % negscore # (100*negtime/(postime+negtime)) else: print "No time recorded" if self.postime > self.negtime: print "Negative side wins!" elif self.negtime > self.postime: print "Positive side wins!" else: print "Tie" print "Press 'g' to play again" def countdown(self): # self.sounds.play("start") self.sounds.start_sound.play() self.graphics.countdown() def handle_events(self): # Event handling through pygame # Currently only two keystrokes: ESC and 'g' for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == KEYUP) or (event.type == KEYDOWN): print event if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_f: print "f" if self.graphics.fullscreen: self.graphics.fullscreen=0 window = pygame.display.set_mode(self.graphics.resolution) else: self.graphics.fullscreen=1 window = pygame.display.set_mode(self.graphics.resolution, pygame.FULLSCREEN) if (event.type == KEYDOWN and event.key == K_ESCAPE): if self.simulation_mode: self.f.close() else: self.vp.close() done = True if (self.mode==WAITING and event.type == KEYDOWN and event.key == K_g): self.mode=GAMEON print "Game ON" self.graphics.set_caption("Possession") if self.gameovertext: self.graphics.remove_gameover_text() self.countdown() self.postime = 0.0 self.negtime = 0.0 self.graphics.draw_clock(360) self.start_clock() def run(self): """ Main game loop """ self.mode = WAITING self.graphics.set_caption("Possession: Press 'g' to start") print "Press 'g' to start play" #mode = GAMEON # debug #reset_clock() done = False while not done: if self.simulation_mode: # read from file obj = get_now_file(self.f,debug=self.options.debug) else: # read from vicon_proxy obj = get_now(self.vp) ## for b in self.balls: ## b.set_pos(obj) markers = get_vicon_raw(obj) # if we couldn't get a proper object (i.e. tracking mode) # then markers will be none # just wait for data but still handle events if markers is None: # maybe not raw mode, keep trying print "Still waiting for data..." self.handle_events() continue # time.sleep(1.0/60) # If there are no markers, then markers will be an empty list # we cannot convert to array # So we create a single dummy neutral point far, far away if len(markers)>0: if options.swap: # use x and z self.pos = np.array(markers)[:,0:3:2] else: self.pos = np.array(markers)[:,0:2] # only take x,y else: print "NO MARKERS" if options.axis==0: self.pos = np.array([[0,1000000]]) else: self.pos = np.array([[1000000,0]]) ## c=0 ## for b in self.balls: ## pos = b.get_pos() ## # update position for display ## self.pos[c,:] = b.pos[0:2] # only take x,y ## c+=1 # regardless of whether we're playing game # update ball position on display #self.graphics.update_ballpos(self.pos) self.graphics.draw_markers(self.pos) # accumulate time on each side if self.mode==GAMEON: s = self.sincelastupdate() # time since last update for m in markers: if m[self.options.axis]>0: self.postime+=s elif m[self.options.axis]<0: self.negtime+=s ## for b in self.balls: ## pos=b.get_pos() ## changed=b.changed(self.options.axis) # did it change sides? ## if pos[self.options.axis] > 0: ## if self.options.debug: ## print "%s + " % b.objectname ## self.postime += s ## elif pos[self.options.axis] < 0: ## if self.options.debug: ## print "%s - " % b.objectname ## self.negtime += s ## # play sounds if ball changed sides ## if changed==1: ## # self.sounds.play("swoosh1") ## self.sounds.swoosh1_sound.play() ## elif changed==2: ## # self.sounds.play("swoosh2") ## self.sounds.swoosh2_sound.play() self.update() #update clock # update text if game is on if self.mode==GAMEON: timeleft = self.time_left() posscore=100-round(100*self.postime/(self.postime+self.negtime+1e-9)) negscore=100-round(100*self.negtime/(self.postime+self.negtime+1e-9)) # I don't see a set_radius command # So I just remove the patch collection, recreate wedge, collection # and add collection again self.graphics.erase_clock() # clock takes a single argument - hand position in degrees self.graphics.draw_clock(360*timeleft/options.game_time) self.graphics.update_scores(posscore,negscore) # regardless of whether we are playing or not, update plot self.graphics.redraw() if self.mode==GAMEON and g.isgameover(): self.mode=GAMEDONE self.gameover(posscore,negscore) self.mode=WAITING self.graphics.set_caption("Possession: Press 'g' to start") self.handle_events() # Outside while loop pygame.quit()
def __init__(self): self.TARGET_FPS = 30 cam_w, cam_h = (640, 480) timer_w = 640 w, h = (cam_w + timer_w, cam_h) pygame.init() self.cam_w = cam_w self.cam_h = cam_h self.sounds = Sounds() # ISPIRO: Load goal image. Pygame handles png transparency gracefully self.goal_image = pygame.image.load("goal.png") self.goal_w = self.goal_image.get_width() self.goal_h = self.goal_image.get_height() try: assert options.objects is not None except: print "Make sure you define 1 or more vicon objects through -o" sys.exit(1) if options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. " "Possession will hang here if you are not connected to a Vicon Proxy server" window = pygame.display.set_mode((w, h), DOUBLEBUF) # surface representing cam view self.camsurface = pygame.Surface((cam_w, cam_h)) # ISPIRO: Need a mask image for blitting circles self.mask = pygame.Surface((cam_w, cam_h)) # surface representing entire display self.screen = pygame.display.get_surface() self.cameras = [] for c in options.cameras: self.cameras.append(Camera(c, fps=self.TARGET_FPS)) if self.simulation_mode: self.f = open(options.vicon_file, "r") # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() self.balls = [] for o in options.objects: self.balls.append(Ball(self.f if self.simulation_mode else self.vp, o)) # set up team colors self.teamcolors = [cm.jet(x) for x in np.linspace(0.2, 0.8, options.numteams)] # set up object colors (using a different colormap) self.objectcolors = [cm.spring(x) for x in np.linspace(0, 1, len(options.objects))] self.score = [0] * options.numteams # self.update_score() self.accumulator = 0 self.digit = options.game_time self.clock = pygame.time.Clock()
class Game: def __init__(self): self.TARGET_FPS = 30 cam_w, cam_h = (640, 480) timer_w = 640 w, h = (cam_w + timer_w, cam_h) pygame.init() self.cam_w = cam_w self.cam_h = cam_h self.sounds = Sounds() # ISPIRO: Load goal image. Pygame handles png transparency gracefully self.goal_image = pygame.image.load("goal.png") self.goal_w = self.goal_image.get_width() self.goal_h = self.goal_image.get_height() try: assert options.objects is not None except: print "Make sure you define 1 or more vicon objects through -o" sys.exit(1) if options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. " "Possession will hang here if you are not connected to a Vicon Proxy server" window = pygame.display.set_mode((w, h), DOUBLEBUF) # surface representing cam view self.camsurface = pygame.Surface((cam_w, cam_h)) # ISPIRO: Need a mask image for blitting circles self.mask = pygame.Surface((cam_w, cam_h)) # surface representing entire display self.screen = pygame.display.get_surface() self.cameras = [] for c in options.cameras: self.cameras.append(Camera(c, fps=self.TARGET_FPS)) if self.simulation_mode: self.f = open(options.vicon_file, "r") # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() self.balls = [] for o in options.objects: self.balls.append(Ball(self.f if self.simulation_mode else self.vp, o)) # set up team colors self.teamcolors = [cm.jet(x) for x in np.linspace(0.2, 0.8, options.numteams)] # set up object colors (using a different colormap) self.objectcolors = [cm.spring(x) for x in np.linspace(0, 1, len(options.objects))] self.score = [0] * options.numteams # self.update_score() self.accumulator = 0 self.digit = options.game_time self.clock = pygame.time.Clock() # self.update_digit() def get_cam(self): p = np.random.permutation(range(len(self.cameras))) cam = self.cameras[p[0]] # select 1 camera print "camera %s" % cam.name pygame.display.set_caption(cam.name) return cam def advance(self): """Advances cameras.""" # GrabFrame in every camera # Strange things happen if we only grab in the active camera for c in self.cameras: cv.GrabFrame(c.capture) def hit(self, team, mode): """Handles a hit of target.""" print "HIT" if mode == GAMEON: self.score[team] += 1 self.update_score() self.sounds.swoosh1_sound.play() def reset(self): """Choose a new random camera and random target.""" cam = self.get_cam() self.mask = pygame.Surface((self.cam_w, self.cam_h)) return cam def tick(self, timeChange): """Updates timer display.""" self.accumulator += timeChange if self.accumulator > 1000: self.accumulator = self.accumulator - 1000 self.digit -= 1 self.update_digit() def update_score(self): # want to blank out the score area # so we are not writing scores on top of scores screen_w, screen_h = self.screen.get_size() cam_w, cam_h = self.camsurface.get_size() score_rec = pygame.Rect(cam_w, (2.0 / 3) * screen_h, (screen_w - cam_w), (1.0 / 3) * screen_h) self.screen.fill((0, 0, 0), score_rec) # font = pygame.font.Font(None,440) font = pygame.font.SysFont("Menlo", 150) # linspace including last elements for xpositioning buf = 100 # pixel buffer on each side # xlinspace = np.linspace(cam_w,screen_w,options.numteams+2)[1:options.numteams+1] xlinspace = np.linspace(cam_w + buf, screen_w - buf, options.numteams) print xlinspace for t in xrange(options.numteams): font_color = (np.array(self.teamcolors[t]) * 255).tolist() image = font.render(str(self.score[t]), True, font_color) rect = image.get_rect() x = xlinspace[t] print x y = (5.0 / 6) * screen_h rect.center = (x, y) self.screen.blit(image, rect) def update_digit(self): # want to blank out the digit area # so we are not writing digits on top of digits screen_w, screen_h = self.screen.get_size() cam_w, cam_h = self.camsurface.get_size() digit_rec = pygame.Rect(cam_w, 0, (screen_w - cam_w), (2.0 / 3) * screen_h) self.screen.fill((0, 0, 0), digit_rec) # font = pygame.font.Font(None,440) font = pygame.font.SysFont("Menlo", 300) # now draw the new digit font_color = (255, 255, 255) image = font.render(str(self.digit), True, font_color) rect = image.get_rect() x = cam_w + (screen_w - cam_w) / 2 y = screen_h / 3 rect.center = (x, y) self.screen.blit(image, rect) def draw(self, frame, cam): m = cv.GetMat(frame) arr = np.asarray(m) pygame.surfarray.blit_array(self.camsurface, arr.transpose(1, 0, 2)[:, :, ::-1]) # ISPIRO: Make a second copy of the image on the right half for masking out self.screen.blit(pygame.transform.flip(self.camsurface, True, False), (640, 0)) rad = 50 # draw markers cam_w, cam_h = self.camsurface.get_size() for j, b in enumerate(self.balls): ball_color = (np.array(self.objectcolors[j]) * 255).tolist() x, y = (cam.image_points[j, 0], cam.image_points[j, 1]) # note use of half radius (display size) to prevent circle going into clock display # ISPIRO: Blit out png graphic self.camsurface.blit(self.goal_image, (x - self.goal_w / 2, y - self.goal_h / 2)) # pygame.draw.circle(self.camsurface, ball_color, # (x,y), rad, 0) # pygame.draw.circle(self.camsurface, (0,0,0), # (x,y), rad, 3) # ISPIRO: Draw a white circle on the mask image pygame.draw.circle(self.mask, (255, 255, 255), (x, y), rad, 0) # optionally, flip the camera view (and targets,balls) horizontally to get mirror # then blit to screen # ISPIRO: Use BLEND_MULT to quickly produce the masked ipcam image if cam.mirrored: self.screen.blit(pygame.transform.flip(self.camsurface, True, False), (0, 0)) self.screen.blit(pygame.transform.flip(self.mask, True, False), (640, 0), None, pygame.BLEND_MULT) else: self.screen.blit(self.camsurface, (0, 0)) self.screen.blit(self.mask, (640, 0), None, pygame.BLEND_MULT) pygame.display.flip() def run(self): mode = WAITING cam = self.reset() done = False while not done: timeChange = self.clock.tick(self.TARGET_FPS) self.advance() if self.simulation_mode: # read from file obj = get_now_file(self.f, debug=True) else: # read from vicon_proxy obj = get_now(self.vp) # only retrieve from chosen cam frame = cv.RetrieveFrame(cam.capture) if not frame: print "Frame is None" sys.exit(1) for j, b in enumerate(self.balls): b.set_pos(obj) p = b.get_pos() cam.object_points[j, 0] = p[0] cam.object_points[j, 1] = p[1] cam.object_points[j, 2] = p[2] cam.project() # update screen if mode == GAMEON: self.tick(timeChange) self.draw(frame, cam) if mode == GAMEON and self.digit == 0: print "GAME OVER" self.sounds.gameover_sound.play() mode = WAITING for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == KEYUP) or (event.type == KEYDOWN): print event if event.type == KEYDOWN and event.key == K_ESCAPE: if self.simulation_mode: self.f.close() else: self.vp.close() done = True if event.type == KEYDOWN and event.key == K_SPACE: # select new camera, target cam = self.reset() if event.type == KEYDOWN and event.key == K_g: print "GO!" mode = GAMEON self.score = [0] * options.numteams self.update_score() self.clock = pygame.time.Clock() self.digit = options.game_time
class Game: """Handles timing, score, game objects and gameplay.""" def __init__(self,options): self.options = options pygame.init() # Related to writing game state self.clock = pygame.time.Clock() # currently this clock is only used for game state writes self.accumulator = 0 # used for game state writes self.write_game_state(0,0,0,0,0,0) # dummy game state means we are waiting # Global scores self.pos_global=0 self.neg_global=0 self.game_time = self.options.game_time self.last_updated = time.time() if self.options.vicon_file is not None: self.simulation_mode = True else: self.simulation_mode = False print "Running in live mode. "\ "Possession will hang here if you are not connected to a Vicon Proxy server" if self.simulation_mode: self.f = open(options.vicon_file,'r') # should we read ahead? for i in xrange(options.line): self.f.readline() else: # Initialize the object... print "Waiting for Vicon..." self.vp = ViconProxy() #Vicon objects as defined on command-line if options.objects is None: print "Automatic object detection mode" while options.objects is None: print "Looking for objects..." options.objects = self.lookfor_objects() # Handle events self.handle_events() else: print "Objects are defined on command line" self.vicon_objects = self.options.objects try: assert(self.vicon_objects is not None) except: print "Make sure you define 1 or more vicon objects through -o" sys.exit(1) numobjects = len(self.vicon_objects) # self.pos is a numobjects x 2 numpy array # which represents the x,y position of the objects self.pos = np.zeros((numobjects,2)) self.postime = 0.0 self.negtime = 0.0 self.gameovertext=False #whether we have written GAME OVER on screen # Currently our graphics implementation (matplotlib + pygame) is a bit hacky # Matplotlib is set to have equal axes (in terms of units) # Therefore the aspect ratio of the room must equal the aspect ratio of the fixed # Screen resolution for matplotlib and pygame to line up # So here we make sure that aspect ratios are the same aspect = float(self.options.height)/self.options.width print "DEBUG: screen aspect %f" % aspect # keep x, but change y roomw = (self.options.xmax-self.options.xmin) roomh = (self.options.ymax-self.options.ymin) targetroomh = roomw*aspect print "DEBUG: room w: %f, target room h: %f" % (roomw,targetroomh) roomhcenter = self.options.ymin+roomh/2.0 # update room y to match target aspect ratio self.options.ymin = roomhcenter - targetroomh/2.0 self.options.ymax = roomhcenter + targetroomh/2.0 print "DEBUG: new ymin: %f, new ymax: %f" % (self.options.ymin,self.options.ymax) self.graphics = Graphics(self.options,self.pos) self.balls = [] for o in self.vicon_objects: self.balls.append(Ball(self.f if self.simulation_mode else self.vp,o) ) self.sounds = Sounds() # for user keyboard input # cv.NamedWindow( "Status", 1) def lookfor_objects(self): objects = None if self.simulation_mode: # read from file obj = get_now_file(self.f,debug=True) else: # read from vicon_proxy obj = get_now(self.vp) try: assert(obj['mode']==1) # should be in object mode # list of objects objs=obj['objs'] except: print "ERROR while parsing objs. Is proxy in raw mode?" return objects # add every object currently broadcasting objects = [] for o in objs: objects.append(o['name']) print "Added: %s" % o['name'] return objects def start_clock(self): self.clock_started = time.time() self.last_updated = self.clock_started def time_elapsed(self): return time.time()-self.clock_started def time_left(self): return self.game_time - self.time_elapsed() def update(self): self.last_updated = time.time() def sincelastupdate(self): return time.time()-self.last_updated def isgameover(self): return self.time_elapsed() >= self.game_time def gameover(self,posscore,negscore): self.graphics.erase_clock() self.graphics.gameover(self.postime,self.negtime) self.gameovertext=True # self.sounds.play("gameover") self.sounds.gameover_sound.play() print "Game is over, here are some stats:" # print "postime: %6.2f" % (postime/len(vicon_objects)) # print "negtime: %6.2f" % (negtime/len(vicon_objects)) if self.postime+self.negtime > 0: print "postime: %6.2f" % posscore # (100*postime/(postime+negtime)) print "negtime: %6.2f" % negscore # (100*negtime/(postime+negtime)) else: print "No time recorded" if self.postime > self.negtime: print "Negative side wins!" self.neg_global+=1 elif self.negtime > self.postime: print "Positive side wins!" self.pos_global+=1 else: print "Tie" self.pos_global+=1 self.neg_global+=1 print "Press 'g' to play again" def getready(self): # self.sounds.play("start") self.accumulator = 0 # used for game state writes self.graphics.instructions() self.sounds.start_sound.play() self.graphics.countdown() def handle_events(self): # Event handling through pygame # Currently only two keystrokes: ESC and 'g' for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == KEYUP) or (event.type == KEYDOWN): print event if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_f: print "f" if self.graphics.fullscreen: self.graphics.fullscreen=0 window = pygame.display.set_mode(self.graphics.resolution) else: self.graphics.fullscreen=1 window = pygame.display.set_mode(self.graphics.resolution, pygame.FULLSCREEN) if hasattr(event, 'key') and event.type == pygame.KEYDOWN: if event.key == pygame.K_1: print "timing 10" self.game_time = 10.0 elif event.key == pygame.K_3: print "timing 30" self.game_time = 30.0 elif event.key == pygame.K_6: print "timing 60" self.game_time = 60.0 elif event.key == pygame.K_9: print "timing 90" self.game_time = 90.0 if (event.key == K_ESCAPE): if self.simulation_mode: self.f.close() else: self.vp.close() done = True # Delete game state file print "Removing game state" os.remove(options.game_state_file) if (self.mode==WAITING and event.type == KEYUP and event.key == K_g): self.mode=GAMEON print "Game ON" self.graphics.set_caption("Possession") if self.gameovertext: self.graphics.remove_gameover_text() self.getready() self.postime = 0.0 self.negtime = 0.0 self.graphics.draw_clock(360) self.start_clock() if (event.type == KEYDOWN and event.key == K_u): print "Update Vicon objects" options.objects = None while options.objects is None: print "Looking for objects..." options.objects = self.lookfor_objects() # Handle events self.handle_events() self.vicon_objects = self.options.objects def write_game_state(self,*state): """Writes the game state to a text file at a specific period. Name of file and period are set by command-line. """ #print "Considering game state write" timeChange = self.clock.tick() self.accumulator += timeChange #print "Accumulator: %f" % self.accumulator if self.accumulator > options.game_state_period: self.accumulator = self.accumulator - options.game_state_period print "Writing game state" f = open(options.game_state_file, 'w') for s in state[:-1]: f.write('%f,' % s) f.write('%f\n' % state[-1]) f.close() def run(self): """ Main game loop """ self.mode = WAITING self.graphics.set_caption("Possession: Press 'g' to start") print "Press 'g' to start play" #mode = GAMEON # debug #reset_clock() done = False while not done: if self.simulation_mode: # read from file obj = get_now_file(self.f,debug=self.options.debug) else: # read from vicon_proxy obj = get_now(self.vp) for b in self.balls: b.set_pos(obj) # time.sleep(1.0/60) c=0 for b in self.balls: pos = b.get_pos() # update position for display self.pos[c,:] = b.pos[0:2] # only take x,y c+=1 # regardless of whether we're playing game # update ball position on display self.graphics.update_ballpos(self.pos) # accumulate time on each side if self.mode==GAMEON: s = self.sincelastupdate() # time since last update for b in self.balls: pos=b.get_pos() changed=b.changed(self.options.axis) # did it change sides? if pos[self.options.axis] > 0: if self.options.debug: print "%s + " % b.objectname self.postime += s elif pos[self.options.axis] < 0: if self.options.debug: print "%s - " % b.objectname self.negtime += s # play sounds if ball changed sides if changed==1: # self.sounds.play("swoosh1") self.sounds.swoosh1_sound.play() elif changed==2: # self.sounds.play("swoosh2") self.sounds.swoosh2_sound.play() self.update() #update clock # update text if game is on if self.mode==GAMEON: timeleft = self.time_left() posscore=100-round(100*self.postime/(self.postime+self.negtime+1e-9)) negscore=100-round(100*self.negtime/(self.postime+self.negtime+1e-9)) # I don't see a set_radius command # So I just remove the patch collection, recreate wedge, collection # and add collection again self.graphics.erase_clock() # clock takes a single argument - hand position in degrees self.graphics.draw_clock(360*timeleft/self.game_time) self.graphics.update_scores(posscore,negscore) # regardless of whether we are playing or not, update plot self.graphics.redraw() if self.mode==GAMEON and g.isgameover(): self.mode=GAMEDONE self.gameover(posscore,negscore) # do one last write self.write_game_state(posscore,negscore,self.time_elapsed(),self.game_time,self.pos_global,self.neg_global) self.mode=WAITING self.graphics.set_caption("Possession: Press 'g' to start") if self.mode==GAMEON: self.write_game_state(posscore,negscore,self.time_elapsed(),self.game_time,self.pos_global,self.neg_global) self.handle_events() # Outside while loop pygame.quit()