Pygame Pong - как приписать мою систему оценки и обнаружения столкновений - PullRequest
2 голосов
/ 31 октября 2019

Эй, я работаю над понгом и, несмотря на все мои усилия, я продолжаю сталкиваться с одной и той же проблемой;система подсчета очков не появляется в окне, когда я запускаю код. Мне сказали, что мне нужно инициализировать такие атрибуты, как система подсчета очков, мяч и весла, и я думаю, что я сделал это для мяча и весла, хотя я не совсем понимаю, что это значит, так как этот курс - самое далекое от доброты по отношению к студентамкто новичок в питоне. Но я полагаю, что я не сделал этого для системы начисления очков, поскольку она не отображается на экране. Я боролся с этими прошлыми несколькими неделями и все еще не нашел способа исправить это, и мне нужно сдать эту следующую неделю, которая заставляет меня волноваться. Буду признателен, если вы объясните мне, что я сделал не так и что означает инициализирующий атрибут, а также проверите мои коды для обнаружения столкновений! Большое спасибо всем вам!! (Между прочим, это всегда происходит и меня сильно смущает, так как я не получаю сообщения об ошибке, но система подсчета очков не работает так, как я ожидал)

# Pong V2
# Pong game needs two players and players try to prevent the ball from hitting 
# the edge of the screen of their side. If the ball hits the edge of the window,
# the counterpart of the player who couldn't defence the wall gains a point. 
# When one of the players reach 11 points, game ends and the player with higher
# points win the game. Players and move the paddles of their own by pressing
# some keys and ball bounces off when the ball has hit the front part of the 
# paddle but passes through when they hit the back part of the paddle. 
# wall, game continuing until the player presses 'x' button to close the window, 
# paddles on the screen but cannot be moved. 
# Version 2 of Pong implies the scoring system and game ending when someone hits
# 11 scores. Also, now collision detection for the paddles and the ball has been
# added as a new feature even though still player cannot move the paddles. 


import pygame
from random import randint

def main():
   # initialize all pygame modules (some need initialization)
   pygame.init()
   # create a pygame display window
   pygame.display.set_mode((500, 400))
   # set the title of the display window
   pygame.display.set_caption('Pong')   
   # get the display surface
   w_surface = pygame.display.get_surface() 
   # create a game object
   game = Game(w_surface)
   # start the main game loop by calling the play method on the game object
   game.play() 
   # quit pygame and clean up the pygame window
   pygame.quit() 


class Game:


   def __init__(self, surface):
      # Initialize a Game.
      self.surface = surface
      self.bg_color = pygame.Color('black')

      self.FPS = 60
      self.game_Clock = pygame.time.Clock()
      self.close_clicked = False
      self.continue_game = True

      #iniotialize the ball
      self.ball = Ball('white', 5, [250, 200], [1, 2], self.surface)
      self.max_frames = 150
      self.frame_counter = 0


      # initialize paddles
      self.paddleA = pygame.Rect((70, 170), (10, 60))    
      self.paddleB = pygame.Rect((415, 170), (10, 60))

      # initialize paddles
      self.scoreA = 0
      self.scoreB = 0



   def draw_score_A(self):
      # this method draws the player's score in the top-left corner of the
      # game window.
      strscoreA = str(self.scoreA)
      font_color = pygame.Color('white')
      font_bg    = pygame.Color('black')
      font       = pygame.font.SysFont("arial", 72)
      text_img   = font.render(strscoreA, True, font_color, font_bg)     
      text_pos   = (0, 0)
      self.surface.blit(text_img, text_pos)             

   def draw_score_B(self):
      # this method draws the player's score in the top-right corner of the
      # game window.
      strscoreB = str(self.scoreB)
      font_color = pygame.Color('white')
      font_bg    = pygame.Color('black')
      font       = pygame.font.SysFont("arial", 72)
      text_img   = font.render(strscoreB, True, font_color, font_bg)     
      text_pos   = (425,0)
      self.surface.blit(text_img, text_pos)             


   def update_score(self):
      # check if the ball has hit the left or right side edge and update score
      # if the ball hit left side, scoreB goes up by 1 and if the ball hit the right
      # side the scoreA goes up by 1. 

      if self.ball.center[0] < self.ball.radius:
         self.scoreB += 1
      if self.ball.center[0] + self.ball.radius > self.surface.get_width():
         self.scoreA += 1

      return self.scoreA, self.scoreB

   def play(self):
      # Play the game until the player presses the close box.
      # - self is the Game that should be continued or not.

      while not self.close_clicked:  # until player clicks close box
         # play frame
         self.handle_events()         
         self.draw()
         self.update_score()
         self.draw_score_A()
         self.draw_score_B()
         if self.continue_game:
            self.update()
            self.decide_continue()
         self.game_Clock.tick(self.FPS) # run at most with FPS Frames Per Second



   def handle_events(self):
      # Handle each user event by changing the game state appropriately.
      # - self is the Game whose events will be handled

      events = pygame.event.get()
      for event in events:
         if event.type == pygame.QUIT:
            self.close_clicked = True

   def draw(self):
      # Draw all game objects.

      self.surface.fill(self.bg_color) # clear the display surface first       
      # draw ball on the surface
      self.ball.draw()
      # draw both paddles on the surface
      paddleA = pygame.Rect((70, 170), (10, 60))
      self.paddleA = pygame.draw.rect(self.surface, (255, 255, 255), paddleA)
      paddleB = pygame.Rect((415, 170), (10, 60))
      self.paddleB = pygame.draw.rect(self.surface, (255, 255, 255), paddleB)
      pygame.display.update() # make the updated surface appear on the display


   def collision_detection(self):
      # figure out if the paddle and the ball has collide or not. 
      # If the ball has hit the front of the paddle, it is recognizes as 
      # a collision and bounces off to the opposite direction. However
      # if the ball has hit the backside of the paddle, this is not 
      # considered as a collision and this will not make the ball bounce of but
      # go through the paddle.We need to check if the center of the ball has passed
      # the center of the paddle or not and for this we will use rect.collidepoint

      if self.paddleA.collidepoint(self.center) and self.velocity[index] > 0 is True:
         self.velocity[index] = self.velocity[index]
      elif self.paddleA.collidepoint(self.center) and self.velocity[index] < 0 is True:
         self.velocity[index] = - self.velocity[index]
      elif self.paddleB.collidepoint(self.center) and self.velocity[index] > 0 is True:
         self.velocity[index] = - self.velocity[index]
      elif self.paddleB.collidepoint(self.center) and self.velocity[index] < 0 is True:
         self.velocity[index] = self.velocity[index]



   def update(self):
      # Update the game objects for the next frame.

      self.ball.move()
      self.frame_counter += self.frame_counter 


   def decide_continue(self):
      # Check and remember if the game should continue
      # if the score of one of the players reaches 11, the game should end.
      # thus we need to check if anyone's score has reached 11 or not and 
      # decide if we'll continue the game or not.

      if self.scoreA == 11 or self.scoreB == 11 : 
         self.continue_game = False



