Advertisement
Windspar

Pygame Driving A Car Demo.

Jan 8th, 2020
573
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.36 KB | None | 0 0
  1. # Example Driving a car. Turning with reverse need fix.
  2.  
  3. import os
  4. import pygame
  5.  
  6. from types import SimpleNamespace
  7. from pygame.sprite import Sprite, Group
  8.  
  9. # Wrap pygame builtin colors into namespace.
  10. color = SimpleNamespace(**pygame.color.THECOLORS)
  11.  
  12. # Interface
  13. class Scene:
  14.     def __init__(self, manager):
  15.         self.manager = manager
  16.  
  17.     def on_draw(self, surface): pass
  18.     def on_event(self, event): pass
  19.     def on_update(self, delta): pass
  20.  
  21.     def on_quit(self):
  22.         self.manager.quit()
  23.  
  24. # Handles what scene is active
  25. class Manager:
  26.     def __init__(self, caption, width, height, center=True, flags=0):
  27.         if center:
  28.             os.environ['SDL_VIDEO_CENTERED'] = '1'
  29.  
  30.         # Basic pygame setup
  31.         pygame.display.set_caption(caption)
  32.         self.surface = pygame.display.set_mode((width, height), flags)
  33.         self.rect = self.surface.get_rect()
  34.         self.clock = pygame.time.Clock()
  35.         self.running = False
  36.         self.delta = 0
  37.         self.fps = 60
  38.  
  39.         self.scene = Scene(self)
  40.  
  41.     def mainloop(self):
  42.         self.running = True
  43.         while self.running:
  44.             for event in pygame.event.get():
  45.                 if event.type == pygame.QUIT:
  46.                     self.scene.on_quit()
  47.                 else:
  48.                     self.scene.on_event(event)
  49.  
  50.             self.scene.on_update(self.delta)
  51.             self.scene.on_draw(self.surface)
  52.             pygame.display.flip()
  53.             self.delta = self.clock.tick(self.fps)
  54.  
  55.     def quit(self):
  56.         self.running = False
  57.  
  58. class Text(Sprite):
  59.     def __init__(self, text, font, color, position, anchor="topleft"):
  60.         Sprite.__init__(self)
  61.         self.font = font
  62.         self.color = color
  63.         self.position = position
  64.         self.anchor = anchor
  65.         self.render(text)
  66.  
  67.     def draw(self, surface):
  68.         surface.blit(self.image, self.rect)
  69.  
  70.     def render(self, text):
  71.         self.image = self.font.render(text, 1, self.color)
  72.         self.rect = self.image.get_rect(**{self.anchor: self.position})
  73.  
  74. class SimpleSprite(Sprite):
  75.     def __init__(self, image, position, anchor="topleft"):
  76.         Sprite.__init__(self)
  77.         self.image = image
  78.         self.rect = image.get_rect(**{anchor: position})
  79.  
  80.     def draw(self, surface):
  81.         surface.blit(self.image, self.rect)
  82.  
  83. class Movement:
  84.     def __init__(self, sprite, speed=2, rotate_speed=120, friction=0.1, max_speed=400):
  85.         self.angle = 180
  86.         self.sprite = sprite
  87.         self.center = sprite.rect.center
  88.         self.orignal_image = sprite.image
  89.         self.velocity = pygame.Vector2(0, 0)
  90.         self.vector = self.get_vector()
  91.         self.speed = speed * 0.001
  92.         self.friction = friction * 0.001
  93.         self.max_speed = max_speed * 0.001
  94.         self.rotate_speed = rotate_speed * 0.001
  95.  
  96.     def apply_friction(self, delta):
  97.         friction = self.get_vector() * self.friction * delta
  98.         friction = abs(friction.elementwise())
  99.  
  100.         if self.velocity.x > 0:
  101.             self.velocity.x -= friction.x
  102.             if self.velocity.x < 0:
  103.                 self.velocity.x = 0
  104.         elif self.velocity.x < 0:
  105.             self.velocity.x += friction.x
  106.             if self.velocity.x > 0:
  107.                 self.velocity.x = 0
  108.  
  109.         if self.velocity.y > 0:
  110.             self.velocity.y -= friction.y
  111.             if self.velocity.y < 0:
  112.                 self.velocity.y = 0
  113.         elif self.velocity.y < 0:
  114.             self.velocity.y += friction.y
  115.             if self.velocity.y > 0:
  116.                 self.velocity.y = 0
  117.  
  118.     def forward(self):
  119.         self.velocity += self.vector * self.speed
  120.         self.speed_cap()
  121.  
  122.     def get_vector(self):
  123.         vector = pygame.Vector2(0, 0)
  124.         vector.from_polar((1, self.angle))
  125.         vector.x, vector.y = vector.y, vector.x
  126.         return vector
  127.  
  128.     def move(self, delta):
  129.         self.center += self.velocity * delta
  130.         self.sprite.rect.center = self.center
  131.  
  132.     def reverse(self):
  133.         self.velocity -= self.vector * self.speed * 0.5
  134.         self.speed_cap()
  135.  
  136.     def rotate_left(self, delta):
  137.         self.angle = (self.angle + self.rotate_speed * delta) % 360
  138.         self.rotation()
  139.  
  140.     def rotate_right(self, delta):
  141.         self.angle = (self.angle - self.rotate_speed * delta) % 360
  142.         self.rotation()
  143.  
  144.     def rotation(self):
  145.         image = pygame.transform.rotate(self.orignal_image, self.angle)
  146.         self.sprite.image = image
  147.         self.sprite.rect = image.get_rect(center=self.center)
  148.         self.vector = self.get_vector()
  149.         self.velocity.rotate_ip(self.velocity.angle_to(self.vector))
  150.  
  151.     def speed_cap(self):
  152.         mspeed = self.max_speed * self.get_vector()
  153.         mspeed = abs(mspeed.elementwise())
  154.  
  155.         if self.velocity.x > 0:
  156.             self.velocity.x = min(self.velocity.x, mspeed.x)
  157.         else:
  158.             self.velocity.x = max(self.velocity.x, -mspeed.x)
  159.  
  160.         if self.velocity.y > 0:
  161.             self.velocity.y = min(self.velocity.y, mspeed.y)
  162.         else:
  163.             self.velocity.y = max(self.velocity.y, -mspeed.y)
  164.  
  165. class Keys:
  166.     def __init__(self, movement,
  167.                  up=(pygame.K_UP, pygame.K_w),
  168.                  down=(pygame.K_DOWN, pygame.K_s),
  169.                  left=(pygame.K_LEFT, pygame.K_a),
  170.                  right=(pygame.K_RIGHT, pygame.K_d)):
  171.  
  172.         self.up = up
  173.         self.down = down
  174.         self.left = left
  175.         self.right = right
  176.         self.movement = movement
  177.  
  178.     def update(self, delta, pressed):
  179.         if any([pressed[k] for k in self.up]):
  180.             self.movement.forward()
  181.         elif any([pressed[k] for k in self.down]):
  182.             self.movement.reverse()
  183.         else:
  184.             self.movement.apply_friction(delta)
  185.  
  186.         if any([pressed[k] for k in self.left]):
  187.             self.movement.rotate_left(delta)
  188.         elif any([pressed[k] for k in self.right]):
  189.             self.movement.rotate_right(delta)
  190.  
  191.         self.movement.move(delta)
  192.  
  193. class Player:
  194.     def __init__(self, center):
  195.         surface = pygame.Surface((6, 10), pygame.SRCALPHA)
  196.         surface.fill(color.firebrick)
  197.  
  198.         self.sprite = SimpleSprite(surface, center, "center")
  199.         self.movement = Movement(self.sprite)
  200.         self.keys = Keys(self.movement)
  201.  
  202.     def draw(self, surface):
  203.         self.sprite.draw(surface)
  204.  
  205.     def update(self, delta, pressed):
  206.         self.keys.update(delta, pressed)
  207.  
  208. class MainScene(Scene):
  209.     def __init__(self, manager):
  210.         Scene.__init__(self, manager)
  211.         self.player = Player(manager.rect.center)
  212.         self.position_template = "{:.2f}, {:.2f}"
  213.         position = self.position_template.format(*self.player.movement.velocity)
  214.         font = pygame.font.Font(None, 28)
  215.         self.str_position = Text(position, font, color.lawngreen, (10, 10))
  216.  
  217.     def on_draw(self, surface):
  218.         surface.fill(color.black)
  219.         self.player.draw(surface)
  220.         self.str_position.draw(surface)
  221.  
  222.     def on_update(self, delta):
  223.         pressed = pygame.key.get_pressed()
  224.         self.player.update(delta, pressed)
  225.         position = self.position_template.format(*self.player.movement.velocity)
  226.         self.str_position.render(position)
  227.  
  228. if __name__ == "__main__":
  229.     pygame.init()
  230.     manager = Manager("Example", 800, 600)
  231.     manager.scene = MainScene(manager)
  232.     manager.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement