main.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import sys, pygame
  2. pygame.init()
  3. #region Fuctions
  4. def clean_up_and_exit():
  5. pygame.quit()
  6. sys.exit()
  7. def screen_pos_to_world_pos(pos: tuple[int, int]) -> tuple[int, int]:
  8. return (pos[0] + camera_pos[0], pos[1] + camera_pos[1])
  9. def draw_rect(surface: pygame.surface.Surface, pos1: tuple[int, int], pos2: tuple[int, int], color: tuple[int, int, int] = (0, 0, 0), width: int = 0):
  10. size = (pos2[0] - pos1[0], pos2[1] - pos1[1])
  11. return pygame.draw.rect(surface, color, (
  12. pos1[0] if size[0] > 0 else pos1[0] - abs(size[0]),
  13. pos1[1] if size[1] > 0 else pos1[1] - abs(size[1]),
  14. abs(size[0]),
  15. abs(size[1])
  16. ), width)
  17. #endregion
  18. #region Engine stuff
  19. fps = 60
  20. fpsClock = pygame.time.Clock()
  21. width, height = 640, 480
  22. screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
  23. antialias = False
  24. camera_pos: list[int, int] = [0, 0]
  25. left_clicked_pos: tuple[int, int] | None = None
  26. middle_clicked_pos: tuple[int, int] | None = None
  27. right_clicked_pos: tuple[int, int] | None = None
  28. debug_ui_shown = False
  29. prev_mouse_pos = (0, 0)
  30. mouse_pos = pygame.mouse.get_pos()
  31. render_enable = True
  32. input_checks_enable = True
  33. #endregion
  34. #region UI
  35. class UIElement:
  36. def __init__(self, x: int, y: int, width: int, height: int):
  37. self.x: int = x
  38. self.y: int = y
  39. self.width: int = width
  40. self.height: int = height
  41. self.state: str|None = None
  42. self.images: dict[str, pygame.surface.Surface] = {}
  43. self.init_images()
  44. def get_x(self) -> int:
  45. return self.x
  46. def get_y(self) -> int:
  47. return self.y
  48. def get_width(self) -> int:
  49. return self.width
  50. def get_height(self) -> int:
  51. return self.height
  52. def init_images(self):
  53. self.images['main'] = pygame.surface.Surface(self.get_rect())
  54. def get_rect(self) -> pygame.rect.Rect:
  55. return pygame.rect.Rect(
  56. self.get_x(),
  57. self.get_y(),
  58. self.get_width(),
  59. self.get_height()
  60. )
  61. def get_image(self) -> pygame.surface.Surface:
  62. return self.images['main']
  63. def handle_event(self, event: pygame.event.Event) -> bool:
  64. return False
  65. class UIButton(UIElement):
  66. def __init__(self, x: int, y: int, text: str):
  67. self.x: int = x
  68. self.y: int = y
  69. self.width: int = 0
  70. self.height: int = 0
  71. self.text: str = text
  72. self.state: str|None = None
  73. self.images: dict[str, pygame.surface.Surface] = {}
  74. self.init_images()
  75. def init_images(self):
  76. font = pygame.font.Font(size=30)
  77. text_img = font.render(self.text, antialias, (0, 0, 0))
  78. self.width = text_img.get_width() + 20
  79. self.height = text_img.get_height() + 18
  80. image = pygame.surface.Surface((self.get_width(), self.get_height()), pygame.SRCALPHA)
  81. pygame.draw.rect(image, (255, 255, 255), (0, 0, self.get_width(), self.get_height()), 0, 10)
  82. pygame.draw.rect(image, (200, 200, 200), (0, 0, self.get_width(), self.get_height()), 5, 10)
  83. image.blit(text_img, (10, 10))
  84. self.images['main'] = image
  85. class UIManager:
  86. pass
  87. #endregion
  88. cur_tool = 'cursor'
  89. #region Tool Buttons
  90. tool_font = pygame.font.Font(size=30)
  91. cursor_tool_image = tool_font.render('Cursor', antialias, (0, 0, 0), (200, 200, 200))
  92. cursor_tool_image = cursor_tool_image.convert_alpha()
  93. cursor_tool_image.set_alpha(200)
  94. rectangle_tool_image = tool_font.render('Rectangle', antialias, (0, 0, 0), (200, 200, 200))
  95. rectangle_tool_image = rectangle_tool_image.convert_alpha()
  96. rectangle_tool_image.set_alpha(200)
  97. #endregion
  98. #region Debug
  99. debug_screen_space = 10
  100. debug_font = pygame.font.Font(size=20)
  101. debug_screen_label = debug_font.render('Debug Information', antialias, (0, 0, 0))
  102. #endregion
  103. temp_ui_button = UIButton(100, 100, 'UIButton Test')
  104. while True:
  105. events = pygame.event.get()
  106. for event in events:
  107. prev_mouse_pos = mouse_pos
  108. mouse_pos = pygame.mouse.get_pos()
  109. if event.type == pygame.QUIT:
  110. clean_up_and_exit()
  111. elif event.type == pygame.KEYDOWN:
  112. if event.key == pygame.K_q:
  113. clean_up_and_exit()
  114. elif event.type == pygame.VIDEORESIZE:
  115. screen_width = event.w
  116. screen_height = event.h
  117. elif event.type == pygame.ACTIVEEVENT:
  118. render_enable = event.state == 1
  119. input_checks_enable = bool(event.gain)
  120. if render_enable:
  121. screen.fill((255, 255, 255))
  122. for event in events:
  123. if input_checks_enable:
  124. if event.type == pygame.MOUSEBUTTONDOWN:
  125. if event.button == 1:
  126. left_clicked_pos = mouse_pos
  127. elif event.button == 2:
  128. middle_clicked_pos = mouse_pos
  129. elif event.button == 3:
  130. right_clicked_pos = mouse_pos
  131. elif event.type == pygame.MOUSEBUTTONUP:
  132. if event.button == 1:
  133. left_clicked_pos = None
  134. elif event.button == 2:
  135. middle_clicked_pos = None
  136. elif event.button == 3:
  137. right_clicked_pos = None
  138. elif event.type == pygame.MOUSEMOTION:
  139. if event.buttons[0]:
  140. match cur_tool:
  141. case 'cursor':
  142. if left_clicked_pos:
  143. if render_enable:
  144. draw_rect(screen, left_clicked_pos, mouse_pos, (0, 0, 0), 1)
  145. if event.buttons[1]:
  146. pass
  147. if event.buttons[2]:
  148. camera_pos[0] += mouse_pos[0] - prev_mouse_pos[0]
  149. camera_pos[1] += mouse_pos[1] - prev_mouse_pos[1]
  150. elif event.type == pygame.KEYDOWN:
  151. if event.key == pygame.K_F3:
  152. debug_ui_shown = not debug_ui_shown
  153. if render_enable:
  154. # WORLD
  155. # UI
  156. screen.blit(temp_ui_button.get_image(), temp_ui_button.get_rect())
  157. screen.blit(cursor_tool_image, (5, 5))
  158. screen.blit(rectangle_tool_image, (10 + cursor_tool_image.get_width(), 5))
  159. if debug_ui_shown:
  160. camera_pos_img = debug_font.render(f'Camera positon: X={camera_pos[0]} Y={camera_pos[1]}', antialias, (0, 0, 0))
  161. bg_size = [0, 0]
  162. bg_size[0] = max(bg_size[0], debug_screen_label.get_width() + (debug_screen_space * 2))
  163. bg_size[0] = max(bg_size[0], camera_pos_img.get_width() + (debug_screen_space * 2))
  164. bg_size[1] += debug_screen_label.get_height() + debug_screen_space
  165. bg_size[1] += camera_pos_img.get_height() + debug_screen_space
  166. bg_size[1] += debug_screen_space
  167. debug_screen = pygame.Surface(bg_size)
  168. debug_screen = debug_screen.convert_alpha()
  169. debug_screen.fill((200, 200, 200))
  170. debug_screen.blit(debug_screen_label, ((bg_size[0] // 2) - (debug_screen_label.get_width() // 2), debug_screen_space))
  171. debug_screen.blit(camera_pos_img, (debug_screen_space, camera_pos_img.get_height() + (debug_screen_space * 2)))
  172. debug_screen.set_alpha(200)
  173. screen.blit(debug_screen, (debug_screen_space, screen.get_height() - debug_screen.get_height() - debug_screen_space))
  174. pygame.display.flip()