Advertisement
Windspar

Example Tank 2 with turret pivot

May 23rd, 2024 (edited)
547
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.35 KB | Gaming | 0 0
  1. # Edit. Fix aim bug. Added pivot to target.
  2. import pygame
  3. from pygame.sprite import Group, Sprite
  4.  
  5. TRANSPARENT = 0, 0, 0, 0
  6.  
  7. class ImageLoader:
  8.     def __init__(self):
  9.         self.tank = self.create_tank((50, 40), 'red')
  10.         self.turret = self.create_turret((56, 20), 'red')
  11.         self.target = self.create_target((20, 20))
  12.  
  13.     def create_tank(self, size, color):
  14.         surface = pygame.Surface(size, pygame.SRCALPHA)
  15.         surface.fill(TRANSPARENT)
  16.         width, height = size
  17.         h = int(height * 0.20)
  18.         body = surface.get_rect().inflate(-8, - h * 2)
  19.         pygame.draw.rect(surface, color, body)
  20.         pygame.draw.rect(surface, 'gray30', (0, 0, width, h))
  21.         pygame.draw.rect(surface, 'gray30', (0, height - h, width, h))
  22.  
  23.         return surface
  24.  
  25.     def create_turret(self, size, color):
  26.         surface = pygame.Surface(size, pygame.SRCALPHA)
  27.         surface.fill(TRANSPARENT)
  28.         width, height = size
  29.  
  30.         body = 0, 0, height, height
  31.         pygame.draw.rect(surface, color, body)
  32.         pygame.draw.rect(surface, 'black', body, 1)
  33.         offset_h = height * 0.25
  34.         h = height - offset_h * 2
  35.         turret = height, offset_h, width - height, h
  36.         pygame.draw.rect(surface, 'gray30', turret)
  37.         return surface
  38.  
  39.     def create_target(self, size):
  40.         surface = pygame.Surface(size, pygame.SRCALPHA)
  41.         surface.fill(TRANSPARENT)
  42.         radius = min(size) // 2
  43.  
  44.         pygame.draw.circle(surface, 'white', (radius, radius), radius)
  45.         pygame.draw.circle(surface, 'red', (radius, radius), radius - 2, 2)
  46.  
  47.         return surface
  48.  
  49. class Scene:
  50.     def __init__(self, display):
  51.         self.display = display
  52.  
  53.     def on_draw(self, surface):
  54.         pass
  55.  
  56.     def on_event(self, event):
  57.         pass
  58.  
  59.     def on_update(self, delta):
  60.         pass
  61.  
  62. class Display:
  63.     def __init__(self, caption, width, height, flags=0, fps=60):
  64.         pygame.display.set_caption(caption)
  65.         self.surface = pygame.display.set_mode((width, height), flags)
  66.         self.rect = self.surface.get_rect()
  67.         self.clock = pygame.time.Clock()
  68.         self.running = True
  69.         self.delta = 0
  70.         self.fps = fps
  71.  
  72.         self.scene = Scene(self)
  73.  
  74.     def loop(self):
  75.         while self.running:
  76.             for event in pygame.event.get():
  77.                 self.scene.on_event(event)
  78.  
  79.             self.scene.on_update(self.delta)
  80.             self.scene.on_draw(self.surface)
  81.             pygame.display.flip()
  82.             self.delta = self.clock.tick(self.fps) / 1000
  83.  
  84. class Entity(Sprite):
  85.     def __init__(self, image, position, anchor):
  86.         super().__init__()
  87.         self.original_image = image
  88.         self.image = image
  89.         self.rect = image.get_rect(**{anchor: position})
  90.         self.center = pygame.Vector2(self.rect.center)
  91.  
  92.     def draw(self, surface):
  93.         surface.blit(self.image, self.rect)
  94.  
  95.     def move(self, movement):
  96.         self.center += movement
  97.         self.rect.center = self.center
  98.  
  99.     def rotate(self, angle):
  100.         self.image = pygame.transform.rotate(self.original_image, -angle)
  101.         self.rect = self.image.get_rect(center=self.rect.center)
  102.  
  103. class Pivot:
  104.     def __init__(self, sprite, pivot, target=None):
  105.         self.sprite = sprite
  106.         self.pivot = pygame.Vector2(pivot)
  107.         self.center = pygame.Vector2(sprite.center)
  108.         self.target = target
  109.         self.update()
  110.  
  111.     def aim(self, target_pos):
  112.         # Fix wrong aim.
  113.         angle = (target_pos - self.center).as_polar()[1]
  114.         pivot = self.pivot.rotate(angle)
  115.         center = self.center.rotate(angle)
  116.         self.sprite.rotate(angle)
  117.         self.update(pivot)
  118.  
  119.     def on_mousemotion(self, mpos):
  120.         self.aim(mpos)
  121.  
  122.     def update(self, pivot=None):
  123.         if pivot is not None:
  124.             self.sprite.center = self.center + pivot
  125.             print(pivot, ", ", self.sprite.center)
  126.         else:
  127.             self.sprite.center = self.center + self.pivot
  128.  
  129.         self.sprite.rect.center = self.sprite.center
  130.  
  131.     def update_aim(self):
  132.         if self.target:
  133.             self.aim(self.target.center)
  134.  
  135. class Tank:
  136.     def __init__(self, tank_image, turret_image, position, anchor):
  137.         self.tank = Entity(tank_image, position, anchor)
  138.         self.turret = Entity(turret_image, self.tank.center, 'center')
  139.         self.pivot = Pivot(self.turret, (20, 0))
  140.         self.sprites = Group(self.tank, self.turret)
  141.         self.vector = pygame.Vector2()
  142.         self.vector.from_polar((1, 0))
  143.         self.rotate_speed = 22
  144.         self.speed = 20
  145.  
  146.     def draw(self, surface):
  147.         self.sprites.draw(surface)
  148.  
  149.     def on_mousemotion(self, mpos):
  150.         self.pivot.on_mousemotion(mpos)
  151.  
  152.     def set_target(self, target):
  153.         self.pivot.target = target
  154.         self.pivot.update_aim()
  155.  
  156.     def update(self, delta):
  157.         keys = pygame.key.get_pressed()
  158.         # Rotate Tank
  159.         if keys[pygame.K_a]:
  160.             angle_movement = self.rotate_speed * delta
  161.             self.vector.rotate_ip(-angle_movement)
  162.             angle = self.vector.as_polar()[1]
  163.             self.tank.rotate(angle)
  164.  
  165.         if keys[pygame.K_d]:
  166.             angle_movement = self.rotate_speed * delta
  167.             self.vector.rotate_ip(angle_movement)
  168.             angle = self.vector.as_polar()[1]
  169.             self.tank.rotate(angle)
  170.  
  171.         # Move Forward
  172.         if keys[pygame.K_w]:
  173.             movement = self.vector * self.speed * delta
  174.             self.tank.move(movement)
  175.             self.turret.move(movement)
  176.             self.pivot.center += movement
  177.             self.pivot.update_aim()
  178.  
  179.         # Move Backwards
  180.         if keys[pygame.K_s]:
  181.             movement = self.vector * self.speed * delta * 0.80
  182.             self.tank.move(-movement)
  183.             self.turret.move(-movement)
  184.             self.pivot.center -= movement
  185.             self.pivot.update_aim()
  186.  
  187. class Target(Sprite):
  188.     def __init__(self, image, center):
  189.         super().__init__()
  190.         self.image = image
  191.         self.rect = image.get_rect(center=center)
  192.         self.center = pygame.Vector2(center)
  193.  
  194.     def set_center(self, center):
  195.         self.center = pygame.Vector2(center)
  196.         self.rect.center = center
  197.  
  198. class Game(Scene):
  199.     def __init__(self, display):
  200.         super().__init__(display)
  201.         self.image = ImageLoader()
  202.         self.target = Target(self.image.target, (self.display.rect.centerx, 50))
  203.         self.tank = Tank(self.image.tank, self.image.turret, self.display.rect.center, 'center')
  204.         self.tank.set_target(self.target)
  205.         self.sprites = Group(self.target)
  206.  
  207.     def on_draw(self, surface):
  208.         surface.fill('black')
  209.         self.tank.draw(surface)
  210.         self.sprites.draw(surface)
  211.  
  212.     def on_event(self, event):
  213.         # Mouse Aim
  214.         #if event.type == pygame.MOUSEMOTION:
  215.             #self.tank.on_mousemotion(event.pos)
  216.  
  217.         # Lock On Target
  218.         if event.type == pygame.MOUSEBUTTONDOWN:
  219.             if event.button == 1:
  220.                 self.target.set_center(event.pos)
  221.                 self.tank.pivot.update_aim()
  222.         elif event.type == pygame.QUIT:
  223.             self.display.running = False
  224.  
  225.     def on_update(self, delta):
  226.         self.tank.update(delta)
  227.  
  228. pygame.init()
  229. display = Display("Tank Play", 800, 600)
  230. display.scene = Game(display)
  231. display.loop()
  232. pygame.quit()
  233.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement