Advertisement
Windspar

Pygame Rotate Image With Vector2 Example

Mar 24th, 2021
1,077
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.44 KB | None | 0 0
  1. import pygame
  2. from pygame.sprite import Group, Sprite
  3.  
  4.  
  5. class _NextScene:
  6.     def __init__(self, scene, args):
  7.         self.scene = scene
  8.         self.args = args
  9.  
  10. class Scene:
  11.     def __init__(self, engine):
  12.         self.engine = engine
  13.  
  14.     def on_enter(self, *args):
  15.         pass
  16.  
  17.     def on_exit(self):
  18.         pass
  19.  
  20.     def on_draw(self, surface):
  21.         pass
  22.  
  23.     def on_event(self, event):
  24.         pass
  25.  
  26.     def on_update(self, delta, ticks):
  27.         pass
  28.  
  29.     # StateEngine Interface
  30.     def set_state(self, state, *args):
  31.         self.engine.next = _NextScene(state, args)
  32.  
  33.     def quit(self):
  34.         self.engine.on_quit()
  35.  
  36. class DisplayEngine:
  37.     def __init__(self, caption, width, height, flags=0):
  38.         pygame.display.set_caption(caption)
  39.         self.surface = pygame.display.set_mode((width, height), flags)
  40.         self.rect = self.surface.get_rect()
  41.         self.clock = pygame.time.Clock()
  42.         self.running = False
  43.         self.delta = 0
  44.         self.fps = 60
  45.  
  46.         self.on_quit = self.quit
  47.         self.scene = Scene(self)
  48.         self.next = None
  49.  
  50.     @property
  51.     def width(self):
  52.         return self.rect.width
  53.  
  54.     @property
  55.     def height(self):
  56.         return self.rect.height
  57.  
  58.     @property
  59.     def size(self):
  60.         return self.rect.size
  61.  
  62.     def main_loop(self):
  63.         self.running = True
  64.         while self.running:
  65.             self.update_scene()
  66.  
  67.             for event in pygame.event.get():
  68.                 if event.type == pygame.QUIT:
  69.                     self.on_quit()
  70.                 else:
  71.                     self.scene.on_event(event)
  72.  
  73.             ticks = pygame.time.get_ticks()
  74.             self.scene.on_draw(self.surface)
  75.             self.scene.on_update(self.delta, ticks)
  76.             pygame.display.flip()
  77.             self.delta = self.clock.tick(self.fps) * 0.001
  78.  
  79.     def update_scene(self):
  80.         if self.next:
  81.             self.scene.on_exit()
  82.             self.scene = self.next.state
  83.             self.scene.on_enter(self.next.args)
  84.             self.next = None
  85.  
  86.     def quit(self):
  87.         self.running = False
  88.  
  89. class Player(Sprite):
  90.     def __init__(self, image, position, anchor):
  91.         Sprite.__init__(self)
  92.         self.o_image = image
  93.         self.image = image
  94.         self.rect = image.get_rect(**{anchor: position})
  95.         self.center = pygame.Vector2(self.rect.center)
  96.  
  97.         self.motion = 0
  98.         self.velocity = 30
  99.         self.vector = pygame.Vector2()
  100.         self.rotate_velocity = 60
  101.         self.rotate_angle = 0
  102.         self.angle = 0
  103.         self.vector.from_polar((1, self.angle - 90))
  104.  
  105.     def update(self, delta):
  106.         if self.motion != 0:
  107.             self.center += self.vector * self.velocity * delta * self.motion
  108.             self.rect.center = self.center
  109.  
  110.         if self.rotate_angle != 0:
  111.             self.rotate(self.angle + self.rotate_angle * delta * self.rotate_velocity)
  112.             self.rotate_angle = 0
  113.  
  114.     def rotate(self, angle):
  115.         self.angle = angle
  116.         # reverse rotation
  117.         self.vector.from_polar((1, 360 - (self.angle + 90)))
  118.         self.image = pygame.transform.rotate(self.o_image, angle)
  119.         self.rect = self.image.get_rect(center=self.rect.center)
  120.  
  121. class Game(Scene):
  122.     def __init__(self, engine):
  123.         Scene.__init__(self, engine)
  124.         image = self.create_player_image()
  125.         self.player = Player(image, engine.rect.center, "center")
  126.         self.sprites = Group(self.player)
  127.         self.draw_vector_line = False
  128.  
  129.     def create_player_image(self):
  130.         surface = pygame.Surface((30, 30), pygame.SRCALPHA)
  131.         surface.fill((0, 0, 0, 0))
  132.         color = pygame.Color("dodgerblue")
  133.         pygame.draw.polygon(surface, color, ((0, 29), (14,0), (29, 29)))
  134.         return surface
  135.  
  136.     def on_draw(self, surface):
  137.         surface.fill(pygame.Color("black"))
  138.         self.sprites.draw(surface)
  139.  
  140.         if self.draw_vector_line:
  141.             a = self.player.center
  142.             b = self.player.center + self.player.vector * 50
  143.             color = pygame.Color("lawngreen")
  144.             pygame.draw.line(surface, color, (int(a.x), int(a.y)), (int(b.x), (int(b.y))))
  145.  
  146.     def on_event(self, event):
  147.         if event.type == pygame.MOUSEMOTION:
  148.             # rotate image with mouse.
  149.             vector = (self.player.center - event.pos).normalize()
  150.             self.player.rotate(-(vector.as_polar()[1] - 90))
  151.         elif event.type == pygame.KEYDOWN:
  152.             if event.key == pygame.K_SPACE:
  153.                 self.draw_vector_line = not self.draw_vector_line
  154.  
  155.     def is_pressed(self, pressed, *keys):
  156.         for key in keys:
  157.             if pressed[key]:
  158.                 return True
  159.  
  160.         return False
  161.  
  162.     def on_update(self, delta, ticks):
  163.         self.player.motion = 0
  164.         pressed = pygame.key.get_pressed()
  165.         if self.is_pressed(pressed, pygame.K_UP, pygame.K_w):
  166.             self.player.motion += 1
  167.  
  168.         if self.is_pressed(pressed, pygame.K_DOWN, pygame.K_s):
  169.             self.player.motion -= 1
  170.  
  171.         if self.is_pressed(pressed, pygame.K_LEFT, pygame.K_a):
  172.             self.player.rotate_angle += 1
  173.  
  174.         if self.is_pressed(pressed, pygame.K_RIGHT, pygame.K_d):
  175.             self.player.rotate_angle -= 1
  176.  
  177.         self.player.update(delta)
  178.  
  179. def main():
  180.     pygame.init()
  181.     engine = DisplayEngine("Rotate Image", 800, 600)
  182.     engine.scene = Game(engine)
  183.     engine.main_loop()
  184.     pygame.quit()
  185.  
  186. main()
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement