Почему мяч все еще подпрыгивает снизу экрана?

Я делаю простую игру в понг и написал большую часть кода.

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

Любые отзывы приветствуются! Заранее спасибо!

L1_base.py (мой базовый код):

import math
import random
import sys, pygame
from pygame.locals import *

import ball
import colors
import paddle

# draw the scene
def draw(screen, ball1, paddle1) :
   screen.fill((128, 128, 128))
   ball1.draw_ball(screen)
   paddle1.draw_paddle(screen)

#function to start up the main drawing
def main():

   pygame.init()
   width = 600
   height = 600
   screen = pygame.display.set_mode((width, height))

   ball1 = ball.Ball(300, 1, 40, colors.YELLOW, 0, 4)
   paddle1 = paddle.Paddle(200, 575, colors.GREEN, 100, 20)

   while 1:
      for event in pygame.event.get():
         if event.type == QUIT: sys.exit()
         elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
               paddle1.update_paddle('right', 35)
            if event.key == pygame.K_LEFT:
               paddle1.update_paddle('left', 35)

      ball1.test_collide_top_ball(0)
      ball1.test_collide_bottom_ball(600, paddle1)
      ball1.update_ball()
      draw(screen, ball1, paddle1)
      pygame.display.flip()

if __name__ == '__main__':
   main()

ball.py (содержит класс / методы шара):

import pygame

class Ball:
   def __init__(self, x, y, radius, color, dx, dy):
      self.x = x
      self.y = y
      self.radius = radius
      self.color = color
      self.dx = dx
      self.dy = dy

   def draw_ball(self, screen):
      pygame.draw.ellipse(screen, self.color,
         pygame.Rect(self.x, self.y, self.radius, self.radius))

   def update_ball(self):
      self.x += self.dx
      self.y += self.dy

   def test_collide_top_ball(self, top_height):
      if (self.y <= top_height) and (self.dy < 0):
         self.dy *= -1

   def test_collide_bottom_ball(self, coll_height, paddle):
      if (self.y >= coll_height - self.radius - (600 - paddle.y)) and (self.x  >= paddle.x) and (self.x <= paddle.x + paddle.width) and (self.dy > 0):
         self.dy *= -1

paddle.py (содержит класс / методы весла):

import pygame

class Paddle:
   def __init__(self, x, y, c, w, h):
       self.x = x
       self.y = y
       self.color = c
       self.width = w
       self.height = h

   def draw_paddle(self, screen):
      pygame.draw.rect(screen, self.color,
         pygame.Rect(self.x, self.y, self.width, self.height), 0)

   def update_paddle(self, dir, dx):
      if (dir == 'left'):
         self.x = max(self.x - dx, 0)
      else:
         self.x = min(self.x + dx, 600 - self.width)

   def get_left(self):
      if (self.x < 300):
         return self.x

   def get_right(self):
      if (self.x >= 300):
         return self.x

person Karen    schedule 07.04.2014    source источник


Ответы (1)


Вы пытались втиснуть слишком много всего в один if оператор в test_collide_bottom_ball, и это значительно усложнило отладку. В этом случае также проще рассмотреть все причины не self.dy *= -1, а не причины, по которым вам следует. Это переключение направлений является привилегией и должно происходить только в особых случаях.

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

 def test_collide_bottom_ball(self, coll_height, paddle):
    print paddle.x, paddle.width + paddle.x, self.x

    # shoot ball back to top when it has gone off the bottom
    if self.y > 600:
       self.y = 300
       return

    # ignore when the ball is far from the y access of the paddle
    if not self.y >= coll_height - self.radius - (600 - paddle.y):
       return

    # check that the current x plus raidus to find "too small" condition
    if self.x + self.radius <= paddle.x:
       print "self.x too small"
       return

    # for too big we have to consider the paddle width
    if self.x >= paddle.x + paddle.width:
       print "self.x too big"
       return

    # ok, looks like its time to switch directions!
    self.dy *= -1

P.S. используйте стандартную утилиту кодирования pep8. Кодировать после pep8 не сложнее, и это избавит вас от головной боли.

person Victory    schedule 07.04.2014
comment
Также вчера вечером был комментарий к вашим вопросам об отключении одной ошибкой в ​​_1 _ / _ 2_, потому что ось x начинается с 0. - person Victory; 07.04.2014