scene.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import os
  2. from typing import Tuple
  3. import pygame
  4. from jogai import settings, utils, videogame
  5. from jogai._globals import _window
  6. from jogai.translations import gettext as _
  7. class Scene:
  8. """
  9. A videogame scene with background color and an optional image.
  10. """
  11. _image = None
  12. _rect = None
  13. filename = ''
  14. background = settings.SCENE_DEFAULT_BACKGROUND
  15. def __init__(
  16. self,
  17. image_filename: str = '',
  18. background: Tuple[int, int, int] = settings.SCENE_DEFAULT_BACKGROUND,
  19. ):
  20. if not isinstance(image_filename, str):
  21. raise TypeError(_('The image filename must be a string'))
  22. self.change_background(background)
  23. if image_filename:
  24. self.change_image(image_filename)
  25. @property
  26. def height(self):
  27. return self._rect.height
  28. @property
  29. def width(self):
  30. return self._rect.width
  31. @property
  32. def x(self):
  33. return self._rect.x
  34. def change_background(self, background: Tuple[int, int, int]):
  35. """
  36. Change the background color.
  37. Parameters:
  38. background: A tuple with the R,G,B components.
  39. Examples:
  40. >>> sc = Scene()
  41. >>> sc.change_background((255, 255, 255))
  42. """
  43. match background:
  44. case r, g, b if (
  45. isinstance(r, int)
  46. and isinstance(g, int)
  47. and isinstance(b, int)
  48. and 0 <= r <= 255
  49. and 0 <= g <= 255
  50. and 0 <= b <= 255
  51. ):
  52. self.background = (r, g, b)
  53. case _:
  54. raise ValueError(
  55. _(
  56. 'The background color must be a tuple with three integers (r,g,b) between 0 and 255.'
  57. )
  58. )
  59. def change_image(self, filename: str) -> bool:
  60. """
  61. Change the scene image.
  62. Parameters:
  63. filename: The image filename to be changed.
  64. Examples:
  65. >>> sc = Scene()
  66. >>> sc.change_image('test.png')
  67. """
  68. self._image, self._rect = utils._load_image(
  69. settings.SCENES_DIR, filename
  70. )
  71. self.filename = filename
  72. def set_position(self, x: int):
  73. """
  74. Set the scene abscissa position.
  75. The scene painted will never exceed the edges of the image.
  76. The x coordinate is a non-positive number (scene is moving to the left).
  77. Parameters:
  78. x: coordinate in horizontal axis
  79. Examples:
  80. >>> sc = Scene('test_large.png')
  81. >>> sc.set_position(300)
  82. """
  83. if not isinstance(x, int):
  84. raise TypeError(_('The x coordinate must be an integer.'))
  85. # Set x in range to prevent the scene from being outside the window.
  86. # The minus sign is essential to correctly position the scene.
  87. self._rect.x = -min(
  88. max(0, x), self._rect.width - settings.WINDOW_WIDTH
  89. )