Итак, я пытаюсь сделать кривую пули в форме спирали.
Однако в итоге пули замирают на месте и движутся по кругу, а не вперед.
Вот мой код класса пули:
class Bullet(pygame.sprite.Sprite): #bullet class
def __init__(self, pos, img, angle=0, speed=10, acceleration=0, curve=10):
super().__init__()
#import image.
self.dir = angle
self.angle = (180 / math.pi) * -angle - 90
#turns towards the mouse
self.image = pygame.transform.rotate(img, self.angle)
self.rect = self.image.get_rect()
self.pos = list(pos)
self.spd = speed
self.acl = acceleration
self.curve = curve
self.wave = 0
#start lifetime of bullet
self.born = pygame.time.get_ticks()
def update(self):
#destroys itself if more than 10 secs have past from birth
self.live = pygame.time.get_ticks()
if self.live - self.born > 10000:
bullets.remove(self)
all_sprites_list.remove(self)
#update stats of bullet
self.dir += self.curve
self.spd += self.acl
#move the bullet
self.pos[0] += math.cos(self.dir) * self.spd
self.pos[1]+= math.sin(self.dir) * self.spd
self.rect.center = self.pos
Вот пример, который создает спиралевидные пули при щелчке правой кнопкой мыши. Сгенерированные щелчком левой кнопки мыши пули перемещаются горизонтально.
Я закомментировал команду заполнения рамки, чтобы вы могли видеть путь, по которому движется пуля.
import pygame
import math
import random
width = 800
height = 600
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
class Bullet(pygame.sprite.Sprite):
"""Horizontally travelling bullet"""
def __init__(self, pos, color = "grey16"):
super().__init__()
self.image = pygame.Surface((12, 5))
self.image.fill(color)
self.rect = self.image.get_rect(center=pos)
def move(self):
"""Move the bullet."""
self.rect.x += 5
def update(self):
"""Move and check for offscreen disposal"""
self.move()
# Remove the bullet if it flies up off the screen
if not 0 < self.rect.x < width + 12:
# print(f"Destroying {self} {self.rect.center} X")
self.kill() # Remove the sprite from all sprite groups.
elif not 0 < self.rect.y < height:
# print(f"Destroying {self} {self.rect.center} Y")
self.kill()
class SpiralBullet(Bullet):
"""Bullet sprite that moves in a spiral"""
def __init__(self, pos):
super().__init__(pos, "violetred")
# need to track the age to determine spiral position
self.start_tick = pygame.time.get_ticks()
self.start_pos = pos
self.angv = 0.1 # Angular Velocity
self.v = 2.0 # Velocity
def move(self):
"""Move in a spiral pattern"""
dt = pygame.time.get_ticks() - self.start_tick
if dt > 0:
dt = dt / 100 # slow it down
self.rect.x = (self.v * dt) * math.cos(self.angv * dt) + self.start_pos[0]
self.rect.y = (self.v * dt) * math.sin(self.angv * dt) + self.start_pos[1]
class Target(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((30, 50))
self.image.fill("orange")
self.rect = self.image.get_rect()
# create at the right of the screen
self.rect.x = width // 1.2
self.rect.y = random.randint(50, height - 50)
self.lives = 3
def update(self):
if self.lives <= 0:
self.kill() # Remove the sprite from all sprite groups.
# Create Groups for tracking sprites
all_sprites_list = pygame.sprite.Group()
bullets = pygame.sprite.Group()
targets = pygame.sprite.Group()
score = 0
screen.fill("turquoise") # initial fill incase we disable per frame fill
done = False
while not done:
## Handle Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
# Click a mouse button to instantiate a bullet.
if event.button == 3: # right-click for SpiralBullet
bullet = SpiralBullet(event.pos)
all_sprites_list.add(bullet)
bullets.add(bullet)
else:
bullet = Bullet(event.pos)
all_sprites_list.add(bullet)
bullets.add(bullet)
## Game State update
# Create a target if there aren't any
if not targets:
target = Target()
all_sprites_list.add(target)
targets.add(target)
# Call the update() method on all the sprites.
all_sprites_list.update()
# Check which bullets have collided with the Target.
collided_bullets = pygame.sprite.groupcollide(bullets, targets, True, False)
for bullet in collided_bullets:
score += 1 # Increment the score.
target.lives -= 1 # Decrement the lives.
## Draw a frame
# screen.fill("turquoise") # comment to see path
all_sprites_list.draw(screen)
## Update the display
pygame.display.flip()
pygame.display.set_caption(f"Score: {score}")
clock.tick(60)
pygame.quit()
Это покажет что-то вроде:
Здесь нижняя оранжевая цель была создана первой и была поражена двумя спиральными пулями и горизонтальной пулей, что привело к появлению более высокой цели.
Добро пожаловать в stackoverflow.com. Вы должны объяснить свою проблему так, как мы ее полностью понимаем, просто прочитав ваш вопрос. Здесь нам нужно открыть внешние ссылки, чтобы понять проблему. Пожалуйста, отредактируйте свой вопрос