def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=DYNAMIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] self.obj = shapes[0].shape.obj if getattr(self.obj, "clickable", True): self.obj.body.velocity = [0.0, 0.0] self.obj_grabbed = True self.obj_rel_pos = self.obj.position - m_pos self.obj_m_pos = m_pos if event.type == pygame.MOUSEBUTTONUP and event.button == 1 and self.obj_grabbed: self.obj_grabbed = False # Give velocity based on previous mouse positions. if self.position_length != 0: differences = sum( (x + 1) / self.position_length * (self.positions[ (self.position_index + x + 1) % self.TOTAL_POSITIONS] - self.positions[ (self.position_index + x) % self.TOTAL_POSITIONS]) for x in range(self.position_length - 1)) # Sum will return 0 if position length is 0 - we need to handle this. if isinstance(differences, int): differences = np.array([0, 0]) self.obj.body.velocity = [ self.VELOCITY_MULT * d for d in differences ] if event.type == pygame.MOUSEMOTION and self.obj_grabbed: self.obj_m_pos = screenspace_to_worldspace(event.pos)
def handleEvent(self, event): if event.type == pygame.KEYDOWN and event.key == pygame.K_p: # Toggle pause state. World.instance.paused = not World.instance.paused if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ DYNAMIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] for shape in shapes: if shape.shape.obj.key == "controlsPause": self._pressed = True if event.type == pygame.MOUSEBUTTONUP and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ DYNAMIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] for shape in shapes: if (shape.shape.obj.key == "controlsPause") & self._pressed: # Toggle pause state. World.instance.paused = not World.instance.paused self._pressed = False if len(shapes) == 0: self._pressed = False
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for shape in shapes: for team in range(len(self.names)): if shape.shape.obj.key.startswith(f"score{team+1}"): action = shape.shape.obj.key.split(str(team + 1))[1] if action == "Plus": self.team_scores[team] += 1 elif action == "Minus": if self.team_scores[team] > 0: self.team_scores[team] -= 1 else: raise ValueError(f"Unknown team action {action}") self.updateScoreText() if shape.shape.obj.key == "controlsReset": self._pressed = True if event.type == pygame.MOUSEBUTTONUP and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for shape in shapes: if (shape.shape.obj.key == "controlsReset") & self._pressed: self.reset() self._pressed = False if len(shapes) == 0: self._pressed = False
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for shape in shapes: for team in range(len(self.names)): if shape.shape.obj.key.startswith(f"score{team+1}"): action = shape.shape.obj.key.split(str(team + 1))[1] if action == "Plus": self.team_scores[team] += 1 elif action == "Minus": if self.team_scores[team] > 0: self.team_scores[team] -= 1 else: raise ValueError(f"Unknown team action {action}") self.updateScoreText() for index in range(self.BOTS_PER_TEAM): if team * self.BOTS_PER_TEAM + index < len( self.robots): if shape.shape.obj.key == f"UI-penalty-{team * self.BOTS_PER_TEAM + index}": self.finishPenalty(team * self.BOTS_PER_TEAM + index) if shape.shape.obj.key == "controlsReset": self._pressed = True if event.type == pygame.MOUSEMOTION: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for team in range(len(self.names)): for index in range(self.BOTS_PER_TEAM): for shape in shapes: if shape.shape.obj.key == f"UI-penalty-{team * self.BOTS_PER_TEAM + index}": shape.shape.obj.visual.fill = "penalty_ui_bg_hover" break else: key = f"UI-penalty-{team * self.BOTS_PER_TEAM + index}" if key in ScriptLoader.instance.object_map: ScriptLoader.instance.object_map[ key].visual.fill = "penalty_ui_bg" if event.type == pygame.MOUSEBUTTONUP and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for shape in shapes: if (shape.shape.obj.key == "controlsReset") & self._pressed: self.reset() self._pressed = False if len(shapes) == 0: self._pressed = False
def calculatePoints(self): relative_scale = ScreenObjectManager.instance.relativeScreenScale() new_size = [int(self.image.get_size()[0] * self.scale * relative_scale[0]), int(self.image.get_size()[1] * self.scale * relative_scale[1])] scaled = pygame.transform.scale(self.image, new_size) self.rotated = pygame.transform.rotate(scaled, self.rotation * 180 / np.pi) self.rotated.fill(self.fill, special_flags=pygame.BLEND_ADD) self.screen_location = utils.worldspace_to_screenspace(self.position) self.screen_size = self.rotated.get_size() if self.hAlignment == 'l': pass elif self.hAlignment == 'm': self.screen_location -= np.array([self.screen_size[0] / 2, 0.0]) elif self.hAlignment == 'r': self.screen_location -= np.array([self.screen_size[0], 0.0]) else: raise ValueError(f'hAlignment is incorrect: {self.hAlignment}') if self.vAlignment == 't': pass elif self.vAlignment == 'm': self.screen_location -= np.array([0.0, self.screen_size[1] / 2]) elif self.vAlignment == 'b': self.screen_location -= np.array([0.0, self.screen_size[1]]) else: raise ValueError(f'vAlignment is incorrect: {self.vAlignment}') from ev3sim.visual.utils import screenspace_to_worldspace physics_size = screenspace_to_worldspace([ScreenObjectManager.instance.screen_width / 2 + self.screen_size[0], ScreenObjectManager.instance.screen_height / 2 + self.screen_size[1]]) self.verts = [ (physics_size[0]/2, physics_size[1]/2), (physics_size[0]/2, -physics_size[1]/2), (-physics_size[0]/2, -physics_size[1]/2), (-physics_size[0]/2, physics_size[1]/2), ]
def getPositionAnchorOffset(self): res = np.array([0.0, 0.0]) from ev3sim.visual.utils import screenspace_to_worldspace physics_size = screenspace_to_worldspace( [ ScreenObjectManager.instance._SCREEN_WIDTH_ACTUAL / 2 + self.screen_size[0], ScreenObjectManager.instance._SCREEN_HEIGHT_ACTUAL / 2 + self.screen_size[1], ] ) if self.hAlignment == "l": res += np.array([physics_size[0] / 2, 0.0]) elif self.hAlignment == "m": pass elif self.hAlignment == "r": res -= np.array([physics_size[0] / 2, 0.0]) else: raise ValueError(f"hAlignment is incorrect: {self.hAlignment}") if self.vAlignment == "t": res += np.array([0.0, physics_size[1] / 2]) elif self.vAlignment == "m": pass elif self.vAlignment == "b": res -= np.array([0.0, physics_size[1] / 2]) else: raise ValueError(f"vAlignment is incorrect: {self.vAlignment}") return res
def toTilePos(self, mpos): new_pos = utils.screenspace_to_worldspace(mpos, self.customMap) new_pos = [ new_pos[0] - self.tile_offset[0], new_pos[1] - self.tile_offset[1] ] return int((new_pos[0] + 105) // 30 - 3), int((new_pos[1] + 105) // 30 - 3)
def handleEvent(self, event): super().handleEvent(event) if event.type == EV3SIM_PRINT: m = event.message.rstrip() if m.endswith("Prize!"): try: result = m.split()[0] for i, response in enumerate(self.RESPONSES): if response == result: ScriptLoader.instance.object_map["prize_box"].fill = f"area_{i+1}_color" ScriptLoader.instance.object_map["prize_output"].text = response else: pass except: pass if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY) ) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] for shape in shapes: if shape.shape.obj.key == "drop": self.dropBall(m_pos)
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ STATIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] self.obj = shapes[0].shape.obj if getattr(self.obj, "clickable", True): self.obj.body.velocity = np.array([0.0, 0.0]) self.obj_grabbed = True self.obj_rel_pos = self.obj.position - m_pos self.obj_m_pos = m_pos if event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: # If a robot is right clicked, copy it's ID for use in the attach script. m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ STATIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] self.obj = shapes[0].shape.obj if hasattr(self.obj, "robot_class"): pyperclip.copy(self.obj.robot_class.ID) if event.type == pygame.MOUSEBUTTONUP and event.button == 1 and self.obj_grabbed: self.obj_grabbed = False # Give velocity based on previous mouse positions. if self.position_length != 0: differences = sum( (x + 1) / self.position_length * (self.positions[ (self.position_index + x + 1) % self.TOTAL_POSITIONS] - self.positions[ (self.position_index + x) % self.TOTAL_POSITIONS]) for x in range(self.position_length - 1)) # Sum will return 0 if position length is 0 - we need to handle this. if isinstance(differences, int): differences = np.array([0, 0]) self.obj.body.velocity = self.VELOCITY_MULT * differences if event.type == pygame.MOUSEMOTION and self.obj_grabbed: self.obj_m_pos = screenspace_to_worldspace(event.pos)
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY) ) for shape in shapes: if shape.shape.obj.key == "controlsReset": self._pressed = True words = shape.shape.obj.key.split("-") if len(words) == 3 and words[0] == "Tile" and words[2] == "UI": tile_index = int(words[1]) self.spawnAt(tile_index) if event.type == pygame.MOUSEBUTTONUP and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY) ) for shape in shapes: if (shape.shape.obj.key == "controlsReset") & self._pressed: self.reset() self._pressed = False if event.type == pygame.MOUSEMOTION: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY) ) for shape in shapes: words = shape.shape.obj.key.split("-") if len(words) == 3 and words[0] == "Tile" and words[2] == "UI": tile_index = int(words[1]) # Highlight at tile. if self.hover_rect.key not in ScreenObjectManager.instance.objects: ScreenObjectManager.instance.registerVisual(self.hover_rect, self.hover_rect.key) self.hover_rect.position = self.tiles[tile_index]["world_pos"] break else: if self.hover_rect.key in ScreenObjectManager.instance.objects: ScreenObjectManager.instance.unregisterVisual(self.hover_rect.key)
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=DYNAMIC_CATEGORY)) if shapes: max_z = max(pq.shape.obj.clickZ for pq in shapes) shapes = [pq for pq in shapes if pq.shape.obj.clickZ == max_z] for pq in shapes: if pq.shape.obj.key == self.generated[0].key: self.device_class.pressed = True self.generated[ 0].visual.fill = "BUTTON_back_color_press" if event.type == pygame.MOUSEBUTTONUP and event.button == 1: self.device_class.pressed = False self.generated[0].visual.fill = "BUTTON_back_color_release"
def calculatePoints(self): relative_scale = ScreenObjectManager.instance.relativeScreenScale() # In order to have a reasonably sized image at all resolutions, calculate the scale to use based on the starting screen scale as well. relative_scale = relative_scale * ScreenObjectManager.instance.original_SCREEN_WIDTH / 1280 new_size = [ int(self.image.get_size()[0] * self.scale * relative_scale), int(self.image.get_size()[1] * self.scale * relative_scale), ] scaled = pygame.transform.scale(self.image, new_size) self.rotated = pygame.transform.rotate(scaled, self.rotation * 180 / np.pi) self.rotated.fill(self.fill, special_flags=pygame.BLEND_ADD) self.screen_location = utils.worldspace_to_screenspace(self.position) self.screen_size = self.rotated.get_size() if self.hAlignment == "l": pass elif self.hAlignment == "m": self.screen_location -= np.array([self.screen_size[0] / 2, 0.0]) elif self.hAlignment == "r": self.screen_location -= np.array([self.screen_size[0], 0.0]) else: raise ValueError(f"hAlignment is incorrect: {self.hAlignment}") if self.vAlignment == "t": pass elif self.vAlignment == "m": self.screen_location -= np.array([0.0, self.screen_size[1] / 2]) elif self.vAlignment == "b": self.screen_location -= np.array([0.0, self.screen_size[1]]) else: raise ValueError(f"vAlignment is incorrect: {self.vAlignment}") from ev3sim.visual.utils import screenspace_to_worldspace physics_size = screenspace_to_worldspace( [ ScreenObjectManager.instance._SCREEN_WIDTH_ACTUAL / 2 + self.screen_size[0], ScreenObjectManager.instance._SCREEN_HEIGHT_ACTUAL / 2 + self.screen_size[1], ] ) self.verts = [ (physics_size[0] / 2, physics_size[1] / 2), (physics_size[0] / 2, -physics_size[1] / 2), (-physics_size[0] / 2, -physics_size[1] / 2), (-physics_size[0] / 2, physics_size[1] / 2), ]
def getPositionAnchorOffset(self): res = np.array([.0, .0]) from ev3sim.visual.utils import screenspace_to_worldspace physics_size = screenspace_to_worldspace([ScreenObjectManager.instance.screen_width / 2 + self.screen_size[0], ScreenObjectManager.instance.screen_height / 2 + self.screen_size[1]]) if self.hAlignment == 'l': res += np.array([physics_size[0] / 2, 0.0]) elif self.hAlignment == 'm': pass elif self.hAlignment == 'r': res -= np.array([physics_size[0] / 2, 0.0]) else: raise ValueError(f'hAlignment is incorrect: {self.hAlignment}') if self.vAlignment == 't': res += np.array([0.0, physics_size[1] / 2]) elif self.vAlignment == 'm': pass elif self.vAlignment == 'b': res -= np.array([0.0, physics_size[1] / 2]) else: raise ValueError(f'vAlignment is incorrect: {self.vAlignment}') return res
def handleEvent(self, event): if self.mode == self.MODE_NORMAL or self.mode == self.MODE_CAN_DRAGGING: button_filter = lambda x: True else: button_filter = lambda x: False super().handleEvent(event, button_filter=button_filter) if self.mode == self.MODE_NORMAL: if event.type == pygame.MOUSEMOTION: self.current_mpos = event.pos elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: world_mpos = utils.screenspace_to_worldspace( self.current_mpos, self.customMap) vec = [ self.can_obj.position[0] - world_mpos[0], self.can_obj.position[1] - world_mpos[1], ] d = magnitude_sq(vec) if d <= pow(2.5, 2): self.mode = self.MODE_CAN_DRAGGING self.rel_pos = vec return if self.current_mpos[0] > self.side_width: self.selectTile(self.toTilePos(self.current_mpos)) elif event.type == pygame.MOUSEWHEEL: for attr, conv, inc in [ ("rotation_entry", int, 90), ]: if hasattr(self, attr): rect = getattr(self, attr).get_relative_rect() if (rect.left <= self.current_mpos[0] <= rect.right and rect.top <= self.current_mpos[1] <= rect.bottom): try: val = conv(getattr(self, attr).text) val += event.y * inc getattr(self, attr).set_text(str(val)) except: pass elif event.type == pygame.KEYDOWN: if event.key == pygame.K_BACKSPACE or event.key == pygame.K_DELETE: # Check that no entry is focused. good = True for attr in [ "rotation_entry", ]: if hasattr(self, attr) and getattr(self, attr).is_focused: good = False if good: self.removeSelected() elif self.mode == self.MODE_CAN_DRAGGING: if event.type == pygame.MOUSEBUTTONUP and event.button == 1: self.mode = self.MODE_NORMAL return elif event.type == pygame.MOUSEMOTION: self.current_mpos = event.pos world_mpos = utils.screenspace_to_worldspace( self.current_mpos, self.customMap) self.can_obj.position = [ self.rel_pos[0] + world_mpos[0], self.rel_pos[1] + world_mpos[1], ] self.previous_info["settings"]["rescue"][ "CAN_SPAWN_POSITION"] = [ float(self.can_obj.position[0] - self.tile_offset[0]), float(self.can_obj.position[1] - self.tile_offset[1]), ]
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) for shape in shapes: for team in range(len(SoccerUIInteractor.instance.names)): # Goal change functionality if shape.shape.obj.key.startswith(f"score{team+1}"): action = shape.shape.obj.key.split(str(team + 1))[1] if action == "Plus": SoccerLogicInteractor.instance.team_scores[ team] += 1 elif action == "Minus": if SoccerLogicInteractor.instance.team_scores[ team] > 0: SoccerLogicInteractor.instance.team_scores[ team] -= 1 else: raise ValueError(f"Unhandled team action {action}") SoccerUIInteractor.instance.updateScoreText( SoccerLogicInteractor.instance.team_scores) # Early penalty end for index in range( SoccerLogicInteractor.instance.BOTS_PER_TEAM): actual_index = team + index * len( SoccerUIInteractor.instance.names) if actual_index < len(self.robots): if shape.shape.obj.key == f"UI-penalty-{actual_index}": SoccerLogicInteractor.instance.finishPenalty( actual_index) if shape.shape.obj.key == "controlsReset": SoccerUIInteractor.instance.onResetPressed() if event.type == pygame.MOUSEMOTION: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) # Penalty UI hover colour. for team in range(len(SoccerUIInteractor.instance.names)): for index in range( SoccerLogicInteractor.instance.BOTS_PER_TEAM): actual_index = team + index * len( SoccerUIInteractor.instance.names) for shape in shapes: if shape.shape.obj.key == f"UI-penalty-{team + index * len(SoccerUIInteractor.instance.names)}": shape.shape.obj.visual.fill = "penalty_ui_bg_hover" break else: key = f"UI-penalty-{team + index * len(SoccerUIInteractor.instance.names)}" if key in ScriptLoader.instance.object_map: ScriptLoader.instance.object_map[ key].visual.fill = "penalty_ui_bg" if event.type == pygame.MOUSEBUTTONUP and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( [float(v) for v in m_pos], 0.0, pymunk.ShapeFilter(mask=STATIC_CATEGORY)) reset_hovered = False for shape in shapes: if shape.shape.obj.key == "controlsReset": reset_hovered = True SoccerUIInteractor.instance.onResetReleased(reset_hovered)