Ejemplo n.º 1
0
    def __init__(self,players,fullscreen,songSelect,get_data,send_data): # fullscreen is boolean
        pygame.mixer.pre_init(44100, 16, 2, 4096)
        self.graphics_path = "../res/graphics/" # should be passed by UI and then passed to stage
        self.sound_path = "../res/sound/" # should be passed by UI and then passed to stage
        self.barellCannonShoot = pygame.mixer.Sound(self.graphics_path+"barrelCannonShoot.ogg")
        self.quitSound = pygame.mixer.Sound(self.sound_path+"gottago.ogg")
        self.lose = pygame.mixer.Sound(self.sound_path+"mescusi.ogg")
        self.sem = threading.Semaphore()
        self.players = players
        self.stage_width,self.stage_height = 550,800
        self.sidebar_width = 180 # sidebar displays statistics
        if len(players) == 1 and get_data == None and send_data == None:
            self.sidebar_width += 10
        self.wall_gap = 10 # space between the walls and the edge of the window
        self.gap_size = 300.0 # how big the gap in the middle is
        self.padding = 10.0 # segment padding
        self.gravity = (0.0, -100.0)
        self.bound_color = "lightgray" # boundary walls color
        self.bg_color = "black" # window background color
        self.bullet_color = "yellow"
        self.step_size = 1/30.0
        self.running = False
        self.stages = []
        self.spawn_rate = 3
        self.spawn_rate_step = 0.25
        self.spawn_rate_interval = 30
        self.swing_y_lower_lim = 0.75 # used in generation of random starting position for swings
        self.swing_y_upper_lim = 0.95
        self.loser = None # pointer to loser player
        self.get_data = get_data
        self.send_data = send_data
        self.virtual_stage = None
        self.opponent_name = None
        self.y_pos = None
        self.game_finished = False
          
        pygame.init()
        
        if songSelect == 0:
            random.seed()
            randNum = random.randint(0,len(level_music)-1)
            pygame.mixer.music.load(self.sound_path+level_music[randNum])
            pygame.mixer.music.play()
            pygame.mixer.music.set_endevent(USEREVENT)
        else:
            pygame.mixer.music.load(self.sound_path+level_music[int(songSelect)-1])
            pygame.mixer.music.play(-1)

        if get_data != None and send_data != None:
            self.networked_game = True
        else:
            self.networked_game = False
        
        if self.networked_game:
            self.get_data.fun = self.parse_data # register data handling callback
            screen_dim = (2*self.stage_width+self.sidebar_width,self.stage_height)
        else:
            screen_dim = (len(self.players)*self.stage_width+self.sidebar_width,self.stage_height)
        if fullscreen:
            self.screen = pygame.display.set_mode(screen_dim,pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode(screen_dim,HWSURFACE)
            
        self.background = pygame.image.load(self.graphics_path+"background.jpg").convert()
        
        if len(players) == 2 or get_data != None: #if its a multiplayer game
            self.gameover = pygame.image.load(self.graphics_path+"2pGameOver.png").convert_alpha()
        else:
            self.gameover = pygame.image.load(self.graphics_path+"1pGameOver.png").convert_alpha()
            
          
        self.clock = pygame.time.Clock()
        pm.init_pymunk()
                
        if self.networked_game: 
            x_offset = 0
            #time.sleep(3)
            name_dict = {"player_name":players[0].name}
            self.send_data.send([name_dict])
            #if it is the host, generate the random y position of the swings and send it to the client
            if self.send_data.comp == "server":
                self.y_pos = [random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim)]
                y_pos_dict = {"y_pos" : self.y_pos}
                self.send_data.send([y_pos_dict])
            #otherwise get the data from the host and parse the data
            while(self.y_pos == None or self.opponent_name == None):
                time.sleep(.1)
            
            new_stage = Stage(players[0],self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.padding,self.bound_color,self.gravity,x_offset,self.sidebar_width,self.bullet_color, True,self.graphics_path,self.sound_path)
            x_step = self.stage_width/4
            j = 0
            for i in range(x_step,x_step*4,x_step):
                new_swing = Polyswing(new_stage,i,self.y_pos[j],1,1,10,1500,1,10,20,1,7,None,3,1,"red")
                j += 1
            
            self.stages.append(new_stage)
            
            x_offset += self.stage_width+self.sidebar_width
            
            #set up opponents virtual stage
            self.virtual_stage = Virtualstage(self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.sidebar_width,self.bound_color,x_offset,self.graphics_path,self.sound_path)
            self.virtual_stage.player = Player(self.opponent_name,1,None,None,None,None,None,None,None,None,None,None)
                        
            
        else: #it's not a networked game
            x_offset = 0
            self.y_pos = [random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim)]
            if len(self.players) > 1:
                is_multiplayer = True
            else:
                is_multiplayer = False
                
            for player in self.players: # initialize stage for each player
                new_stage = Stage(player,self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.padding,self.bound_color,self.gravity,x_offset,self.sidebar_width,self.bullet_color,is_multiplayer,self.graphics_path,self.sound_path)
                x_step = self.stage_width/4
                j = 0
                for i in range(x_step,x_step*4,x_step):
                    new_swing = Polyswing(new_stage,i,self.y_pos[j],1,1,10,1500,1,10,20,1,7,None,3,1,"red")
                    j += 1
                
                self.stages.append(new_stage)
                x_offset += self.stage_width+self.sidebar_width    
        
        #use player 1's sound volume by default
        self.barellCannonShoot.set_volume(players[0].volume)
        self.quitSound.set_volume(players[0].volume)
        self.lose.set_volume(players[0].volume)
Ejemplo n.º 2
0
class Game(object):
    def __init__(self,players,fullscreen,songSelect,get_data,send_data): # fullscreen is boolean
        pygame.mixer.pre_init(44100, 16, 2, 4096)
        self.graphics_path = "../res/graphics/" # should be passed by UI and then passed to stage
        self.sound_path = "../res/sound/" # should be passed by UI and then passed to stage
        self.barellCannonShoot = pygame.mixer.Sound(self.graphics_path+"barrelCannonShoot.ogg")
        self.quitSound = pygame.mixer.Sound(self.sound_path+"gottago.ogg")
        self.lose = pygame.mixer.Sound(self.sound_path+"mescusi.ogg")
        self.sem = threading.Semaphore()
        self.players = players
        self.stage_width,self.stage_height = 550,800
        self.sidebar_width = 180 # sidebar displays statistics
        if len(players) == 1 and get_data == None and send_data == None:
            self.sidebar_width += 10
        self.wall_gap = 10 # space between the walls and the edge of the window
        self.gap_size = 300.0 # how big the gap in the middle is
        self.padding = 10.0 # segment padding
        self.gravity = (0.0, -100.0)
        self.bound_color = "lightgray" # boundary walls color
        self.bg_color = "black" # window background color
        self.bullet_color = "yellow"
        self.step_size = 1/30.0
        self.running = False
        self.stages = []
        self.spawn_rate = 3
        self.spawn_rate_step = 0.25
        self.spawn_rate_interval = 30
        self.swing_y_lower_lim = 0.75 # used in generation of random starting position for swings
        self.swing_y_upper_lim = 0.95
        self.loser = None # pointer to loser player
        self.get_data = get_data
        self.send_data = send_data
        self.virtual_stage = None
        self.opponent_name = None
        self.y_pos = None
        self.game_finished = False
          
        pygame.init()
        
        if songSelect == 0:
            random.seed()
            randNum = random.randint(0,len(level_music)-1)
            pygame.mixer.music.load(self.sound_path+level_music[randNum])
            pygame.mixer.music.play()
            pygame.mixer.music.set_endevent(USEREVENT)
        else:
            pygame.mixer.music.load(self.sound_path+level_music[int(songSelect)-1])
            pygame.mixer.music.play(-1)

        if get_data != None and send_data != None:
            self.networked_game = True
        else:
            self.networked_game = False
        
        if self.networked_game:
            self.get_data.fun = self.parse_data # register data handling callback
            screen_dim = (2*self.stage_width+self.sidebar_width,self.stage_height)
        else:
            screen_dim = (len(self.players)*self.stage_width+self.sidebar_width,self.stage_height)
        if fullscreen:
            self.screen = pygame.display.set_mode(screen_dim,pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode(screen_dim,HWSURFACE)
            
        self.background = pygame.image.load(self.graphics_path+"background.jpg").convert()
        
        if len(players) == 2 or get_data != None: #if its a multiplayer game
            self.gameover = pygame.image.load(self.graphics_path+"2pGameOver.png").convert_alpha()
        else:
            self.gameover = pygame.image.load(self.graphics_path+"1pGameOver.png").convert_alpha()
            
          
        self.clock = pygame.time.Clock()
        pm.init_pymunk()
                
        if self.networked_game: 
            x_offset = 0
            #time.sleep(3)
            name_dict = {"player_name":players[0].name}
            self.send_data.send([name_dict])
            #if it is the host, generate the random y position of the swings and send it to the client
            if self.send_data.comp == "server":
                self.y_pos = [random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim)]
                y_pos_dict = {"y_pos" : self.y_pos}
                self.send_data.send([y_pos_dict])
            #otherwise get the data from the host and parse the data
            while(self.y_pos == None or self.opponent_name == None):
                time.sleep(.1)
            
            new_stage = Stage(players[0],self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.padding,self.bound_color,self.gravity,x_offset,self.sidebar_width,self.bullet_color, True,self.graphics_path,self.sound_path)
            x_step = self.stage_width/4
            j = 0
            for i in range(x_step,x_step*4,x_step):
                new_swing = Polyswing(new_stage,i,self.y_pos[j],1,1,10,1500,1,10,20,1,7,None,3,1,"red")
                j += 1
            
            self.stages.append(new_stage)
            
            x_offset += self.stage_width+self.sidebar_width
            
            #set up opponents virtual stage
            self.virtual_stage = Virtualstage(self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.sidebar_width,self.bound_color,x_offset,self.graphics_path,self.sound_path)
            self.virtual_stage.player = Player(self.opponent_name,1,None,None,None,None,None,None,None,None,None,None)
                        
            
        else: #it's not a networked game
            x_offset = 0
            self.y_pos = [random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim),random.randint(self.stage_height*self.swing_y_lower_lim,self.stage_height*self.swing_y_upper_lim)]
            if len(self.players) > 1:
                is_multiplayer = True
            else:
                is_multiplayer = False
                
            for player in self.players: # initialize stage for each player
                new_stage = Stage(player,self.screen,self.stage_width,self.stage_height,self.wall_gap,self.gap_size,self.padding,self.bound_color,self.gravity,x_offset,self.sidebar_width,self.bullet_color,is_multiplayer,self.graphics_path,self.sound_path)
                x_step = self.stage_width/4
                j = 0
                for i in range(x_step,x_step*4,x_step):
                    new_swing = Polyswing(new_stage,i,self.y_pos[j],1,1,10,1500,1,10,20,1,7,None,3,1,"red")
                    j += 1
                
                self.stages.append(new_stage)
                x_offset += self.stage_width+self.sidebar_width    
        
        #use player 1's sound volume by default
        self.barellCannonShoot.set_volume(players[0].volume)
        self.quitSound.set_volume(players[0].volume)
        self.lose.set_volume(players[0].volume)
                
    def start(self): # start pymunk, run main loop, and then return stats for each player
        self.running = True
        
        last_swing_spawn = 0 # last swing spawn
        last_spawn_rate_update = 0
        last_net_stat_update = 0
        last_score_sent = 0
        
        while self.running: # main game loop
            game_time = pygame.time.get_ticks()/1000.
            if self.game_finished:
                self.running = False
            if self.networked_game: 
                if game_time-last_net_stat_update >= 0.25:
                    last_net_stat_update = game_time
                    self.send_data.send(self.stages[0].objects_to_send())
            for event in pygame.event.get():
                if event.type == QUIT:
                    self.quitSound.play()
                    self.running = False
                elif event.type == KEYDOWN and event.key == K_ESCAPE:
                    self.quitSound.play()
                    self.running = False
                elif event.type == USEREVENT:
                    randNum = random.randint(0,len(level_music)-1)
                    pygame.mixer.music.load(self.sound_path+level_music[randNum])
                    pygame.mixer.music.play()
                    pygame.mixer.music.set_endevent(USEREVENT)
                    
                for stage in self.stages:
                    if stage.running == True:
                        if stage.player.controller:
                            if (event.type==JOYBUTTONDOWN and stage.player.controller.get_button(0)):
                                stage.gun.shoot(1200)
                            elif (event.type==JOYBUTTONDOWN and stage.player.controller.get_button(2)):
                                if len(stage.cannons) > 0:
                                    stage.cannons[0].shoot(1000)
                                    if stage.cannons[0].loaded:
                                        self.barellCannonShoot.play()
                                
                            opponent_stage = None
                            for find_stage in self.stages:
                                if find_stage != stage:
                                    opponent_stage = find_stage
                            
                            if (event.type == JOYBUTTONDOWN and stage.player.controller.get_button(5)):
                                stage.build_down_operation(opponent_stage)
                            if (event.type == JOYBUTTONDOWN and stage.player.controller.get_button(4)):
                                stage.build_up_operation(opponent_stage)
                            if (event.type == JOYBUTTONDOWN and stage.player.controller.get_button(1)):
                                stage.build_operation(opponent_stage)
                            if (event.type == JOYBUTTONDOWN and stage.player.controller.get_button(3)):
                                stage.cancel_operation(opponent_stage)
                                
                        else:                                
                            if event.type == KEYDOWN and event.key == stage.shoot_key:
                               stage.gun.shoot(1200)
                            elif event.type == KEYDOWN and event.key == stage.player.key_barrel_shoot:
                                #there should only be 1 barrel at most... if there are more this needs to be changed
                                if len(stage.cannons) > 0:
                                    stage.cannons[0].shoot(1000)
                                    if stage.cannons[0].loaded:
                                        self.barellCannonShoot.play()
                           
                            opponent_stage = None
                            for find_stage in self.stages:
                                if find_stage != stage:
                                    opponent_stage = find_stage
                        
                            if event.type == KEYDOWN and event.key == stage.player.key_build_down:
                                stage.build_down_operation(opponent_stage)
                        
                            if event.type == KEYDOWN and event.key == stage.player.key_build_up:
                                stage.build_up_operation(opponent_stage)
                        
                            if event.type == KEYDOWN and event.key == stage.player.key_build_confirm:
                                stage.build_operation(opponent_stage)
                        
                            if event.type == KEYDOWN and event.key == stage.player.key_build_cancel:
                                stage.cancel_operation(opponent_stage)
                

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

            if game_time - last_spawn_rate_update >= self.spawn_rate_interval:
                last_spawn_rate_update = game_time
                self.update_spawn_rate()
                    
            if game_time-last_swing_spawn >= self.spawn_rate:
                last_swing_spawn = game_time
                for stage in self.stages:
                    stage.spawn_swing()
            
            for stage in self.stages:
                stage.process_input()
                if stage.running == True:
                    stage.bullet_reload(game_time)
                    stage.move_items()
                    stage.space.step(self.step_size)
                else:
                    for stage2 in self.stages:
                        stage2.set_end_time()
                    if self.virtual_stage != None:
                        self.sem.acquire()
                        self.virtual_stage.set_end_time()
                        self.sem.release()
                    if(self.loser == None):
                        self.loser = stage.player
                    self.game_finished = True
                stage.draw_self()
                    
            if self.virtual_stage != None:
                self.sem.acquire()
                if self.virtual_stage.running == False:
                    print "other player has LOST"
                    self.stages[0].set_end_time()
                    self.virtual_stage.set_end_time()
                    if(self.loser == None):
                        self.loser = self.virtual_stage.player
                    self.game_finished = True
                self.virtual_stage.draw_self()
                self.sem.release()           
                        
            # send network update every two seconds
            

            pygame.display.flip()
            self.clock.tick(1/self.step_size)    
        
        stats = [] # list of stat dictionaries for each player
        for stage in self.stages:
            player_stats = {}
            player_stats['player'] = stage.player
            player_stats['points'] = stage.point_total
            player_stats['purchases_made'] = stage.purchases_made
            player_stats['time_elapsed'] = stage.end_time - stage.start_time
            if(self.loser == stage.player):
                player_stats['won_game'] = False
            else:
                player_stats['won_game'] = True 
            stats.append(player_stats)
        # ADD: virtual stats
        
        if self.game_finished == True:
            self.screen.blit(self.gameover, (0, 0))
            #display who won and how many seconds it was
            # Create a font
            verdana = pygame.font.match_font('Verdana')
            font = pygame.font.Font(verdana, 32)
            
            # Render the text
            if len(self.players) == 1 and self.get_data == None: #message for single player
                message = "You survived " + str(int(self.stages[0].end_time-self.stages[0].start_time)) + " seconds!"
            elif len(self.players) == 2 and self.get_data == None: #local multi
                #find the name of the winner
                winner = None
                for stage in self.stages:
                    if self.loser != stage.player:
                        winner = stage
                message = winner.player.name + " won in " + str(int(winner.end_time-winner.start_time)) + " seconds!"
            elif self.networked_game:
                winner = None
                if self.loser == self.stages[0].player:
                    winner = self.virtual_stage
                else:
                    winner = self.stages[0]
                message = winner.player.name + " won in " + str(int(winner.end_time-winner.start_time)) + " seconds!"
                
            text = font.render(message, True, (255,255, 255))
            
            # Create a rectangle
            textRect = text.get_rect()
            
            # Center the rectangle
            textRect.centerx = self.screen.get_rect().centerx
            textRect.centery = 700
            
            # Blit the text
            self.screen.blit(text, textRect)
            pygame.display.flip()
            
            self.lose.play()
            time.sleep(5)
            return stats            

    def update_spawn_rate(self):
        if self.spawn_rate - self.spawn_rate_step >= 0.5:
            self.spawn_rate -= self.spawn_rate_step
            
    def parse_data(self,data_list):
        # we also need dict to tell both players to start game, and one to signal to the other that they lost
        if self.y_pos == None or self.opponent_name == None:
            for dict in data_list:
                for k,v in dict.iteritems():
                    if k == "y_pos":
                        self.y_pos = v
                    elif k == "player_name":
                        self.opponent_name = v
        else:
            self.sem.acquire()
            if self.virtual_stage != None:        
                self.virtual_stage.ball_prop = data_list[0]              
                self.virtual_stage.bullet_prop = data_list[1]
                self.virtual_stage.swing_prop = data_list[2]
                self.virtual_stage.cannon_prop = data_list[3]
                self.virtual_stage.spinner_prop = data_list[4]
                self.virtual_stage.gun_prop = []
                for i in range(5,8):
                    self.virtual_stage.gun_prop.append(data_list[i])
                self.virtual_stage.point_total = int(data_list[8])
                self.virtual_stage.gun_bullets_curr = int(data_list[9])
                self.virtual_stage.running = data_list[10]
                if self.virtual_stage.running == False:
                    print "IT IS NOW FALSE OMG"
            
            self.sem.release()