sprite_object.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import pygame as pg
  2. from settings import *
  3. import os
  4. from collections import deque
  5. class SpriteObject:
  6. def __init__(self, game, path='resources/sprites/static_sprites/candlebra.png',
  7. pos=(10.5, 3.5), scale=0.7, shift=0.27):
  8. self.game = game
  9. self.player = game.player
  10. self.x, self.y = pos
  11. self.image = pg.image.load(path).convert_alpha()
  12. self.IMAGE_WIDTH = self.image.get_width()
  13. self.IMAGE_HALF_WIDTH = self.image.get_width() // 2
  14. self.IMAGE_RATIO = self.IMAGE_WIDTH / self.image.get_height()
  15. self.dx, self.dy, self.theta, self.screen_x, self.dist, self.norm_dist = 0, 0, 0, 0, 1, 1
  16. self.sprite_half_width = 0
  17. self.SPRITE_SCALE = scale
  18. self.SPRITE_HEIGHT_SHIFT = shift
  19. def get_sprite_projection(self):
  20. proj = SCREEN_DIST / self.norm_dist * self.SPRITE_SCALE
  21. proj_width, proj_height = proj * self.IMAGE_RATIO, proj
  22. image = pg.transform.scale(self.image, (int(proj_width), int(proj_height)))
  23. self.sprite_half_width = proj_width // 2
  24. height_shift = proj_height * self.SPRITE_HEIGHT_SHIFT
  25. pos = self.screen_x - self.sprite_half_width, HALF_HEIGHT - proj_height // 2 + height_shift
  26. self.game.raycasting.objects_to_render.append((self.norm_dist, image, pos))
  27. def get_sprite(self):
  28. dx = self.x - self.player.x
  29. dy = self.y - self.player.y
  30. self.dx, self.dy = dx, dy
  31. self.theta = math.atan2(dy, dx)
  32. delta = self.theta - self.player.angle
  33. if (dx > 0 and self.player.angle > math.pi) or (dx < 0 and dy < 0):
  34. delta += math.tau
  35. delta_rays = delta / DELTA_ANGLE
  36. self.screen_x = (HALF_NUM_RAYS + delta_rays) * SCALE
  37. self.dist = math.hypot(dx, dy)
  38. self.norm_dist = self.dist * math.cos(delta)
  39. if -self.IMAGE_HALF_WIDTH < self.screen_x < (WIDTH + self.IMAGE_HALF_WIDTH) and self.norm_dist > 0.5:
  40. self.get_sprite_projection()
  41. def update(self):
  42. self.get_sprite()
  43. class AnimatedSprite(SpriteObject):
  44. def __init__(self, game, path='resources/sprites/animated_sprites/green_light/0.png',
  45. pos=(11.5, 3.5), scale=0.8, shift=0.16, animation_time=120):
  46. super().__init__(game, path, pos, scale, shift)
  47. self.animation_time = animation_time
  48. self.path = path.rsplit('/', 1)[0]
  49. self.images = self.get_images(self.path)
  50. self.animation_time_prev = pg.time.get_ticks()
  51. self.animation_trigger = False
  52. def update(self):
  53. super().update()
  54. self.check_animation_time()
  55. self.animate(self.images)
  56. def animate(self, images):
  57. if self.animation_trigger:
  58. images.rotate(-1)
  59. self.image = images[0]
  60. def check_animation_time(self):
  61. self.animation_trigger = False
  62. time_now = pg.time.get_ticks()
  63. if time_now - self.animation_time_prev > self.animation_time:
  64. self.animation_time_prev = time_now
  65. self.animation_trigger = True
  66. def get_images(self, path):
  67. images = deque()
  68. for file_name in os.listdir(path):
  69. if os.path.isfile(os.path.join(path, file_name)):
  70. img = pg.image.load(path + '/' + file_name).convert_alpha()
  71. images.append(img)
  72. return images