Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
Hey i am trying to create a breakout clone with pygame, and i used
self.course(180 - self.course) % 360
To bounce the ball of the paddle, however i was looking into the vector 2 class, but i got no idea how to convert my Ball class using this. If anyone could guide me in the right direction.
here is my code that i want to convert using vector2.
import pygame
import math
class Ball(pygame.sprite.Sprite):
course = 130
def __init__(self):
# Calling the parent class (Sprite)
pygame.sprite.Sprite.__init__(self)
# Creating the ball and load the ball image
self.image = pygame.image.load("ball.png").convert()
self.rect = self.image.get_rect()
self.rect.x = 0
self.rect.y = 270
# Creating a bounce function to make the ball bounce of surfaces.
def bounce(self, diff):
self.course = (180 - self.course) % 360
self.course -= diff
# Create the function that will update the ball.
def update(self):
course_radianse = math.radians(self.course)
self.rect.x += 10 * math.sin(course_radianse)
self.rect.y -= 10 * math.cos(course_radianse)
self.rect.x = self.rect.x
self.rect.y = self.rect.y
# Check if ball goes past top
if self.rect.y <= 0:
self.bounce(0)
self.rect.y = 1
# Check if ball goes past left side
if self.rect.x <= 0:
self.course = (360 - self.course) % 360
self.rect.x = 1
# Check if ball goes past right side
if self.rect.x >= 800:
self.course = (360 - self.course) % 360
self.rect.x = 800 - 1
if self.rect.y > 600:
return True
else:
return False
–
A vector defines a direction and an amount. You have to add the vector to the location of the ball. Sadly pygame.Rect
stores integral numbers only, so the location of the object has to be stored in a pygame.math.Vector2
, too. You need 1 vector for the location of the object and a 2nd one for the direction. Every time when the location changes, then the .rect
attribute has to be set by the rounded location.
If the object hits a surface then the Ball is reflected (.reflect()) by the Normal vector to the surface.
Minimal example: repl.it/@Rabbid76/PyGame-BallBounceOffFrame
import pygame
import random
class Ball(pygame.sprite.Sprite):
def __init__(self, startpos, velocity, startdir):
super().__init__()
self.pos = pygame.math.Vector2(startpos)
self.velocity = velocity
self.dir = pygame.math.Vector2(startdir).normalize()
self.image = pygame.image.load("ball.png").convert_alpha()
self.rect = self.image.get_rect(center = (round(self.pos.x), round(self.pos.y)))
def reflect(self, NV):
self.dir = self.dir.reflect(pygame.math.Vector2(NV))
def update(self):
self.pos += self.dir * self.velocity
self.rect.center = round(self.pos.x), round(self.pos.y)
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
all_groups = pygame.sprite.Group()
start, velocity, direction = (250, 250), 5, (random.random(), random.random())
ball = Ball(start, velocity, direction)
all_groups.add(ball)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
all_groups.update()
if ball.rect.left <= 100:
ball.reflect((1, 0))
if ball.rect.right >= 400:
ball.reflect((-1, 0))
if ball.rect.top <= 100:
ball.reflect((0, 1))
if ball.rect.bottom >= 400:
ball.reflect((0, -1))
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), (100, 100, 300, 300), 1)
all_groups.draw(window)
pygame.display.flip()
Lets assume you have a group of blocks:
block_group = pygame.sprite.Group()
Detect the collision of the ball
and the block_group
. Once a collision (pygame.sprite.spritecollide()
) is detected, reflect
the ball on the block:
block_hit = pygame.sprite.spritecollide(ball, block_group, False)
if block_hit:
bl = block_hit[0].rect.left - ball.rect.width/4
br = block_hit[0].rect.right + ball.rect.width/4
nv = (0, 1) if bl < ball.rect.centerx < br else (1, 0)
ball.reflect(nv)
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.