Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Edit. Fix aim bug. Added pivot to target.
- import pygame
- from pygame.sprite import Group, Sprite
- TRANSPARENT = 0, 0, 0, 0
- class ImageLoader:
- def __init__(self):
- self.tank = self.create_tank((50, 40), 'red')
- self.turret = self.create_turret((56, 20), 'red')
- self.target = self.create_target((20, 20))
- def create_tank(self, size, color):
- surface = pygame.Surface(size, pygame.SRCALPHA)
- surface.fill(TRANSPARENT)
- width, height = size
- h = int(height * 0.20)
- body = surface.get_rect().inflate(-8, - h * 2)
- pygame.draw.rect(surface, color, body)
- pygame.draw.rect(surface, 'gray30', (0, 0, width, h))
- pygame.draw.rect(surface, 'gray30', (0, height - h, width, h))
- return surface
- def create_turret(self, size, color):
- surface = pygame.Surface(size, pygame.SRCALPHA)
- surface.fill(TRANSPARENT)
- width, height = size
- body = 0, 0, height, height
- pygame.draw.rect(surface, color, body)
- pygame.draw.rect(surface, 'black', body, 1)
- offset_h = height * 0.25
- h = height - offset_h * 2
- turret = height, offset_h, width - height, h
- pygame.draw.rect(surface, 'gray30', turret)
- return surface
- def create_target(self, size):
- surface = pygame.Surface(size, pygame.SRCALPHA)
- surface.fill(TRANSPARENT)
- radius = min(size) // 2
- pygame.draw.circle(surface, 'white', (radius, radius), radius)
- pygame.draw.circle(surface, 'red', (radius, radius), radius - 2, 2)
- return surface
- class Scene:
- def __init__(self, display):
- self.display = display
- def on_draw(self, surface):
- pass
- def on_event(self, event):
- pass
- def on_update(self, delta):
- pass
- class Display:
- def __init__(self, caption, width, height, flags=0, fps=60):
- pygame.display.set_caption(caption)
- self.surface = pygame.display.set_mode((width, height), flags)
- self.rect = self.surface.get_rect()
- self.clock = pygame.time.Clock()
- self.running = True
- self.delta = 0
- self.fps = fps
- self.scene = Scene(self)
- def loop(self):
- while self.running:
- for event in pygame.event.get():
- self.scene.on_event(event)
- self.scene.on_update(self.delta)
- self.scene.on_draw(self.surface)
- pygame.display.flip()
- self.delta = self.clock.tick(self.fps) / 1000
- class Entity(Sprite):
- def __init__(self, image, position, anchor):
- super().__init__()
- self.original_image = image
- self.image = image
- self.rect = image.get_rect(**{anchor: position})
- self.center = pygame.Vector2(self.rect.center)
- def draw(self, surface):
- surface.blit(self.image, self.rect)
- def move(self, movement):
- self.center += movement
- self.rect.center = self.center
- def rotate(self, angle):
- self.image = pygame.transform.rotate(self.original_image, -angle)
- self.rect = self.image.get_rect(center=self.rect.center)
- class Pivot:
- def __init__(self, sprite, pivot, target=None):
- self.sprite = sprite
- self.pivot = pygame.Vector2(pivot)
- self.center = pygame.Vector2(sprite.center)
- self.target = target
- self.update()
- def aim(self, target_pos):
- # Fix wrong aim.
- angle = (target_pos - self.center).as_polar()[1]
- pivot = self.pivot.rotate(angle)
- center = self.center.rotate(angle)
- self.sprite.rotate(angle)
- self.update(pivot)
- def on_mousemotion(self, mpos):
- self.aim(mpos)
- def update(self, pivot=None):
- if pivot is not None:
- self.sprite.center = self.center + pivot
- print(pivot, ", ", self.sprite.center)
- else:
- self.sprite.center = self.center + self.pivot
- self.sprite.rect.center = self.sprite.center
- def update_aim(self):
- if self.target:
- self.aim(self.target.center)
- class Tank:
- def __init__(self, tank_image, turret_image, position, anchor):
- self.tank = Entity(tank_image, position, anchor)
- self.turret = Entity(turret_image, self.tank.center, 'center')
- self.pivot = Pivot(self.turret, (20, 0))
- self.sprites = Group(self.tank, self.turret)
- self.vector = pygame.Vector2()
- self.vector.from_polar((1, 0))
- self.rotate_speed = 22
- self.speed = 20
- def draw(self, surface):
- self.sprites.draw(surface)
- def on_mousemotion(self, mpos):
- self.pivot.on_mousemotion(mpos)
- def set_target(self, target):
- self.pivot.target = target
- self.pivot.update_aim()
- def update(self, delta):
- keys = pygame.key.get_pressed()
- # Rotate Tank
- if keys[pygame.K_a]:
- angle_movement = self.rotate_speed * delta
- self.vector.rotate_ip(-angle_movement)
- angle = self.vector.as_polar()[1]
- self.tank.rotate(angle)
- if keys[pygame.K_d]:
- angle_movement = self.rotate_speed * delta
- self.vector.rotate_ip(angle_movement)
- angle = self.vector.as_polar()[1]
- self.tank.rotate(angle)
- # Move Forward
- if keys[pygame.K_w]:
- movement = self.vector * self.speed * delta
- self.tank.move(movement)
- self.turret.move(movement)
- self.pivot.center += movement
- self.pivot.update_aim()
- # Move Backwards
- if keys[pygame.K_s]:
- movement = self.vector * self.speed * delta * 0.80
- self.tank.move(-movement)
- self.turret.move(-movement)
- self.pivot.center -= movement
- self.pivot.update_aim()
- class Target(Sprite):
- def __init__(self, image, center):
- super().__init__()
- self.image = image
- self.rect = image.get_rect(center=center)
- self.center = pygame.Vector2(center)
- def set_center(self, center):
- self.center = pygame.Vector2(center)
- self.rect.center = center
- class Game(Scene):
- def __init__(self, display):
- super().__init__(display)
- self.image = ImageLoader()
- self.target = Target(self.image.target, (self.display.rect.centerx, 50))
- self.tank = Tank(self.image.tank, self.image.turret, self.display.rect.center, 'center')
- self.tank.set_target(self.target)
- self.sprites = Group(self.target)
- def on_draw(self, surface):
- surface.fill('black')
- self.tank.draw(surface)
- self.sprites.draw(surface)
- def on_event(self, event):
- # Mouse Aim
- #if event.type == pygame.MOUSEMOTION:
- #self.tank.on_mousemotion(event.pos)
- # Lock On Target
- if event.type == pygame.MOUSEBUTTONDOWN:
- if event.button == 1:
- self.target.set_center(event.pos)
- self.tank.pivot.update_aim()
- elif event.type == pygame.QUIT:
- self.display.running = False
- def on_update(self, delta):
- self.tank.update(delta)
- pygame.init()
- display = Display("Tank Play", 800, 600)
- display.scene = Game(display)
- display.loop()
- pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement