Python OO — игра с пушкой pygame. Не удается переместить пушечное ядро

#python #move #pygame

#python #переместить #pygame

Вопрос:

В настоящее время я пытаюсь работать над домашним заданием для моего класса разработки программного обеспечения. Мы создаем объектно-ориентированную пушечную игру. Нам просто нужно создать пушку и выстрелить пушечным ядром.

В настоящее время я могу получить свой код для создания пушечного ядра в точке дульного среза пушки, но, к сожалению, функция перемещения не перемещает пушечное ядро под углом вверх (сначала попробуйте это сделать, прежде чем запускать фактический пушечный выстрел). Вместо этого пушечное ядро (которое я сделал красным для удобства просмотра, если оносоздается в точке дульного среза пушки) остается на месте, и я мельком увидел, что сама пушка движется в правом нижнем углу. Я озадачен тем, что я мог сделать неправильно. Или почему я не могу заставить мяч двигаться так, как нужно.

     import pygame
    from colors import color

class Cannonball(object):
'''
classdocs
'''
    _x = 135
    _y = 310

    def __init__(self):
        '''
        Constructor for cannonball. Initiates x and y at initial values
        of x == 135 and y == 310. at 30 FPS 
        '''
        self._x = Cannonball._x
        self._y = Cannonball._y
        clock = pygame.time.Clock()
        time_passed = clock.tick(30)
        time_passed_seconds = time_passed / 1000.0


    def draw(self, screen):  
        '''
        Draws the cannonball
        '''      
        sprite = pygame.draw.circle(screen, color["red"], (self._x,self._y), 5)
        return sprite

    def move(self, screen, time_passed):
        '''
        initiates the cannonball to move until its past the screen
        '''
        speed = 50
        self._x  = speed time_passed
        self._y -= speed time_passed    
        pygame.display.flip()
  

Вот мой класс пушечного ядра

     import pygame
    import sys
    from cannon import Cannon
    from cannonball import Cannonball
    from colors import color

    pygame.init()
    '''create the GUI window'''
    screen = pygame.display.set_mode((640,480))
    pygame.display.set_caption("Cannon Game")       
    background = screen.fill(color["white"])

    clock = pygame.time.Clock()
    '''draw the Cannon onto the window'''
    aCannon = Cannon
    aCannon.draw(aCannon, screen)
    pygame.display.flip()

    while True: 
        '''handle keydown and quit events for Cannon Game. Space bar
        fires the cannonball
        '''
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                 if event.key == pygame.K_SPACE: 
                 aCannonball = aCannon.fire(screen)
                 cannon_ball = True
            if cannon_ball == True:
                 aCannonball.draw(screen)
                 aCannonball.move(screen, time_passed)
                 pygame.display.flip()
  

Это мой драйвер. Пытаюсь сохранить это простым в настоящее время, поскольку это помогло мне создать вещи до сих пор.

     import pygame
    from colors import color
    from cannonball import Cannonball

    class Cannon (object):
        '''
        classdocs
        '''

    def __init__(self):
            '''
            Constructor
            '''


        def draw(self, screen):
            pygame.draw.circle(screen, color["black"], (40,400), 20)
            pygame.draw.polygon(screen, color["black"], ([30,400], [135, 300], [150,          320], [50,400]), 0)

        def fire (self, screen):   
            print("Fire") //used this as a tester to make sure the fire call worked before attempting to have a cannonball created and move. 
            aCannonball = Cannonball()
            aCannonball.draw(screen)
            aCannonball.move(screen)
  

И, наконец, мой класс cannon, который содержит функцию fire, которая создает пушечное ядро, выводит его в графический интерфейс и инициирует его перемещение.

Я все еще пытаюсь выяснить, что я мог сделать неправильно, но любая помощь будет с радостью оценена.

РЕДАКТИРОВАТЬ: я обнаружил проблему с кодом, в котором мое пушечное ядро не двигалось. Я умножал скорость на прошедшее время, а не добавлял. Оно исчезнет с экрана почти сразу, прежде чем его можно будет увидеть.

Спасибо за помощь! Может быть, я смогу пройти мимо этого в дуговой огонь.

Комментарии:

1. Вам нужно сделать отступ в ваших методах в классе cannonball, в настоящее время они не принадлежат этому классу.

2. Они имеют отступы в коде. Должно быть, я неправильно отформатировал эту часть кода при попытке поместить в блок кода. Я отредактировал блок кода, чтобы исправить это.

3. отступы _x и _y также указаны в коде? (я предполагаю, что пока они есть)

4. Они есть. И спасибо за ваш вклад. Я пытаюсь переработать свой код.

Ответ №1:

Есть несколько проблем с фреймворком, который вы опубликовали здесь:

  1. Методы и переменные не имеют отступов в CannonBall классе и, следовательно, являются частью глобальной области видимости, а не самого класса.

  2. В методе move не должно быть цикла while, вместо этого попробуйте структурировать свою игру, аналогично следующему коду.

  3. То pygame.display , что находится в вашем классе cannonball, не совпадает pygame.display с тем, что выполняется в вашей основной программе, поэтому основной дисплей не будет обновляться, чтобы сделать то, что вы делаете, вам нужно передать отображение в основной программе классу cannonball для его обновления.

  4. Вместо использования Cannon и CannonBall вам нужно использовать Cannon() и CannonBall() для инициализации конструкторов этих классов.

Игровой фреймворк:

 while True: #main loop  
    handle input  
    update spritee 
    draw to screen
  

И переместите все остальные циклы из классов спрайтов (в вашем случае cannonball), потому что пока это выполняется, ваша программа не может получать входные данные или обновлять другие спрайты.

Рекомендация по идентификатору изменяет перемещение на (записывается в псевдокоде):

 def move(self, screen, time_passed):
    x  = speed*time_passed;
    y  = speed*time_passed;
    if(x out of screen remove sprite);
    if(y out of screen remove sprite);
  

Комментарии:

1. Спасибо, мне потребовалось некоторое время, чтобы разобраться, но ваше руководство очень помогло! Однако частью этого было выяснение, почему оно не будет двигаться, и это было. Он просто двигался слишком далеко, слишком быстро. x = speed time_passed меня достучался.

2. Это приятно слышать, попробуйте использовать speed*time_passed вместо этого, но снижайте скорость, пока не достигнете скорости, которой вы довольны, причина * в том, что вы хотите поддерживать постоянную скорость программы независимо от того, насколько быстр компьютер. Также, пожалуйста, отметьте как ответ, если на ваш вопрос будет дан ответ, это поможет мне и всем, у кого похожие проблемы 🙂

3. Думал, что я пометил как ответил. Это сейчас. Сейчас я работаю над превышением скорости * time_passed и пытаюсь фактически включить дугу, которую она должна запустить. a может быть немного сложнее, чем я думал. Думаю, это может быть то, как я объявляю свои переменные и метод перемещения в основном цикле. Так близко, но я чувствую себя так далеко.

Ответ №2:

На самом деле вы не создали экземпляр пушечного ядра — ваша переменная aCannonball — это просто ссылка на класс. Вам нужно вызвать класс, чтобы создать его экземпляр. Как только вы это сделаете, вы можете удалить повторяющиеся ссылки на Cannonball в вызовах ваших методов.

Ответ №3:

Я написал аналогичный класс для игры, которую мне нужно было создать. Может быть, это поможет:

 '''
Created on Oct 2, 2011

@author: Mac Spinks
'''
import math
import pygame

class Cannonball(object):

    RADIUS = 4

    def __init__(self, initial_x, initial_y, launch_angle, launch_velocity, time_interval):
        self.x = initial_x
        self.y = initial_y
        self.time_interval = time_interval
        self.angle = launch_angle
        self.x_velocity = launch_velocity*math.cos(self.angle)
        self.y_velocity = launch_velocity*math.sin(self.angle)
        self.is_flying = True
        self.x_delta = self.time_interval * self.x_velocity

    def move(self):

        prev_y_velocity = self.y_velocity
        self.y_velocity = self.y_velocity - (9.8 * self.time_interval)
        self.y = (self.y   (self.time_interval * 
                             ((prev_y_velocity   self.y_velocity)/ 2)))
        self.y = max(self.y, 0)
        self.x  = (self.x_delta)
        self.container = pygame.Rect(self.x - self.RADIUS, self.y - self.RADIUS, self.RADIUS*2, self.RADIUS*2)
        self.is_flying = (self.y > 0)
        self.hit_ground = (self.y <= 0)