python - Partial Collision Error -
i trying make version of pong using pygame, having issues detecting collision between ball , paddle. got detection working both paddles, came realize left player cannot move paddle when ball collides without ball passing through. player on right has no such issue, , keeping left player still allows ball reflect normally.
import pygame, sys pygame.locals import * pygame.init() pygame.mixer.init() pygame.font.init() black = (0, 0, 0) white = (255, 255, 255) screenx = 1080 screeny = 720 clock = pygame.time.clock() pygame.mouse.get_pos in (screenx, screeny): pygame.mouse.set_visible(false) # blueprint creating player character class player: # defines initial conditions player def __init__(self): self.xpos = 0 self.ypos = 0 self.width = 20 self.length = 100 self.speed = 10 self.move = 0 self.upkey = 0 self.downkey = 0 self.score = 0 self.rect = pygame.rect((self.xpos, self.ypos, self.width, self.length)) # if player character, defines paddle movement def player_move(self, key): if key[self.upkey]: self.ypos -= self.speed self.move = -1 elif key[self.downkey]: self.ypos += self.speed self.move = 1 else: self.move = 0 # creates screen boundary players def player_boundary(self, key): if self.ypos == 0: self.speed = 0 self.move = 0 if key[self.downkey]: self.speed = 10 self.move = -1 elif self.ypos + self.length == screeny: self.speed = 0 self.move = 0 if key[self.upkey]: self.speed = 10 self.move = 1 # draws player rectangle surface def draw(self, surface): self.rect = pygame.draw.rect(surface, white, (self.xpos, self.ypos, self.width, self.length)) # blueprint creating ball class ball: def __init__(self): self.size = 15 self.speed = 10 self.vy = 0 self.vx = 10 self.ypos = screeny/2 self.xpos = 100 self.rect = pygame.rect((self.xpos, self.ypos, self.size, self.size)) # defines movement of ball (in xy components) def ball_move(self): self.ypos += self.vy self.xpos += self.vx # method ball bouncing off of player paddle ** def ball_block(self, player): if player.move > 0: self.vy += player.speed * 0.3 self.vx = -((self.speed**2 - self.vy**2) ** .5) elif player.move < 0: self.vy = player.speed * -0.3 self.vx = -((self.speed**2 - self.vy**2) ** .5) elif player.move == 0: self.vx = -self.vx # reflecting off of screen boundaries ** def ball_reflect(self, screeny): if self.ypos == 0: self.vy = -self.vy elif self.ypos == screeny - self.size: self.vy = -self.vy # method detecting when player has scored def score(self): if self.xpos == 0: self.vx = -self.vx print ('score') elif self.xpos == screenx - self.size: self.vx = -self.vx print ('score') # draws ball surface def draw(self, surface): self.rect = pygame.draw.rect(surface, white, (self.xpos, self.ypos, self.size, self.size)) def setup(): # assigns values player 1 (left side) player1 = player() player1.xpos = 50 player1.ypos = screeny/1.5 player1.upkey = k_w player1.downkey = k_s # assigns values player 2 (right side) player2 = player() player2.xpos = screenx - player2.width - 50 player2.ypos = screeny/1.5 player2.upkey = k_up player2.downkey = k_down return player1, player2 # main loop of game def main(): player1, player2 = setup() ball = ball() play = true while play: event in pygame.event.get(): if event.type == quit: pygame.quit() sys.exit() key = pygame.key.get_pressed() if key[k_escape]: play = false if ball.rect.colliderect(player1): # reason, ball can go through p1 while moving ball.ball_block(player1) elif ball.rect.colliderect(player2): ball.ball_block(player2) # had issue ball going through bottom, fixed adding screeny dependencies if ball.ypos == 0: ball.ball_reflect(screeny) elif ball.ypos == screeny - ball.size: ball.ball_reflect(screeny) player1.player_move(key) player2.player_move(key) ball.ball_move() # calls methods player boundaries , ball scoring player1.player_boundary(key) player2.player_boundary(key) ball.score() # ball score if colliding head on , not on p2's side # draws objects screen surface.fill(black) player1.draw(surface) player2.draw(surface) ball.draw(surface) pygame.display.update() clock.tick(60) # sets screen, calls main loop surface = pygame.display.set_mode((screenx, screeny)) pygame.display.set_caption('pong') main()
as far can tell, code both players identical, , yet 1 player works in way intended to. appreciated, , thank time.
edit: fixed adding few lines ball_block method
def ball_block(self, player): if player.move > 0: self.vy += player.speed * 0.3 if self.vx < 0: self.vx = ((self.speed**2 - self.vy**2) ** .5) elif self.vx > 0: self.vx = -((self.speed**2 - self.vy**2) ** .5) elif player.move < 0: self.vy = player.speed * -0.3 if self.vx < 0: self.vx = ((self.speed**2 - self.vy**2) ** .5) elif self.vx > 0: self.vx = -((self.speed**2 - self.vy**2) ** .5) elif player.move == 0: self.vx = -self.vx
if player moving during collision, setting
self.vx = -((self.speed**2 - self.vy**2) ** .5)
so it's negative
Comments
Post a Comment