mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			155 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			155 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import datetime | ||
|  | 
 | ||
|  | from s2clientprotocol import score_pb2 as score_pb | ||
|  | 
 | ||
|  | from .position import Point2 | ||
|  | 
 | ||
|  | 
 | ||
|  | class Renderer: | ||
|  | 
 | ||
|  |     def __init__(self, client, map_size, minimap_size): | ||
|  |         self._client = client | ||
|  | 
 | ||
|  |         self._window = None | ||
|  |         self._map_size = map_size | ||
|  |         self._map_image = None | ||
|  |         self._minimap_size = minimap_size | ||
|  |         self._minimap_image = None | ||
|  |         self._mouse_x, self._mouse_y = None, None | ||
|  |         self._text_supply = None | ||
|  |         self._text_vespene = None | ||
|  |         self._text_minerals = None | ||
|  |         self._text_score = None | ||
|  |         self._text_time = None | ||
|  | 
 | ||
|  |     async def render(self, observation): | ||
|  |         render_data = observation.observation.render_data | ||
|  | 
 | ||
|  |         map_size = render_data.map.size | ||
|  |         map_data = render_data.map.data | ||
|  |         minimap_size = render_data.minimap.size | ||
|  |         minimap_data = render_data.minimap.data | ||
|  | 
 | ||
|  |         map_width, map_height = map_size.x, map_size.y | ||
|  |         map_pitch = -map_width * 3 | ||
|  | 
 | ||
|  |         minimap_width, minimap_height = minimap_size.x, minimap_size.y | ||
|  |         minimap_pitch = -minimap_width * 3 | ||
|  | 
 | ||
|  |         if not self._window: | ||
|  |             # pylint: disable=C0415 | ||
|  |             from pyglet.image import ImageData | ||
|  |             from pyglet.text import Label | ||
|  |             from pyglet.window import Window | ||
|  | 
 | ||
