def __init__(self, parent, cb_video, cb_controller, cb_connect, cb_stop): super().__init__(pygame.Rect(common.width - 148, 0, 148, parent.get_bounds().height - 10), parent) Button(8, 5, 132, 20, 'open video stream', self, common.font_14, cb_video) Button(8, 27, 132, 20, 'connect controller', self, common.font_14, cb_controller) Button(8, 49, 132, 20, 'connect to robot', self, common.font_14, cb_connect) Button(8, 71, 132, 20, 'emergency stop', self, common.font_14, cb_stop)
def __init__(self, width, height, label, parent): super().__init__(common.width // 2 - width // 2, common.height // 2 - height // 2, width, height, '', parent) self.text_input = TextInput(width // 2 - 200 // 2, height // 2 - 25 // 2, 200, 25, parent=self) _add_object(self.text_input) self.submit_button = Button(0, 0, 0, 0, 'submit', self, common.font_14, self.parent.submit) self.submit_button.set_size(self.submit_button.get_size()[0] + 10, self.submit_button.get_size()[1] + 4) self.submit_button.set_local_pos(self.text_input.get_local_pos()[0] + self.text_input.get_size()[0] - self.submit_button.get_size()[0], self.text_input.get_local_pos()[1] + self.submit_button.get_size()[1] + 6) _add_object(self.submit_button) self.label = label
def __init__(self, parent, cb_change_speed): super().__init__(pygame.Rect(common.width - 148 - 126 - 126, 0, 126, parent.get_bounds().height - 10), parent) self.callback = cb_change_speed self.input = TextInput(8, 27, 110, 20, self, True) self.input.text = '0' Button(8, 49, 110, 20, 'submit', self, common.font_14, self.change_speed)
def __init__(self, parent, cb_record, cb_stop, cb_follow, cb_home): super().__init__(pygame.Rect(common.width - 148 - 126, 0, 126, parent.get_bounds().height - 10), parent) self.record_button = Button(8, 5, 110, 20, 'start recording', self, common.font_14, cb_record) self.stop_button = Button(8, 27, 110, 20, 'stop recording', self, common.font_14, cb_stop) self.follow_button = Button(8, 49, 110, 20, 'follow path', self, common.font_14, cb_follow) self.home_button = Button(8, 71, 110, 20, 'return home', self, common.font_14, cb_home) self.record_button.set_enabled(True) self.stop_button.set_enabled(False) self.follow_button.set_enabled(False) self.home_button.set_enabled(False)
class PopupForeground(Panel, Clickable): def __init__(self, width, height, label, parent): super().__init__(common.width // 2 - width // 2, common.height // 2 - height // 2, width, height, '', parent) self.text_input = TextInput(width // 2 - 200 // 2, height // 2 - 25 // 2, 200, 25, parent=self) _add_object(self.text_input) self.submit_button = Button(0, 0, 0, 0, 'submit', self, common.font_14, self.parent.submit) self.submit_button.set_size(self.submit_button.get_size()[0] + 10, self.submit_button.get_size()[1] + 4) self.submit_button.set_local_pos(self.text_input.get_local_pos()[0] + self.text_input.get_size()[0] - self.submit_button.get_size()[0], self.text_input.get_local_pos()[1] + self.submit_button.get_size()[1] + 6) _add_object(self.submit_button) self.label = label def on_click(self): self.draw() def draw(self): r = pygame.Rect(self.get_bounds().x + 1, self.get_bounds().y + 1, self.get_bounds().width, self.get_bounds().height) pygame.draw.rect(common.screen, common.color_bg_dark, r) pygame.draw.rect(common.screen, common.color_bg_main, self.get_bounds()) pygame.draw.rect(common.screen, common.color_bg_dark, self.get_bounds(), 1) s = common.font_16.size(self.label) write(self.label, self.text_input.get_pos()[0], self.text_input.get_pos()[1] - s[1] - 2, self.colors[2], self.colors[0], common.font_16) Transform.draw(self)
class PathControls(Transform): def __init__(self, parent, cb_record, cb_stop, cb_follow, cb_home): super().__init__(pygame.Rect(common.width - 148 - 126, 0, 126, parent.get_bounds().height - 10), parent) self.record_button = Button(8, 5, 110, 20, 'start recording', self, common.font_14, cb_record) self.stop_button = Button(8, 27, 110, 20, 'stop recording', self, common.font_14, cb_stop) self.follow_button = Button(8, 49, 110, 20, 'follow path', self, common.font_14, cb_follow) self.home_button = Button(8, 71, 110, 20, 'return home', self, common.font_14, cb_home) self.record_button.set_enabled(True) self.stop_button.set_enabled(False) self.follow_button.set_enabled(False) self.home_button.set_enabled(False) def draw(self): x = self.get_pos()[0] pygame.draw.line(common.screen, common.color_bg_dark, (x, 10), (x, 65), 1) pygame.draw.line(common.screen, common.color_bg_light, (x+1, 10), (x+1, 65), 1) Transform.draw(self)
class Window(pyglet.window.Window): """This class renders the game data within a pyglet window.""" def __init__(self, my_controller, size): super(Window, self).__init__(700, 700, fullscreen=False, caption='') # Link the view to the controller self.controller = my_controller # Gamplay information passed by the controller self.data = { 'size' : size, 'stones' : [[None for x in range(size)] for y in range(size)], 'territory': [[None for x in range(size)] for y in range(size)], 'color' : None, 'game_over': False, 'score' : [0, 20] } # Set default background color pyglet.gl.glClearColor(0.5,0.5,0.5,1) # Load background image and stones self.image_background = BACKGROUND self.image_black_stone = BLACK_STONE self.image_white_stone = WHITE_STONE # Center black and white stones self.init_resources() # Initialize the display self.init_display() def init_resources(self): """Center black and white stones for proper visualization Attributes updated by this function: self.image_black_stone self.image_white_stone """ def center_image(image): """Set an image's anchor point to its center Arguments: image (pyglet.resource.image) - image to center Attributes updated by this function: image """ image.anchor_x = image.width/2 image.anchor_y = image.height/2 center_image(self.image_black_stone) center_image(self.image_white_stone) def init_display(self): """Gather all graphical elements together and draw them simutaneously. Attributes updated by this function: self.batch self.grp_back self.grp_grid self.grp_label self.grp_stones self.grp_territory self.background self.grid self.info self.score_black self.black_label_stone self.score_white self.white_label_stone self.player_color self.current_player_stone self.button_pass self.button_newgame """ # Creating a batch to display all graphics self.batch = pyglet.graphics.Batch() # Graphic groups (groups of lower index get drawn first) self.grp_back = pyglet.graphics.OrderedGroup(0) self.grp_grid = pyglet.graphics.OrderedGroup(1) self.grp_label = pyglet.graphics.OrderedGroup(2) self.grp_stones = pyglet.graphics.OrderedGroup(3) self.grp_territory = pyglet.graphics.OrderedGroup(4) # Initially load all graphic groups. self.init_back() self.init_grid() self.init_label() def init_back(self): """Load the background. Attributes updated by this function: self.background """ # Display background image self.background = Sprite(self.image_background, batch=self.batch, group=self.grp_back) def init_grid(self): """Load the grid. Attributes updated by this function: self.grid """ # Display grid self.grid = Grid(x=self.width/2, y=self.height/2, width=self.width*MAX_GRID_SIZE, height=self.height*MAX_GRID_SIZE, batch=self.batch, group=self.grp_grid, n=self.data['size']) def init_label(self): """Load all labels and buttons. Attributes updated by this function: self.info self.score_black self.black_label_stone self.score_white self.white_label_stone self.player_color self.current_player_stone self.button_pass self.button_newgame """ # Game Information Display label_y = 670 # y position of scores and next turn labels label_font_size = 12 label_text_color = (0, 0, 0, 255) # Controller-Info Panel # The Text of this label is directly changed inside the controller self.info = Label(x=10, y=10, text="Let's start!", color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) # Score-Label Label(x=10, y=label_y, text='Score:', color=label_text_color, font_size=label_font_size, bold=True, batch=self.batch, group=self.grp_label) # SCORES BLACK PLAYER self.score_black = Label(x=100, y=label_y, text=str(self.data['score'][1]), color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) self.black_label_stone = Sprite(self.image_black_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.black_label_stone.scale = LITTLE_STONE_SIZE self.black_label_stone.set_position(80, label_y + self.black_label_stone.height/4) # SCORES WHITE PLAYER self.score_white = Label(x=170, y=label_y, text=str(self.data['score'][0]), color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) self.white_label_stone = Sprite(self.image_white_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.white_label_stone.scale = LITTLE_STONE_SIZE self.white_label_stone.set_position(150, label_y + self.white_label_stone.height/4) # CURRENT PLAYER STONE self.player_color = Label(x=550, y=label_y, text="Your color: ", color=label_text_color, font_size=label_font_size, bold=True, batch=self.batch, group=self.grp_label) # INITIAL PLAYER STONE self.current_player_stone = Sprite(self.image_black_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.current_player_stone.scale = LITTLE_STONE_SIZE self.current_player_stone.set_position(660, label_y + self.current_player_stone.height/4) # Game Buttons # Button that can be pressed to pass on current round self.button_pass = Button(pos=(600,40), text='Pass', batch=self.batch) # New-Game Button self.button_newgame = Button(pos=(480,40), text='New Game') def update(self, *args): """This function does all the calculations when the data gets updated. For other games that require permanent simulations you would add the following line of code at the end of __init__(): pyglet.clock.schedule_interval(self.update, 1/30) Attributes updated by this function: self.batch_stones self.stone_sprites self.image_black_stone self.image_white_stone self.batch_territory self.score_black self.score_white self.current_player_stone """ # Game Information Updates # Scores of each player self.update_stones() self.update_territories() self.update_scores() self.update_current_player() # If the new size in the data is different than the current size if self.data['size'] != self.grid.size: self.init_display() def update_stones(self): """Update the black and white stones on the game board. Attributes updated by this function: self.batch_stones self.stone_sprites self.image_black_stone self.image_white_stone """ # Display the stones on the regular batch self.batch_stones = self.batch self.stone_sprites = [] # Center black and white stones def center_image(image): """Sets an image's anchor point to its center""" image.anchor_x = image.width/2 image.anchor_y = image.height/2 center_image(self.image_black_stone) center_image(self.image_white_stone) # Place all stones on the grid # Scale stone images scaling = self.grid.field_width / self.image_black_stone.width # Limit max size of stones if scaling > MAX_STONE_SCALING: scaling = MAX_STONE_SCALING # Iterate trough all data stones and place the corresponding black or # white stone on the grid for i in range(0, self.data['size']): for j in range(0, self.data['size']): if self.data['stones'][j][i] != None: # Get x and y grid coordinates x_coord, y_coord = self.grid.get_coords(i, j) # Get the stone color to place stone_color = self.image_black_stone if self.data['stones'][j][i] == BLACK else None stone_color = self.image_white_stone if self.data['stones'][j][i] == WHITE else stone_color # Place the stone on the grid if stone_color: _s = Sprite(stone_color, batch=self.batch_stones, group=self.grp_stones, x=x_coord, y=y_coord) _s.scale = scaling self.stone_sprites.append(_s) def update_territories(self): """Update the black and white territories on the board. Attributes updated by this function: self.batch_territory """ # Display the territory an the regular batch # Display the stones on the regular batch self.batch_territory = self.batch rad = 5 # Iterate trough all territory indicators and place the corresponding # black or white circle on the grid or above stones for i in range(0, self.data['size']): for j in range(0, self.data['size']): if self.data['territory'][j][i] != None: x_coord, y_coord = self.grid.get_coords(i, j) if self.data['territory'][j][i] == BLACK: Circle(x_coord, y_coord, color=BLACK_TERRITORY, r=rad, batch=self.batch_territory, group=self.grp_territory) elif self.data['territory'][j][i] == WHITE: Circle(x_coord, y_coord, color=WHITE_TERRITORY, r=rad, batch=self.batch_territory, group=self.grp_territory) def update_scores(self): """Update scores for BLACK and WHITE. Attributes updated by this function: self.score_black self.score_white """ self.score_black.text = str(self.data['score'][1]) self.score_white.text = str(self.data['score'][0]) def update_current_player(self): """Update stone of current player. Attributes updated by this function: self.current_player_stone """ # Remve the last current player stone self.current_player_stone.delete() # If its the BLACK players turn if self.data['color']: self.current_player_stone = Sprite(self.image_black_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.current_player_stone.scale = LITTLE_STONE_SIZE self.current_player_stone.set_position(660, 670 + self.current_player_stone.height/4) # If its the WHITE players turn else: self.current_player_stone = Sprite(self.image_white_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.current_player_stone.scale = LITTLE_STONE_SIZE self.current_player_stone.set_position(660, 670 + self.current_player_stone.height/4) def on_draw(self): """Draw the interface. Attributes updated by this function: self self.batch self.button_newgame """ # Clear out old graphics self.clear() # Drawing the batch (which does not contain any graphics yet) self.batch.draw() # Check if Game is over, if True, draw the New Game Button if(self.data['game_over']): self.button_newgame.draw() def on_mouse_press(self, mousex, mousey, button, modifiers): """Function called on any mouse button press. Arguments: mousex : x-coord of the click mousey : y-coord of the click button : modifiers : The buttons are saved as constants in pyglet.window.mouse, the modifiers under pyglet.window.key E.g. >>> if button == pyglet.window.mouse.LEFT: pass Look at the documentation for more information: >>> import pyglet >>> help(pyglet.window.mouse) """ # Check for clicks on New Game Button only when game is Over if(self.data['game_over']): if (mousex, mousey) in self.button_newgame: self.controller.new_game() if button == pyglet.window.mouse.LEFT: # Mark territory if the game is over pos = self.grid.get_indices(mousex, mousey) if pos != None: self.controller.mark_territory(pos) # Handle clicks during game # Check if pass-button was pressed if (mousex, mousey) in self.button_pass: self.controller.passing() # Grid position clicked (only if above buttons) elif button == pyglet.window.mouse.LEFT and mousey > 60: # Place a stone at clicked position pos = self.grid.get_indices(mousex, mousey) if pos != None: self.controller.play(pos) def on_key_press(self, symbol, modifiers): """Function that gets called on any key press (keyboard). Arguments: symbol : symbol that was pressed modifiers : modifiers (e.g. l-shift, r-shift, ctrl, ...) You can compare symbol/modifiers to the constants defined in pyglet.window.key: E.g. >>> if symbol == pyglet.window.key.A: pass For more information look on the help page: >>> import pyglet >>> help(pyglet.window.key) """ pass def receive_data(self, data): """Receive data from the controller and update view. Attributes updated by this function: self.data """ self.data.update(data) self.update() def new_game(self, data): """Receive data from the controller and start a new game. Attributes updated by this function: self.data """ # Initialize the display self.data.update(data) self.init_display() self.update()
def init_label(self): """Load all labels and buttons. Attributes updated by this function: self.info self.score_black self.black_label_stone self.score_white self.white_label_stone self.player_color self.current_player_stone self.button_pass self.button_newgame """ # Game Information Display label_y = 670 # y position of scores and next turn labels label_font_size = 12 label_text_color = (0, 0, 0, 255) # Controller-Info Panel # The Text of this label is directly changed inside the controller self.info = Label(x=10, y=10, text="Let's start!", color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) # Score-Label Label(x=10, y=label_y, text='Score:', color=label_text_color, font_size=label_font_size, bold=True, batch=self.batch, group=self.grp_label) # SCORES BLACK PLAYER self.score_black = Label(x=100, y=label_y, text=str(self.data['score'][1]), color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) self.black_label_stone = Sprite(self.image_black_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.black_label_stone.scale = LITTLE_STONE_SIZE self.black_label_stone.set_position(80, label_y + self.black_label_stone.height/4) # SCORES WHITE PLAYER self.score_white = Label(x=170, y=label_y, text=str(self.data['score'][0]), color=label_text_color, font_size=label_font_size, batch=self.batch, group=self.grp_label) self.white_label_stone = Sprite(self.image_white_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.white_label_stone.scale = LITTLE_STONE_SIZE self.white_label_stone.set_position(150, label_y + self.white_label_stone.height/4) # CURRENT PLAYER STONE self.player_color = Label(x=550, y=label_y, text="Your color: ", color=label_text_color, font_size=label_font_size, bold=True, batch=self.batch, group=self.grp_label) # INITIAL PLAYER STONE self.current_player_stone = Sprite(self.image_black_stone, batch=self.batch, group=self.grp_label, x=0, y=0) self.current_player_stone.scale = LITTLE_STONE_SIZE self.current_player_stone.set_position(660, label_y + self.current_player_stone.height/4) # Game Buttons # Button that can be pressed to pass on current round self.button_pass = Button(pos=(600,40), text='Pass', batch=self.batch) # New-Game Button self.button_newgame = Button(pos=(480,40), text='New Game')