I'm creating a tennis game, similar to pong but will be much more similar to real tennis (ie ability to control the direction and type of your shot). I think I've got the collision detection with the ball and the player figured out, but when the player collides with the ball it moves a few pixels then stops. I need it to keep going like in pong. Not sure if the problem is with the collision detection or just with something else in the code.
import pygame
pygame.init()
# Define some colors
BLACK = (0, 0, 0)
OUT = (193, 58, 34)
COURT = (69, 150, 81)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
SKIN = (232, 214, 162)
ballspeed = 2
# Create the screen
windowsize = (700, 500)
screen = pygame.display.set_mode(windowsize)
pygame.display.set_caption('Tennis')
# Player Sprites
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Robert_tennis.png")
self.rect = self.image.get_rect()
self.rect.center = (360, 480)
self.speedx = 0
self.speedy = 0
def update(self):
self.speedx = 0
self.speedy = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speedx = -4
if keystate[pygame.K_RIGHT]:
self.speedx = 4
self.rect.x += self.speedx
if self.rect.right > 700:
self.rect.right = 700
if self.rect.right < 0:
self.rect.left = 0
if keystate[pygame.K_UP]:
self.speedy = -5
if keystate[pygame.K_DOWN]:
self.speedy = 3
self.rect.y += self.speedy
if self.rect.y < 235:
self.rect.y = 235
if self.rect.y < 0:
self.rect.y = 0
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("tennisball.png")
self.rect = self.image.get_rect()
self.rect.center = (360, 325)
def update(self):
if tennisball.rect.colliderect(robert):
self.rect.y -= 2
#Add myself
all_sprites = pygame.sprite.Group()
robert = Player()
tennisball = Ball()
all_sprites.add(robert)
all_sprites.add(tennisball)
carryOn = True
clock = pygame.time.Clock()
while carryOn:
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carryOn = False
all_sprites.update()
# Fill the screen with a sky color
screen.fill(OUT)
# Draw the court
pygame.draw.rect(screen, COURT, [175, 0, 350, 500])
pygame.draw.line(screen, WHITE, (170,500), (170,0), 10)
pygame.draw.line(screen, WHITE, (520,500), (520,0), 10)
pygame.draw.line(screen, WHITE, (170,130), (520,130), 10)
pygame.draw.line(screen, WHITE, (170,370), (520,370), 10)
pygame.draw.line(screen, WHITE, (340,130), (340,370), 10)
pygame.draw.line(screen, BLACK, (170,250), (520,250), 10)
# Update
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
When you do
def update(self): if tennisball.rect.colliderect(robert): self.rect.y -= 2
then the ball moves only once. In that "moment" when the player hits the ball and the condition is fulfilled. After the ball has moved, the condition is not fulfilled any more and the ball stops.
When the racket hits the ball then you've to change the speed of the ball rather than its position.
Add attributes which store the speed of the ball ( .speedx
, .speedy
). Initialize the attributes by 0. Continuously change the position of the ball by it speed in the method .update()
. When the racket hits the ball then change the speed:
eg
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("tennisball.png")
self.rect = self.image.get_rect()
self.rect.center = (360, 325)
self.speedx = 0
self.speedy = 0
def update(self):
if tennisball.rect.colliderect(robert):
self.speedy = -2
self.rect = self.rect.move(self.speedx, self.speedy)
Note, if there is a player at the other side of the court, which hits the ball, then the speed is changed again. The speed can also have an sideward component for a diagonal movement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.