Как сделать баллистическую траекторию для снаряда?
Мне нужна пушка, которая вращается нажатием стрелок (я уже это сделал), чтобы стрелять "металлическими" шариками, летящими по баллистической траектории (и на них действует сила сопротивления воздуха), и при столкновении с ракетами ("Rockets"), которые летят в цель ("Mansion"), сбивать эти самые ракеты и исчезать вместе с ними. Я не могу придумать способ поместить снаряды за дуло пушки и запустить их по баллистической траектории
Вот так программа выглядит у меня:
from random import randint
import sys
import pygame
import math
pygame.init()
run = True
width = 1280
height = 720
fps = 30
gameDisplay = pygame.display.set_mode((width, height))
pygame.display.set_caption('Air Defence')
clock = pygame.time.Clock()
pygame.time.set_timer(pygame.USEREVENT, 2000)
background = pygame.image.load('background.png').convert()
background = pygame.transform.smoothscale(background, gameDisplay.get_size())
mansion = pygame.image.load('mansion.png')
mansion = mansion.convert()
mansion.set_colorkey((0, 0, 0))
mansion = pygame.transform.scale(mansion, (mansion.get_width() // 6, mansion.get_height() // 6))
tower = pygame.image.load('tower.png')
tower = tower.convert()
tower.set_colorkey((0, 0, 0))
tower = pygame.transform.scale(tower, (tower.get_width() // 3, tower.get_height() // 3))
def blitRotate(surf, image, pos, originPos, angle):
image_rect = image.get_rect(topleft=(pos[0] - originPos[0], pos[2] - originPos[2]))
offset_center_to_pivot = pygame.math.Vector2(pos) - image_rect.center
rotated_offset = offset_center_to_pivot.rotate(-angle)
rotated_image_center = (pos[0] - rotated_offset.x, pos[1] - rotated_offset.y)
rotated_image = pygame.transform.rotate(image, angle)
rotated_image_rect = rotated_image.get_rect(center=rotated_image_center)
surf.blit(rotated_image, rotated_image_rect)
def blitRotate2(surf, image, topleft, angle):
rotated_image = pygame.transform.rotate(image, angle)
new_rect = rotated_image.get_rect(center=image.get_rect(topleft=topleft).center)
surf.blit(rotated_image, new_rect.topleft)
pygame.draw.rect(surf, (255, 0, 0), new_rect, 2)
try:
image = pygame.image.load('gun.png')
image = pygame.transform.scale(image, (image.get_width() // 10, image.get_height() // 10))
except:
text = pygame.font.SysFont('Times New Roman', 50).render('image', False, (255, 255, 0))
image = pygame.Surface((text.get_width() + 1, text.get_height() + 1))
pygame.draw.rect(image, (0, 0, 255), (1, 1, *text.get_size()))
image.blit(text, (1, 1))
w, h = image.get_size()
RIGHT = "to the right"
LEFT = "to the left"
STOP = "stop"
angle = 0
motion = STOP
r = pygame.image.load('rocket.png')
r = r.convert()
r.set_colorkey((0, 0, 0))
r = pygame.transform.scale(r, (r.get_width() // 25, r.get_height() // 25))
score = 5
class rocket(pygame.sprite.Sprite):
def __init__(self, x, speed, group):
pygame.sprite.Sprite.__init__(self)
self.mansion = mansion
self.image = r
self.rect = self.image.get_rect(center=(x, -100))
self.angle = 180 * (math.atan((980 - x) / (height - self.rect.centery))) / math.pi
self.speed = speed.rotate(-self.angle)
self.add(group)
self.image = pygame.transform.rotate(self.image, self.angle)
self.rect = self.image.get_rect(center=(x, -100))
self.score = score
def update(self, *args):
if self.rect.y < args[0] - 10:
self.rect.y += self.speed.y
self.rect.x += self.speed.x
else:
self.kill()
if self.rect.colliderect(mansion_on):
self.kill()
self.score -= 1
# elif self.rect.collidepoint()
def cRockets(group):
x = randint(20, width - 20)
speed = pygame.math.Vector2(0, randint(9, 10))
return rocket(x, speed, group)
rockets = pygame.sprite.Group()
cRockets(rockets)
ground = height - 70
ro = 100
black = (0, 0, 0)
white = (255, 255, 255)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, speedx, speedy):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((width, height))
self.image.fill(black)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.speedx = speedx
self.speedy = speedy
def update(self):
self.rect.x += self.speedx - 2
self.rect.y += self.speedy - 9.8
if self.rect.bottom < 0 or self.rect.right < 0 or self.rect.top > h or self.rect.left > w:
self.kill()
bullets = pygame.sprite.Group()
while run:
clock.tick(fps)
pos = (240, 475)
gameDisplay.fill(0)
gameDisplay.blit(background, (0, 0))
rx = randint(0, 1280)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
motion = LEFT
elif event.key == pygame.K_RIGHT:
motion = RIGHT
# elif event.key == pygame.K_SPACE:
# player.shoot()
elif event.type == pygame.KEYUP:
if event.key in [pygame.K_LEFT,
pygame.K_RIGHT]:
motion = STOP
elif event.type == pygame.USEREVENT:
cRockets(rockets)
if motion == LEFT:
blitRotate(gameDisplay, image, pos, (w / 2, h / 2), angle)
angle += 1
if angle > 90:
angle -= 1
elif motion == RIGHT:
blitRotate(gameDisplay, image, pos, (w / 2, h / 2), angle)
angle -= 1
if angle < -90:
angle += 1
elif motion == STOP:
blitRotate(gameDisplay, image, pos, (w / 2, h / 2), angle)
angle += 0
mansion_on = mansion.get_rect(center=(920, 590))
gameDisplay.blit(mansion, mansion_on)
tower_on = tower.get_rect(center=(240, 580))
gameDisplay.blit(tower, tower_on)
rockets.draw(gameDisplay)
pygame.display.update()
pygame.display.flip()
rockets.update(height)
pygame.quit()
exit()
Вот картинки которые я использовал для кода:
![tower.png]]6
Источник: Stack Overflow на русском