Example #1
0
    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()
Example #2
0
    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()
Example #3
0
    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()
Example #4
0
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()
Example #5
0
    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()
Example #6
0
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()
Example #7
0
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()
Example #8
0
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()
Example #9
0
    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()
Example #10
0
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
Example #11
0
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()