Advertisement
Windspar

Pygame Movement And Collision Example

Jan 16th, 2020
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.39 KB | None | 0 0
  1. import os
  2. import pygame
  3. from types import SimpleNamespace
  4. from pygame.sprite import Sprite, Group, spritecollide
  5.  
  6. # Wrap pygame builtin colors into namespace.
  7. color = SimpleNamespace(**pygame.color.THECOLORS)
  8.  
  9. # Interface
  10. class Scene:
  11.     def __init__(self, manager):
  12.         self.manager = manager
  13.  
  14.     def on_draw(self, surface): pass
  15.     def on_event(self, event): pass
  16.     def on_update(self, delta): pass
  17.  
  18.     def on_quit(self):
  19.         self.manager.quit()
  20.  
  21. # Handles what scene is active
  22. class Manager:
  23.     def __init__(self, caption, width, height, center=True, flags=0):
  24.         if center:
  25.             os.environ['SDL_VIDEO_CENTERED'] = '1'
  26.  
  27.         # Basic pygame setup
  28.         pygame.display.set_caption(caption)
  29.         self.surface = pygame.display.set_mode((width, height), flags)
  30.         self.rect = self.surface.get_rect()
  31.         self.clock = pygame.time.Clock()
  32.         self.running = False
  33.         self.delta = 0
  34.         self.fps = 60
  35.  
  36.         self.scene = Scene(self)
  37.  
  38.     def mainloop(self):
  39.         self.running = True
  40.         while self.running:
  41.             for event in pygame.event.get():
  42.                 if event.type == pygame.QUIT:
  43.                     self.scene.on_quit()
  44.                 else:
  45.                     self.scene.on_event(event)
  46.  
  47.             self.scene.on_update(self.delta)
  48.             self.scene.on_draw(self.surface)
  49.             pygame.display.flip()
  50.             self.delta = self.clock.tick(self.fps)
  51.  
  52.     def quit(self):
  53.         self.running = False
  54.  
  55. class Label(Sprite):
  56.     def __init__(self, text, font, color, position, anchor="topleft"):
  57.         Sprite.__init__(self)
  58.         self._text = text
  59.         self._font = font
  60.         self._color = color
  61.         self._anchor = anchor
  62.         self._position = position
  63.         self.render()
  64.  
  65.     def render(self):
  66.         self.image = self._font.render(self._text, 1, self._color)
  67.         self.rect = self.image.get_rect(**{self._anchor: self._position})
  68.  
  69.     def set_text(self, text):
  70.         self._text = text
  71.         self.render()
  72.  
  73. class Images:
  74.     @classmethod
  75.     def init(cls):
  76.         cls.character = pygame.Surface((30, 30))
  77.         cls.character.fill(color.firebrick)
  78.  
  79.         cls.player = pygame.Surface((30, 30))
  80.         cls.player.fill(color.dodgerblue)
  81.  
  82. class Character(Sprite):
  83.     def __init__(self, name, image, position, anchor="topleft"):
  84.         Sprite.__init__(self)
  85.         self.name = name
  86.         self.image = image
  87.         self.rect = image.get_rect(**{anchor: position})
  88.         self.center = pygame.Vector2(self.rect.center)
  89.  
  90. class Player(Sprite):
  91.     def __init__(self, image, position, anchor="topleft"):
  92.         Sprite.__init__(self)
  93.         self.image = image
  94.         self.rect = image.get_rect(**{anchor: position})
  95.         self.center = pygame.Vector2(self.rect.center)
  96.         self.speed = 80 * 0.001
  97.  
  98.     def move(self, pressed, delta, group):
  99.         if any([pressed[k] for k in (pygame.K_UP, pygame.K_w)]):
  100.             self.center.y -= self.speed * delta
  101.  
  102.         if any([pressed[k] for k in (pygame.K_DOWN, pygame.K_s)]):
  103.             self.center.y += self.speed * delta
  104.  
  105.         if any([pressed[k] for k in (pygame.K_LEFT, pygame.K_a)]):
  106.             self.center.x -= self.speed * delta
  107.  
  108.         if any([pressed[k] for k in (pygame.K_RIGHT, pygame.K_d)]):
  109.             self.center.x += self.speed * delta
  110.  
  111.         # Move sprite
  112.         self.rect.center = self.center
  113.  
  114.         # Collision
  115.         names = []
  116.         sprites = spritecollide(self, group, False)
  117.         for sprite in sprites:
  118.             clip = sprite.rect.clip(self.rect)
  119.             if clip.h < clip.w:
  120.                 if sprite.rect.centery > self.rect.centery:
  121.                     self.center.y -= clip.h
  122.                 else:
  123.                     self.center.y += clip.h
  124.             else:
  125.                 if sprite.rect.centerx > self.rect.centerx:
  126.                     self.center.x -= clip.w
  127.                 else:
  128.                     self.center.x += clip.w
  129.  
  130.             self.rect.center = self.center
  131.             names.append(sprite.name)
  132.  
  133.         return names
  134.  
  135. class GameScene(Scene):
  136.     def __init__(self, manager):
  137.         Scene.__init__(self, manager)
  138.         self.sprites = Group()
  139.         self.characters = Group()
  140.         self.player = Player(Images.player, manager.rect.center, "center")
  141.  
  142.         for name, pos in [("Amy", (40, 40)), ("Steve", (320, 120)), ("Mike", (80, 280))]:
  143.             self.characters.add(Character(name, Images.character, pos))
  144.  
  145.         position = manager.rect.centerx, 20
  146.         self.label = Label("No Collision", pygame.font.Font(None, 28), color.lawngreen, position, "midtop")
  147.  
  148.         self.sprites.add(self.player, self.label)
  149.         self.sprites.add(self.characters)
  150.  
  151.     def on_draw(self, surface):
  152.         surface.fill(color.black)
  153.         self.sprites.draw(surface)
  154.  
  155.     def on_update(self, delta):
  156.         pressed = pygame.key.get_pressed()
  157.         names = self.player.move(pressed, delta, self.characters)
  158.         if len(names) == 1:
  159.             self.label.set_text("Collide with " + names[0])
  160.         elif len(names) > 1:
  161.             string = "{}, " * len(names)
  162.             self.label.set_text("Collide with " + string.format(*names))
  163.  
  164. def main():
  165.     pygame.init()
  166.     manager = Manager("Collision Example", 600, 600)
  167.     Images.init()
  168.     manager.scene = GameScene(manager)
  169.     manager.mainloop()
  170.  
  171. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement