class Replay(MainScreen): def __init__(self, display, list_of_turns, size): MainScreen.__init__(self, display) self.list_of_turns = list_of_turns self.current_step = 0 self.go_board = Board(size) self.size = size self.btn_prev = Button(lang.data["prev"], [150, 70], [700, 300]) self.btn_next = Button(lang.data["next"], [150, 70], [700, 400]) def update_screen(self): self.go_board.draw(self.display) self.btn_prev.draw(self.display) self.btn_next.draw(self.display) if self.btn_next.active: if self.current_step < len(self.list_of_turns) - 1: self.make_step_forward() self.btn_next.active = False if self.btn_prev.active: if self.current_step > 0: self.make_step_back() self.btn_prev.active = False def make_step_forward(self): coord = self.list_of_turns[self.current_step] self.go_board.make_step(coord) self.current_step += 1 def make_step_back(self): self.current_step -= 1 self.go_board.__init__(self.size) for step in range(self.current_step): coord = self.list_of_turns[step] self.go_board.make_step(coord)
class AboutProgram(MainScreen): def __init__(self, display): MainScreen.__init__(self, display) self.btn_main_menu = Button(lang.data["main menu"], [240, 50], [340, 480], 38) def update_screen(self): font = pygame.font.Font(None, 52) mdl_font = pygame.font.Font(None, 40) sm_font = pygame.font.SysFont('arial', 25) text = font.render(lang.data["about program"], 1, color['green']) lb = text.get_rect(center=(450, 50)) self.display.blit(text, lb) text = mdl_font.render(lang.data["go"], 1, color['black']) lb = text.get_rect(center=(450, 150)) self.display.blit(text, lb) text = sm_font.render("0.1.0", 1, color['black']) lb = text.get_rect(center=(450, 200)) self.display.blit(text, lb) text = sm_font.render(lang.data["popular Japanese game"], 1, color['black']) lb = text.get_rect(center=(450, 250)) self.display.blit(text, lb) text = sm_font.render(lang.data["developer"], 1, color['black']) lb = text.get_rect(center=(450, 320)) self.display.blit(text, lb) text = sm_font.render(lang.data["copyright"], 1, color['black']) lb = text.get_rect(center=(450, 370)) self.display.blit(text, lb) self.btn_main_menu.draw(self.display) if self.btn_main_menu.active: self.show = False
class Rools(MainScreen): def __init__(self, display): MainScreen.__init__(self, display) self.btn_main_menu = Button(lang.data["main menu"], [ 240, 50], [340, 530], 38) self.slider = Slider() image_rool = pygame.image.load(os.path.join('images/rools.png')) self.image_rool = pygame.transform.scale( image_rool, (800, image_rool.get_height() * 800 // image_rool.get_width())) def update_screen(self): image = pygame.transform.chop( self.image_rool, (0, 0, 0, (self.slider.value / 100) * (self.image_rool.get_height() - 500))) image = pygame.transform.chop( image, (0, 500, 0, image.get_height() - 500)) self.display.blit(image, (20, 20)) self.btn_main_menu.draw(self.display) self.slider.draw(self.display) if self.btn_main_menu.active: self.show = False
class MainMenu: def __init__(self, display): self.display = display self.btn_start = Button(lang.data["start"], [220, 70], [340, 150]) self.btn_settings = Button(lang.data["settings"], [220, 70], [340, 250]) self.btn_exit = Button(lang.data["exit"], [220, 70], [340, 350]) def update_screen(self): for event in pygame.event.get(): if event.type == pygame.QUIT: exit(self.display) self.display.fill(color['white']) self.btn_start.draw(self.display) self.btn_settings.draw(self.display) self.btn_exit.draw(self.display) if self.btn_start.active: choose_size_of_board = ChooseGameMode(self.display) choose_size_of_board.run() del choose_size_of_board self.btn_start.active = False elif self.btn_settings.active: settings = Settings(self.display) settings.run() del settings self.btn_settings.active = False elif self.btn_exit.active: exit(self.display) self.btn_exit.active = False def run(self): while True: self.update_screen() pygame.display.update() clock.tick(FPS)
class Settings(MainScreen): def __init__(self, display): MainScreen.__init__(self, display) self.btn_about_program = Button(lang.data["program"], [240, 50], [340, 270], 38) self.btn_rools = Button(lang.data["rools"], [240, 50], [340, 340], 38) self.btn_main_menu = Button(lang.data["main menu"], [240, 50], [340, 410], 38) self.tgl_music = Toggle([250, 130]) self.tgl_sound = Toggle([650, 130]) self.tgl_language = Toggle([420, 200]) if lang.current_language == 'russian': self.tgl_language.active = True if sound: self.tgl_sound.active = True def update_screen(self): font = pygame.font.Font(None, 44) self.btn_about_program.draw(self.display) self.btn_rools.draw(self.display) self.btn_main_menu.draw(self.display) self.tgl_music.draw(self.display) self.tgl_sound.draw(self.display) self.tgl_language.draw(self.display) text_music = font.render(lang.data["music"], 1, color['black']) text_sound = font.render(lang.data["sound"], 1, color['black']) text_russian = font.render("Русский", 1, color['black']) text_english = font.render("English", 1, color['black']) lbmusic = text_music.get_rect(center=(280, 100)) lbsound = text_sound.get_rect(center=(680, 100)) lbrussian = text_russian.get_rect(center=(590, 210)) lbenglish = text_russian.get_rect(center=(310, 210)) self.display.blit(text_music, lbmusic) self.display.blit(text_sound, lbsound) self.display.blit(text_russian, lbrussian) self.display.blit(text_english, lbenglish) if self.btn_main_menu.active: self.show = False elif self.btn_rools.active: rools = Rools(self.display) rools.run() del rools self.btn_rools.active = False elif self.btn_about_program.active: about_program = AboutProgram(self.display) about_program.run() del about_program self.btn_about_program.active = False if self.tgl_language.active and lang.current_language != 'russian': lang.change_language('russian') if not self.tgl_language.active and lang.current_language != 'english': lang.change_language('english') global sound if self.tgl_sound.active: sound = True else: sound = False
class ChooseGameMode(MainScreen): def __init__(self, display): MainScreen.__init__(self, display) self.btn_sizes = [] self.btn_play_with_friend = Button(lang.data['play with friend'], [400, 100], [250, 160]) self.btn_play_online = Button(lang.data['play online'], [400, 100], [250, 290]) self.btn_watch_gotv = Button(lang.data['Go TV'], [400, 100], [250, 420]) def update_screen(self): font = pygame.font.Font(None, 72) text = font.render(lang.data["choose game mode"], 1, color['green']) lb = text.get_rect(center=(450, 50)) self.display.blit(text, lb) self.btn_play_with_friend.draw(self.display) self.btn_play_online.draw(self.display) self.btn_watch_gotv.draw(self.display) if self.btn_play_with_friend.active: self.btn_play_with_friend.active = False choose_size_of_board = ChooseSizeOfBoard(self.display, 'friend') choose_size_of_board.run() self.show = False del choose_size_of_board elif self.btn_play_online.active: self.btn_play_online.active = False choose_size_of_board = ChooseSizeOfBoard(self.display, 'online') choose_size_of_board.run() self.show = False del choose_size_of_board elif self.btn_watch_gotv.active: watch_gotv = WatchGoTV(self.display) watch_gotv.run() self.show = False del watch_gotv
class Game(MainScreen): def __init__(self, display, size_of_board): MainScreen.__init__(self, display) self.go_board = Board(size_of_board) self.btn_pass = Button(lang.data["pass"], [170, 70], [690, 300]) self.btn_resign = Button(lang.data["resign"], [170, 70], [690, 425]) self.sound = pygame.mixer.Sound(os.path.join('sounds/gong.wav')) if sound: self.sound.play() def update_screen(self): for event in pygame.event.get(): if event.type == pygame.QUIT: exit(self.display) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: notification = Notification(self.display, lang.data["exit to menu"]) notification.run() if notification.action: self.show = False del notification elif event.type == pygame.MOUSEBUTTONUP: self.go_board.make_step() self.display.fill(color['white']) self.go_board.draw(self.display) self.btn_pass.draw(self.display) self.btn_resign.draw(self.display) if self.btn_pass.active: self.play = self.make_pass(self.display) self.btn_pass.active = False if self.btn_resign.active: self.go_board.list_of_turns.append(None) notification = Notification(self.display, lang.data["game over"]) notification.run() if notification.action: replay = Replay(self.display, self.go_board.list_of_turns, self.go_board.size) replay.run() del replay self.show = False del notification font = pygame.font.Font(None, 72) if self.go_board.turn: text = font.render(lang.data["black's turn"], 1, color['green']) else: text = font.render(lang.data["white's turn"], 1, color['green']) lbturn = text.get_rect(center=(400, 50)) self.display.blit(text, lbturn) def update_main_screen(self): self.update_screen() def make_pass(self, surface): self.go_board.turn = not self.go_board.turn try: if not self.go_board.list_of_turns[-1]: notification = Notification(surface, lang.data["game over"]) notification.run() if notification.action: replay = Replay(surface, self.go_board.list_of_turns, self.go_board.size) replay.run() del replay self.show = False del notification return False else: self.go_board.list_of_turns.append(None) except IndexError: self.go_board.list_of_turns.append(None) return True
class GameState: def __init__(self, owner, screen, player, inqueue, outqueue): # Knowledge about the outside world self.owner = owner self.screen = screen self.player = player self.inqueue = inqueue self.outqueue = outqueue # UI configuration self.size = self.width, self.height = self.screen.get_size() self.black = 0, 0, 0 self.yellow = 250, 215, 0 # Game status tracking self.start = False self.cards = [] self.selected = [] self.timestart = 0 # Special flags to allow for the powers to function self.matchallowed = True self.doneselecting = False self.skipturn = False # Set up the bonus timer self.maxbonus = 10000 self.bonusdurations = {1: 5000, 2: 5000} self.bonus = BonusTimer(5000,Rect(600,750,330,25)) # Set up the powers self.powers = [] self.powersallowed = True for i in xrange(12): self.powers.append(Power(self,i)) # Allow us to go back to the menu after a game self.menubutton = Button('Return to Menu',Rect(335,430,300,25),self.gotoMenu,fgcolor=self.yellow) # Network initialization self.inqueue.get().addCallback(self.gotMessage) # Let player 1 be authoritative on the ordering of the cards if self.player == 1: self.arrangeCards() #Basic Initializations self.firstCard = 0 #Stores number of cards that have been selected self.message = "P1 turn" #Whose turn is it? self.p1 = 0 #Score self.p2 = 0 #Score self.p1interp = TimedInterpolator() self.p2interp = TimedInterpolator() self.turn = 1 # Player whose turn it is self.turncount = 0 self.GameOver = False #Create labels self.myfont = pygame.font.SysFont("monospace",30) self.label = self.myfont.render("Memory",1,self.yellow) self.turnlabel = self.myfont.render(str(self.message),1,self.yellow) self.player1 = self.myfont.render("Player 1: "+str(self.p1),1,self.yellow) self.player2 = self.myfont.render("Player 2: "+str(self.p2),1,self.yellow) self.gameover = self.myfont.render("WAITING FOR PLAYER 2",3,self.yellow) self.winsurf = self.myfont.render('You Win!',True,self.yellow) self.tiesurf = self.myfont.render('It\'s a Tie!',True,self.yellow) self.losesurf = self.myfont.render('You Lose!',True,self.yellow) # Code for handling a message (probably from the other player, across # the network, but we don't really care either way). def gotMessage(self, msg): # All commands are text-based, with arguments and such seperated by single spaces cmd = msg.split(' ') try: if cmd[0] == 'connection_made': # Signal to start the game proper self.start = True if self.turn == self.player: self.bonus.reset() self.bonus.start() self.outqueue.put('turn ' + str(self.bonus.starttime)) elif cmd[0] == 'card_order': # Player 2 learning the answers if self.player == 1: print 'card ordering received from a player other than player 1' elif self.cards: print 'already have a card ordering' else: self.initializeCards(int(x) for x in cmd[1:25]) elif cmd[0] == 'turn': # Synchronize the bonus timers if self.turn == self.player: print 'turn message received on own turn' else: starttime = int(cmd[1]) self.bonus.reset(starttime=starttime) elif cmd[0] == 'select_card': # Let the other player know which card you picked if self.turn == self.player: print 'received card selection message on own turn' else: ticks = int(cmd[1]) self.bonus.update(time=ticks) i = int(cmd[2]) self.selectCard(i,notify=False) # All of the below are commands associated with powers; c.f. powers.py elif cmd[0] == 'fast_bonus': self.powers[Card.HORSE].activate(evil=True) elif cmd[0] == 'scramble_cards': self.powers[Card.MONKEY].activate(evil=True) elif cmd[0] == 'skip_turn': self.powers[Card.GORILLA].activate(evil=True) elif cmd[0] == 'extra_points': self.addPoints(1000) self.powers[Card.SQUIRREL].activate(evil=True) elif cmd[0] == 'disable_powers': self.powers[Card.BULL].activate(evil=True) elif cmd[0] == 'show_cards': self.powers[Card.BIRD].activate(evil=True) elif cmd[0] == 'erq_ureevat': self.powers[Card.FISH].activate(evil=True) elif cmd[0] == 'replenish_cards': # Reset (most) cards for card in self.cards: if card.value != Card.SPIDER: card.__init__(self,card.rect.x,card.rect.y,card.value) self.scrambleCards() # Also reset (most) powers for power in self.powers: if power.value != Card.SPIDER: power.setAvailable(False) elif cmd[0] == 'sniff': if not self.doneselecting and len(self.selected) == 1: for i, card in enumerate(self.cards): if card.value == self.selected[0].value and card is not self.selected[0]: self.selectCard(i) if self.turn != self.player: self.powers[Card.PIG].activate(evil=True) elif cmd[0] == 'replenish_card': value = int(cmd[1]) for card in filter(lambda c: c.value in (Card.ROOSTER, value),self.cards): card.__init__(self,card.rect.x,card.rect.y,card.value) self.scrambleCards() self.powers[Card.ROOSTER].activate(evil=True) elif cmd[0] == 'steal_points': if self.turn == 1: points = 0.1*self.p2 self.addPoints( points,player=1) self.addPoints(-points,player=2) else: points = 0.1*self.p1 self.addPoints(-points,player=1) self.addPoints( points,player=2) elif cmd[0] == 'slow_bonus': self.powers[Card.TURTLE].activate(evil=True) else: print 'unknown command: ' + cmd[0] except (IndexError, ValueError): print 'bad command received: ' + msg # Ask for the next one form our DeferredQueue self.inqueue.get().addCallback(self.gotMessage) # Calculate the n-th layout position for a card def cardPosition(self, n): topleft = 10, 100 hspacing = 160 vspacing = 160 ncols = 6 x = topleft[0] + n%ncols*hspacing y = topleft[1] + n/ncols*vspacing return x, y # Determine the official order of the cards for this game def arrangeCards(self): # Two of each of the twelve cards self.initializeCards(random.sample(list(n/2 for n in xrange(24)),24)) # Tell the other player self.outqueue.put('card_order ' + ' '.join(str(c.value) for c in self.cards)) # Don't change the in-memory order of the cards, only the on-screen arrangement def scrambleCards(self): order = iter(random.sample(range(24),24)) for card in self.cards: pos = self.cardPosition(next(order)) card.move(pos[0],pos[1]) # Actually construct and place the cards def initializeCards(self, ids): self.cards = [] # Card arrangement n = 0 for i in ids: pos = self.cardPosition(n) self.cards.append(Card(self,pos[0],pos[1],i)) n += 1 # As long as 2 cards have not already been selected, # and the card clicked is not already matched # or already selected, then flip it. def selectCard(self, i, notify=True): card = self.cards[i] if not self.doneselecting and not card.matched and not card.selected: card.select() self.selected.append(card) self.timestart = pygame.time.get_ticks() self.doneselecting |= len(self.selected) >= 2 if self.doneselecting: self.bonus.stop() # Tell the other player if notify: self.outqueue.put('select_card ' + str(self.bonus.curtime) + ' ' + str(i)) # Change the score of a player (the current player, by default) def addPoints(self, points, player=None): points = int(points) if player == 1 or self.turn == 1: self.p1interp.start(self.p1,self.p1 + points,2000) self.p1 += points else: self.p2interp.start(self.p2,self.p2 + points,2000) self.p2 += points # Adieu def gotoMenu(self): self.owner.stop(main_screen.MainScreen(self.screen)) # The main game logic, called sixty times a second (assuming Twisted is reliable) def gameLoop(self): if self.start: #If a player 2 is connected, then display main screen self.loop() else: #Otherwise display waiting screen self.waiting() def waiting(self): #Handle user inputs for event in pygame.event.get(): if event.type == pygame.QUIT: reactor.stop() self.screen.fill(self.black) #Display labels self.screen.blit(self.label,(430,30)) self.screen.blit(self.player1,(20,30)) self.screen.blit(self.player2,(750,30)) self.screen.blit(self.gameover,(300,400)) pygame.display.flip() def loop(self): # handle user inputs for event in pygame.event.get(): if event.type == pygame.QUIT: reactor.stop() elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # Check for clicks on game objects if self.turn == self.player: for i, card in enumerate(self.cards): if card.rect.collidepoint(pygame.mouse.get_pos()): self.selectCard(i) if not self.doneselecting and self.powersallowed: for power in self.powers: if power.rect.collidepoint(pygame.mouse.get_pos()): power.activate() if self.GameOver: self.menubutton.click(event.button,event.pos) #After 3 seconds, update score, switch turn and flip cards back over if self.doneselecting and pygame.time.get_ticks() - self.timestart > 3000: #The 2 cards are a match if self.matchallowed and self.selected[0].value == self.selected[1].value: for card in self.selected: card.matched = True card.selected = False # Activate the power if self.turn == self.player: self.powers[self.selected[0].value].setAvailable(True) # Update score self.addPoints(100 + int((1 - self.bonus.progress)*self.maxbonus)) else: #The 2 cards are not a match #Flip the cards back over for card in self.selected: card.startFlip() card.selected = False # Reset the selection for the next turn self.selected = [] self.matchallowed = True self.doneselecting = False #Change turns for _ in xrange(2 if self.skipturn else 1): self.bonusdurations[self.turn] = self.bonus.duration self.turn = 2 if self.turn == 1 else 1 self.turncount += 1 self.bonus.setDuration(self.bonusdurations[self.turn]) # Reset the bonus timer self.bonus.stop() self.bonus.reset() if self.turn == self.player: self.bonus.start() # Synchronize with the other player if self.turn == self.player: self.outqueue.put('turn ' + str(self.bonus.starttime)) # Update the on-screen message if self.turn == 1: self.message = "P1 turn" else: self.message = "P2 turn" # send a tick to every game object! for card in self.cards: card.tick() for power in self.powers: power.tick() self.bonus.tick() # Update the on-screen labels self.turnlabel = self.myfont.render(str(self.message),1,self.yellow) self.player1 = self.myfont.render("Player 1: "+str(self.p1interp.current()),1,self.yellow) self.player2 = self.myfont.render("Player 2: "+str(self.p2interp.current()),1,self.yellow) #Make screen black self.screen.fill(self.black) #display cards for card in self.cards: card.draw(self.screen) # Draw the power icons for power in self.powers: power.draw(self.screen) # Draw the bonus timer self.bonus.draw(self.screen) #display labels self.screen.blit(self.label,(430,30)) self.screen.blit(self.player1,(20,30)) self.screen.blit(self.player2,(950 - self.player2.get_width(),30)) self.screen.blit(self.turnlabel,(430,750)) # Check for the endgame condition -- all cards matched self.GameOver = bool(self.cards) for card in self.cards: if card.matched is False: self.GameOver = False # If game over, display a message if self.GameOver: if self.p1 == self.p2: self.screen.blit(self.tiesurf,(400, 400)) elif (self.p1 > self.p2) == (self.player == 1): self.screen.blit(self.winsurf,(400, 400)) else: self.screen.blit(self.losesurf,(400, 400)) self.menubutton.draw(self.screen) pygame.display.flip()
class Game(object): print "Setting global Game params." # Game parameters BG_TILE_IMG = 'images/wood2.png' BUTTON_BGIMG = 'images/x.png' SCREEN_WIDTH, SCREEN_HEIGHT = 580, 500 GRID_SIZE = 20 FIELD_SIZE = 400, 400 #need to implement resource loading here #global game constants make cheating easy! def __init__(self): pygame.init() print "Pygame started." #set up screen and background self.screen = pygame.display.set_mode( (self.SCREEN_WIDTH, self.SCREEN_HEIGHT), 0, 32) self.tile_img = pygame.image.load(self.BG_TILE_IMG).convert_alpha() self.tile_img_rect = self.tile_img.get_rect() #Drawing a handy MessageBoard widget #Can use these for any text. print "Configuring tboard MessageBoard params." self.tboard_text = ['This is a test.'] self.tboard_x = 120 self.tboard_y = 120 self.tboard_width = 125 self.tboard_height = 30 self.tboard_rect = Rect(self.tboard_x, self.tboard_y, self.tboard_width, self.tboard_height) self.tboard_bgcolor = Color(50, 20, 0) self.tboard = MessageBoard(self.screen, rect=self.tboard_rect, bgcolor=self.tboard_bgcolor, border_width=4, border_color=Color('black'), text=self.tboard_text, padding=5, font=('comic sans', 18), font_color=Color('yellow')) print "Moving on to buttons..." self.button_bgimgs = ['images/x.png'] #self.button_width = self.button_bgimgs[0].get_width() #self.button_height = self.button_bgimgs[0].get_height() #hopefully this will draw the button -15 pixels from the right end, +15 from the top #(hopefully giving us a nice X) # should be replaced in the future with a method that returns the coords for an x button # in whatever corner we want. #self.button_rect = Rect(self.tboard_width, self.tboard_y-15, self.button_width, self.button_height) self.button = Button(self.screen, pos=vec2d(self.tboard_width, self.tboard_y-15), btntype='Close', imgnames=self.button_bgimgs, attached=self.tboard) print "Created close button." #setting up our toggle button self.togglebtn_bgimgs = ['images/toggle1.png', 'images/toggle2.png'] self.togglebtn = Button(self.screen, pos=vec2d(250, 250), btntype='Toggle', imgnames=self.togglebtn_bgimgs, attached="") print "Created toggle button." self.buttons = [self.button, self.togglebtn] self.clock = pygame.time.Clock() self.paused = False #spawning entities #Setting up gamefield #need a method for dynamically figuring out how many rows/columns we need based on #the spacing we want and field size. Using some constants for now. self.grid_nrows = 30 self.grid_ncols = 30 self.field_rect = Rect(0, 0, self.SCREEN_WIDTH, self.SCREEN_HEIGHT) self.options = dict(debug=True, draw_grid=False) print "Done setting game options, exiting Game init." def xy2coord(self, pos): """ Convert a (x, y) pair to a (nrow, ncol) coordinate """ x, y = (pos[0] - self.field_rect.left, pos[1] - self.field_rect.top) return (int(y) / self.GRID_SIZE, int(x) / self.GRID_SIZE) def coord2xy_mid(self, coord): """ Convert a (nrow, ncol) coordinate to a (x, y) pair, where x,y is the middle of the square at the coord """ nrow, ncol = coord return ( self.field_rect.left + ncol * self.GRID_SIZE + self.GRID_SIZE / 2, self.field_rect.top + nrow * self.GRID_SIZE + self.GRID_SIZE / 2) def get_field_rect(self): """ Return the internal field rect - the rect of the game field exluding its border. """ return self.field_box.get_internal_rect() def draw_background(self): img_rect = self.tile_img.get_rect() nrows = int(self.screen.get_height() / img_rect.height) + 1 ncols = int(self.screen.get_width() / img_rect.width) + 1 for y in range(nrows): for x in range(ncols): img_rect.topleft = (x * img_rect.width, y * img_rect.height) self.screen.blit(self.tile_img, img_rect) def draw_grid(self): for y in range(self.grid_nrows + 1): pygame.draw.line( self.screen, Color(50, 50, 50), (self.field_rect.left, self.field_rect.top + y * self.GRID_SIZE - 1), (self.field_rect.right - 1, self.field_rect.top + y * self.GRID_SIZE - 1)) for x in range(self.grid_ncols + 1): pygame.draw.line( self.screen, Color(50, 50, 50), (self.field_rect.left + x * self.GRID_SIZE - 1, self.field_rect.top), (self.field_rect.left + x * self.GRID_SIZE - 1, self.field_rect.bottom - 1)) def draw(self): #draw background image self.draw_background() #draw game field crap here #decide if we should draw grid. if self.options['draw_grid']: self.draw_grid() #Only stuff being drawn right now. #Message board with x button self.tboard.draw() if self.button.is_visible(): self.button.draw() if self.togglebtn.is_visible(): self.togglebtn.draw() #this way we can draw dynamic MessageBoards. #self.mboard.text = self.mboard_text <-- copy in latest text #self.mboard.draw() #other entity draw calls def run(self): print "Beginning run sequence." # The main game loop # while True: # Limit frame speed to 30 FPS # time_passed = self.clock.tick(30) #~ time_passed = self.clock.tick() #~ print time_passed # If too long has passed between two frames, don't # update (the game must have been suspended for some # reason, and we don't want it to "jump forward" # suddenly) # if time_passed > 100: continue #Event loop. In-game control is routed through here #Will probably need something more robust soon. for event in pygame.event.get(): if event.type == pygame.QUIT: self.quit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.paused = not self.paused elif event.key == pygame.K_g: #toggle draw grid self.options['draw_grid'] = not self.options['draw_grid'] elif (event.type == pygame.MOUSEBUTTONDOWN and event.button == 1): for button in self.buttons: button.mouse_click_event(event.pos) pass #entity events here. #update hud, counters, score, anything like that here if not self.paused: msg1 = '' msg2 = '' #update stats counters. Not doing anything yet self.mboard_text = [msg1, msg2] #update entities with time passed for internal calculations self.draw() #actually flip Surface buffer pygame.display.flip() def quit(self): sys.exit()
class OnlineGame(MainScreen): def __init__(self, display, size_of_board, side, client): MainScreen.__init__(self, display) self.side = side self.client = client self.go_board = Board(size_of_board) self.btn_pass = Button(lang.data["pass"], [150, 70], [700, 300]) self.btn_resign = Button(lang.data["resign"], [150, 70], [700, 425]) self.show_err_msg = False self.request_for_pass = False def update_screen(self): if self.show_err_msg: message_box = MessageBox( self.display, lang.data["lost connection"]) message_box.run() del message_box self.show = False for event in pygame.event.get(): if event.type == pygame.QUIT: exit(self.display) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: notification = Notification( self.display, lang.data["exit to menu"]) notification.run() if notification.action: self.show = False del notification elif event.type == pygame.MOUSEBUTTONUP and self.side == self.go_board.turn: temp = len(self.go_board.list_of_turns) self.go_board.make_step() if temp != len(self.go_board.list_of_turns): self.client.client_socket.send( pickle.dumps(self.go_board.list_of_turns[-1])) self.display.fill(color['white']) self.go_board.draw(self.display) self.btn_pass.draw(self.display) self.btn_resign.draw(self.display) if self.btn_pass.active or self.request_for_pass: self.play = self.make_pass(self.display) self.btn_pass.active = False self.request_for_pass = False if self.btn_resign.active: self.go_board.list_of_turns.append(None) self.client.client_socket.send(pickle.dumps(-1)) notification = Notification( self.display, lang.data["game over"]) notification.run() if notification.action: replay = Replay( self.display, self.go_board.list_of_turns, self.go_board.size) replay.run() del replay self.show = False del notification font = pygame.font.Font(None, 72) if self.go_board.turn ^ self.side: text = font.render(lang.data["their turn"], 1, color['green']) else: text = font.render(lang.data["your turn"], 1, color['green']) lbturn = text.get_rect(center=(400, 50)) self.display.blit(text, lbturn) def run_screen(self): while self.show: self.update_screen() pygame.display.update() clock.tick(FPS) def run_client(self): try: while True: data = self.client.client_socket.recv(1024) if data == b'exit': raise EOFError if data == b"Get turns": self.client.client_socket.send(pickle.dumps( (self.go_board.size, self.go_board.list_of_turns))) else: if self.side != self.go_board.turn: data = pickle.loads(data) if not data: self.request_for_pass = True elif data == -1: self.btn_resign.active = True else: self.go_board.make_step(data) except EOFError: self.show_err_msg = True def run(self): thr_screen = threading.Thread(target=self.run_screen) thr_client = threading.Thread(target=self.run_client, daemon=True) thr_screen.start() thr_client.start() thr_screen.join() def make_pass(self, surface): if self.side == self.go_board.turn or self.request_for_pass: self.go_board.turn = not self.go_board.turn try: if not self.go_board.list_of_turns[-1]: self.client.client_socket.send(pickle.dumps(None)) notification = Notification( surface, lang.data["game over"]) notification.run() if notification.action: replay = Replay( surface, self.go_board.list_of_turns, self.go_board.size) replay.run() del replay self.show = False del notification return False else: self.go_board.list_of_turns.append(None) if not self.request_for_pass: self.client.client_socket.send(pickle.dumps(None)) except IndexError: self.go_board.list_of_turns.append(None) if not self.request_for_pass: self.client.client_socket.send(pickle.dumps(None)) return True