class Ball:
   # An object in this class represents a ball that moves 

   def __init__(self, ball_color, ball_radius, ball_center, ball_velocity, 
                 surface):
      # Initialize a ball.
      # - self is the ball to initialize
      # - color is the pygame.Color of the ball
      # - center is a list containing the x and y int
      #   coords of the center of the dot
      # - radius is the int pixel radius of the ball
      # - velocity is a list containing the x and y components
      # - surface is the window's pygame.Surface object

      self.color = pygame.Color(ball_color)
      self.radius = ball_radius
      self.center = ball_center
      self.velocity = ball_velocity
      self.surface = surface



   def move(self):
      # Change the location of the ball by adding the corresponding 
      # speed values to the x and y coordinate of its center

      # we need the height and width of the screen to determine when ball
      # should change their direction of motion (bounce)
      screen_width = self.surface.get_width()
      screen_height = self.surface.get_height()        

      # updates the ball's position based on its velocity and also bounces the
      # ball off a wall if it  gets too close
      screen_size = (screen_width, screen_height)
      for index in range(0, len(self.center)):
         self.center[index] += self.velocity[index]               
         if (self.center[index] <= 0 + self.radius or self.center[index] >= 
             screen_size[index] - self.radius):
            self.velocity[index] = -self.velocity[index] 



   def draw(self):
      # Draw the ball on the surface

      pygame.draw.circle(self.surface, self.color, self.center, self.radius)






main()

1 Ответ

2 голосов
/ 31 октября 2019

Код вызывает draw() (для перекраски и очистки экрана), а , а затем вызывает draw_score_A() и draw_score_B() без очистки. Таким образом, изменения, сделанные функциями draw_score_, никогда не будут видны пользователю.

Если у вас есть функция draw() - заставьте ее нарисовать все . Это сохраняет все операции вытяжки и промывки в одном месте. Конечно, функция draw() вызывает другие функции для рисования, но все начинается с одного места.

def draw( self ):
    # Draw all game objects.
    # clear the display surface first       
    self.surface.fill( self.bg_color ) 

    # draw ball on the surface
    self.ball.draw()

    # draw both paddles on the surface
    pygame.draw.rect( self.surface, ( 255, 255, 255 ), self.paddleA )
    pygame.draw.rect( self.surface, ( 255, 255, 255 ), self.paddleB )

    # Paint the scores
    self.draw_score_A()
    self.draw_score_B()

    # make the updated surface appear on the display
    pygame.display.update() 

Кроме того, ваша функция draw(), кажется, переопределяет paddleA и paddleB как часть рисунка. Я исправил это в версии выше.

...