Перемещение кометы в пигме - PullRequest
4 голосов
/ 10 февраля 2020

Added a picture

Я хочу, чтобы коммент в пигаме стрелял по экрану. Вот мой класс комментариев

class Commet:
    def __init__(self):
        self.x  = -10
        self.y = 10
        self.radius = 20
        self.commet = pygame.image.load(r"C:\Users\me\OneDrive\Documents\A level python codes\final game\commet.png")
        self.commet = pygame.transform.scale(self.commet, (self.radius, self.radius))
        self.drop = 0.0000009
        self.speed = 2
        self.pos = 0
        self.commets = []

Затем я добавил 20 комментариев в список self.commets.

  def tail(self, n): # n is a variable used to denote the length of the self.commets
        for i in range(n):
            if len(self.commets) <= n - 1:
                self.commets.append(Commet())

У меня две проблемы. Первой проблемой является перемещение комета. Чтобы переместить его, я сделал это

def move_tail(self):
    for c in  self.commets:
        c.x += self.speed
    for i in range(len(self.commets) - 1):
         self.commets[i].y += ((self.commets[i + 1].x) ** 2) * self.drop

Для координаты х я просто добавил 2 к его значению в каждом кадре. Тем не менее, для значения y комета, я хочу, чтобы он производил эффект, похожий на хвост. Я попытался присвоить значение y комета квадрату x значения комета в индексной позиции над кометом, на который мы ссылаемся в списке self.commets. Я ожидал, что кометы будут следовать друг за другом вдоль общая кривая x = y ** 2 квадради c. Они следуют по кривой, но все с одинаковой скоростью (я ожидал, что они будут следовать с разной скоростью, потому что все комментарии имеют разные значения x), что дает мне эффект, похожий на хвост. Как я смогу создать этот эффект, похожий на хвост?

Вторая часть моего вопроса заключается в том, что я хочу, чтобы комментарии, следующие за первым, становились все меньше и меньше. Я попытался уменьшить значение radius, которое используется для масштабирования импортированного изображения. Код выглядит следующим образом:

    # Decrease radius
    for i in range(n):
        self.commets[i].radius = i + 1

Когда я распечатываю значения радиуса комментариев на консоли, они варьируются от 1 до 20, как я и ожидаю, но размер изображения, которое появляется на экране одинаково для всех комментариев в списке. Следующий код показывает, как я переворачиваю комментарий

  for i in range(n):
        self.commets[i].pos = i * 10 #  This line maintains a certain x- distance between commets

    for c in self.tails:
        D.blit(c.commet, (c.x - c.pos, c.y))

        if self.pos >= n:
            self.pos = n

1 Ответ

3 голосов
/ 10 февраля 2020

Если вы хотите, чтобы ваша комета летала слева направо на экране FullHD.

Комета должна начинаться с левой стороны в точке с координатой yy 900, а затем достигать своей наивысшей точки при x = 1400 и y = 100, а затем падает до 600 в правой части экрана.

Comet flight

Обычно параболой является y = ax² + bx + c.

Чтобы быть независимым от разрешения экрана, вы, конечно, должны рассчитать эти значения из некоторого процента, скажем, 900 ~ высота экрана * 83%, 600 ~ высота экрана * 55%, 1400 ~ ширина экрана * 73%, 100 ~ высота экрана * 9%

Имея три заданные точки, вы можете вычислить параболу:

class ParabolaFrom3Points:
    def __init__(self, points: list):
        self.a = (points[0][0] * (points[1][1] - points[2][1]) + points[1][0] * (
                points[2][1] - points[0][1]) + points[2][0] * (points[0][1] - points[1][1])) / (
                         (points[0][0] - points[1][0]) * (points[0][0] - points[2][0]) * (
                         points[2][0] - points[1][0]))
        self.b = (points[0][0] ** 2 * (points[1][1] - points[2][1]) + points[1][0] ** 2 * (
                points[2][1] - points[0][1]) + points[2][0] ** 2 * (points[0][1] - points[1][1])) / (
                         (points[0][0] - points[1][0]) * (points[0][0] - points[2][0]) * (
                         points[1][0] - points[2][0]))
        self.c = (points[0][0] ** 2 * (points[1][0] * points[2][1] - points[2][0] * points[1][1]) +
                  points[0][0] * (points[2][0] ** 2 * points[1][1] - points[1][0] ** 2 * points[2][1]) +
                  points[1][0] * points[2][0] * points[0][1] * (points[1][0] - points[2][0])) / (
                         (points[0][0] - points[1][0]) * (points[0][0] - points[2][0]) * (
                         points[1][0] - points[2][0]))

    def y(self, x: int) -> int:
        return int(self.a * x ** 2 + self.b * x + self.c)

Тогда комета довольно проста. Ему просто нужно знать функцию параболы, а затем вычислить y по x.

class Comet:
    def __init__(self, radius: int, para: ParabolaFrom3Points):
        self.x = -radius  # Be invisible at the beginning
        self.radius = radius
        self.para = para

    def move(self, x):
        self.x = x

    def paint(self, screen):
        x = self.x
        radius = self.radius
        for tail in range(20):
            pygame.draw.circle(screen, [255, 255, 255], (int(x), self.para.y(x)), radius)
            x = x - radius / 2
            radius -= 1

Тестовый код:

import pygame

pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((1920, 1080))

pygame.display.set_caption('Comet example')
comet = Comet(20, ParabolaFrom3Points([(0, 1080 * 0.83), (1920 * 0.73, 1080 * 0.12), (1920, 1080 * 0.55)]))
for x in range(-20, 1920 + 200, 3):
    comet.move(x)
    comet.paint(window)
    clock.tick(90)
    pygame.display.flip()
    window.fill([0, 0, 0])

pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...