|  |             self._window = Window(width=map_width, height=map_height) | ||
|  |             self._window.on_mouse_press = self._on_mouse_press | ||
|  |             self._window.on_mouse_release = self._on_mouse_release | ||
|  |             self._window.on_mouse_drag = self._on_mouse_drag | ||
|  |             self._map_image = ImageData(map_width, map_height, "RGB", map_data, map_pitch) | ||
|  |             self._minimap_image = ImageData(minimap_width, minimap_height, "RGB", minimap_data, minimap_pitch) | ||
|  |             self._text_supply = Label( | ||
|  |                 "", | ||
|  |                 font_name="Arial", | ||
|  |                 font_size=16, | ||
|  |                 anchor_x="right", | ||
|  |                 anchor_y="top", | ||
|  |                 x=self._map_size[0] - 10, | ||
|  |                 y=self._map_size[1] - 10, | ||
|  |                 color=(200, 200, 200, 255), | ||
|  |             ) | ||
|  |             self._text_vespene = Label( | ||
|  |                 "", | ||
|  |                 font_name="Arial", | ||
|  |                 font_size=16, | ||
|  |                 anchor_x="right", | ||
|  |                 anchor_y="top", | ||
|  |                 x=self._map_size[0] - 130, | ||
|  |                 y=self._map_size[1] - 10, | ||
|  |                 color=(28, 160, 16, 255), | ||
|  |             ) | ||
|  |             self._text_minerals = Label( | ||
|  |                 "", | ||
|  |                 font_name="Arial", | ||
|  |                 font_size=16, | ||
|  |                 anchor_x="right", | ||
|  |                 anchor_y="top", | ||
|  |                 x=self._map_size[0] - 200, | ||
|  |                 y=self._map_size[1] - 10, | ||
|  |                 color=(68, 140, 255, 255), | ||
|  |             ) | ||
|  |             self._text_score = Label( | ||
|  |                 "", | ||
|  |                 font_name="Arial", | ||
|  |                 font_size=16, | ||
|  |                 anchor_x="left", | ||
|  |                 anchor_y="top", | ||
|  |                 x=10, | ||
|  |                 y=self._map_size[1] - 10, | ||
|  |                 color=(219, 30, 30, 255), | ||
|  |             ) | ||
|  |             self._text_time = Label( | ||
|  |                 "", | ||
|  |                 font_name="Arial", | ||
|  |                 font_size=16, | ||
|  |                 anchor_x="right", | ||
|  |                 anchor_y="bottom", | ||
|  |                 x=self._minimap_size[0] - 10, | ||
|  |                 y=self._minimap_size[1] + 10, | ||
|  |                 color=(255, 255, 255, 255), | ||
|  |             ) | ||
|  |         else: | ||
|  |             self._map_image.set_data("RGB", map_pitch, map_data) | ||
|  |             self._minimap_image.set_data("RGB", minimap_pitch, minimap_data) | ||
|  |             self._text_time.text = str(datetime.timedelta(seconds=(observation.observation.game_loop * 0.725) // 16)) | ||
|  |             if observation.observation.HasField("player_common"): | ||
|  |                 self._text_supply.text = f"{observation.observation.player_common.food_used} / {observation.observation.player_common.food_cap}" | ||
|  |                 self._text_vespene.text = str(observation.observation.player_common.vespene) | ||
|  |                 self._text_minerals.text = str(observation.observation.player_common.minerals) | ||
|  |             if observation.observation.HasField("score"): | ||
|  |                 # pylint: disable=W0212 | ||
|  |                 self._text_score.text = f"{score_pb._SCORE_SCORETYPE.values_by_number[observation.observation.score.score_type].name} score: {observation.observation.score.score}" | ||
|  | 
 | ||
|  |         await self._update_window() | ||
|  | 
 | ||
|  |         if self._client.in_game and (not observation.player_result) and self._mouse_x and self._mouse_y: | ||
|  |             await self._client.move_camera_spatial(Point2((self._mouse_x, self._minimap_size[0] - self._mouse_y))) | ||
|  |             self._mouse_x, self._mouse_y = None, None | ||
|  | 
 | ||
|  |     async def _update_window(self): | ||
|  |         self._window.switch_to() | ||
|  |         self._window.dispatch_events() | ||
|  | 
 | ||
|  |         self._window.clear() | ||
|  | 
 | ||
|  |         self._map_image.blit(0, 0) | ||
|  |         self._minimap_image.blit(0, 0) | ||
|  |         self._text_time.draw() | ||
|  |         self._text_score.draw() | ||
|  |         self._text_minerals.draw() | ||
|  |         self._text_vespene.draw() | ||
|  |         self._text_supply.draw() | ||
|  | 
 | ||
|  |         self._window.flip() | ||
|  | 
 | ||
|  |     def _on_mouse_press(self, x, y, button, _modifiers): | ||
|  |         if button != 1:  # 1: mouse.LEFT | ||
|  |             return | ||
|  |         if x > self._minimap_size[0] or y > self._minimap_size[1]: | ||
|  |             return | ||
|  |         self._mouse_x, self._mouse_y = x, y | ||
|  | 
 | ||
|  |     def _on_mouse_release(self, x, y, button, _modifiers): | ||
|  |         if button != 1:  # 1: mouse.LEFT | ||
|  |             return | ||
|  |         if x > self._minimap_size[0] or y > self._minimap_size[1]: | ||
|  |             return | ||
|  |         self._mouse_x, self._mouse_y = x, y | ||
|  | 
 | ||
|  |     def _on_mouse_drag(self, x, y, _dx, _dy, buttons, _modifiers): | ||
|  |         if not buttons & 1:  # 1: mouse.LEFT | ||
|  |             return | ||
|  |         if x > self._minimap_size[0] or y > self._minimap_size[1]: | ||
|  |             return | ||
|  |         self._mouse_x, self._mouse_y = x, y |