Advertisement
Windspar

Pygame 2D Camera Example

Mar 28th, 2023
790
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.66 KB | Gaming | 0 0
  1. import pygame
  2. import random
  3. import string
  4.  
  5. DEFAULT_ALLOW = string.ascii_letters + string.digits + ':,'
  6.  
  7. class LetterSprite(pygame.sprite.Sprite):
  8.     def __init__(self, letter, pos, line_pos):
  9.         super().__init__()
  10.         self.image = letter
  11.         self.line_pos = line_pos
  12.         self.rect = letter.get_rect(topleft=pos)
  13.  
  14. class SpritePen:
  15.     def __init__(self, fontname, size, color, bcolor=None, allowed=DEFAULT_ALLOW):
  16.         self.font = pygame.font.Font(fontname, size)
  17.         self.allowed = allowed
  18.         self.letters = {}
  19.  
  20.         for letter in allowed:
  21.             self.letters[letter] = self.font.render(letter, 1, color, bcolor)
  22.  
  23.     def render(self, text, pos=(0, 0), padding=(0, 0)):
  24.         result = pygame.sprite.Group()
  25.         lines = text.split('\n')
  26.         linesize = self.font.get_linesize()
  27.         y = pos[1]
  28.         for enumy, line in enumerate(lines):
  29.             for enumx, letter in enumerate(line):
  30.                 if letter in self.allowed:
  31.                     if enumx != 0:
  32.                         l = self.font.size(letter)[0]
  33.                         x = self.font.size(line[:enumx + 1])[0] - l
  34.                         x += pos[0] + padding[0] * enumx
  35.                     else:
  36.                         x = pos[0]
  37.  
  38.                     image = self.letters[letter]
  39.                     result.add(LetterSprite(image, (x, y), (enumx, enumy)))
  40.  
  41.             y += linesize + padding[1]
  42.         return result
  43.  
  44. # Camera is just a position that offset sprites. view.topleft is the offset.
  45. class Camera:
  46.     def __init__(self, area, view, speed):
  47.         self.view = view
  48.         self.area = area
  49.         self.speed = speed
  50.         self.center = pygame.Vector2(view.center)
  51.         self.sprites = pygame.sprite.Group()
  52.  
  53.     def draw(self, surface):
  54.         for sprite in self.sprites:
  55.             pos = pygame.Vector2(sprite.rect.topleft) - self.view.topleft
  56.             surface.blit(sprite.image, pos)
  57.  
  58.     def move(self, direction):
  59.         self.center += direction * self.speed
  60.         self.view.center = self.center
  61.         clamping_ip(self.area, self.view, self.center)
  62.  
  63.     def update(self, delta):
  64.         self.sprites.update(delta, self.area)
  65.  
  66. class BlockSprite(pygame.sprite.Sprite):
  67.     def __init__(self, image, position, vector, speed):
  68.         super().__init__()
  69.         self.image = image
  70.         self.rect = image.get_rect(center=position)
  71.         self.center = pygame.Vector2(self.rect.center)
  72.         self.vector = pygame.Vector2(vector)
  73.         self.speed = speed
  74.  
  75.     def update(self, delta, area):
  76.         self.center += self.vector * delta * self.speed
  77.         self.rect.center = self.center
  78.         clamping_ip(area, self.rect, self.center, self.vector)
  79.  
  80. def create_image(color, size):
  81.     surface = pygame.Surface(size)
  82.     surface.fill(color)
  83.     return surface
  84.  
  85. def clamping_ip(area, rect, center, vector=None):
  86.     if not area.contains(rect):
  87.         clamp = rect.clamp(area)
  88.         if clamp.x != rect.x:
  89.             rect.x = clamp.x
  90.             center.x = rect.centerx
  91.             if vector:
  92.                 vector.x = -vector.x
  93.  
  94.         if clamp.y != rect.y:
  95.             rect.y = clamp.y
  96.             center.y = rect.centery
  97.             if vector:
  98.                 vector.y = -vector.y
  99.  
  100. def main():
  101.     # Basic Pygame Setup
  102.     pygame.init()
  103.     pygame.display.set_caption("Example")
  104.     surface = pygame.display.set_mode((800, 600))
  105.     clock = pygame.time.Clock()
  106.     rect = surface.get_rect()
  107.     running = True
  108.     delta = 0
  109.     fps = 60
  110.  
  111.     # Variables
  112.     backgound = 'grey3'
  113.     area = pygame.Rect(0, 0, 1500, 1500)
  114.     camera = Camera(area, rect.copy(), 200)
  115.     pen = SpritePen(None, 30, 'skyblue')
  116.     fps_text = pen.render('fps: 0', (10, 10))
  117.     cam_pos = rect.w - 150, 10
  118.     cam_text = pen.render('pos: 0, 0', cam_pos)
  119.  
  120.     images = []
  121.     for i in range(10):
  122.         color = pygame.Color('black')
  123.         h = random.randint(0, 7)
  124.         if h in [0, 3, 4, 6]:
  125.             color.r = random.randint(120, 255)
  126.         elif h in [1, 3, 5, 6]:
  127.             color.g = random.randint(120, 255)
  128.         elif h in [2, 4, 5, 6]:
  129.             color.b = random.randint(120, 255)
  130.  
  131.         size = random.randint(20, 30)
  132.         size = size, size
  133.         images.append(create_image(color, size))
  134.  
  135.     for i in range(100):
  136.         image = random.choice(images)
  137.         position = random.randint(50, area.w - 50), random.randint(50, area.h - 50)
  138.         vector = pygame.Vector2()
  139.         vector.from_polar((1, random.randint(0, 360)))
  140.         speed = random.randint(50, 100)
  141.         sprite = BlockSprite(image, position, vector, speed)
  142.         camera.sprites.add(sprite)
  143.  
  144.     # Main Loop
  145.     while running:
  146.         for event in pygame.event.get():
  147.             if event.type == pygame.QUIT:
  148.                 running = False
  149.  
  150.         keys = pygame.key.get_pressed()
  151.         direction = pygame.Vector2()
  152.         if keys[pygame.K_w]:
  153.             direction.y -= 1
  154.  
  155.         if keys[pygame.K_s]:
  156.             direction.y += 1
  157.  
  158.         if keys[pygame.K_a]:
  159.             direction.x -= 1
  160.  
  161.         if keys[pygame.K_d]:
  162.             direction.x += 1
  163.  
  164.         if direction != pygame.Vector2():
  165.             direction.normalize_ip()
  166.             camera.move(direction * delta)
  167.             x, y = camera.view.topleft
  168.             cam_text = pen.render(f'pos: {x}, {y}', cam_pos)
  169.  
  170.         camera.update(delta)
  171.  
  172.         surface.fill(backgound)
  173.         camera.draw(surface)
  174.         cam_text.draw(surface)
  175.         fps_text.draw(surface)
  176.  
  177.         pygame.display.flip()
  178.         delta = clock.tick(fps) * 0.001
  179.         fps_text = pen.render(f'fps: {int(clock.get_fps())}', (10, 10))
  180.  
  181. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement