在 pygame 中使用 vector2.与窗框碰撞,将球限制在矩形区域内 [英] Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area
问题描述
嘿,我正在尝试使用 pygame 创建一个突破性克隆,我使用了
self.course(180 - self.course) % 360
为了弹起桨的球,但是我正在研究矢量 2 类,但我不知道如何使用它来转换我的 Ball 类.如果有人能指导我朝着正确的方向前进.
这是我想使用 vector2 转换的代码.
导入pygame导入数学类球(pygame.sprite.Sprite):课程 = 130def __init__(self):# 调用父类(Sprite)pygame.sprite.Sprite.__init__(self)# 创建球并加载球图像self.image = pygame.image.load("ball.png").convert()self.rect = self.image.get_rect()self.rect.x = 0self.rect.y = 270# 创建一个弹跳函数,使球在表面上弹跳.def反弹(自我,差异):self.course = (180 - self.course) % 360self.course -= 差异# 创建将更新球的函数.定义更新(自我):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.xself.rect.y = self.rect.y# 检查球是否越过顶部如果 self.rect.y <= 0:self.bounce(0)self.rect.y = 1# 检查球是否越过左侧如果 self.rect.x <= 0:self.course = (360 - self.course) % 360self.rect.x = 1# 检查球是否经过右侧如果 self.rect.x >= 800:self.course = (360 - self.course) % 360self.rect.x = 800 - 1如果 self.rect.y >600:返回真别的:返回错误
一个向量定义了一个方向和一个数量.您必须将向量添加到球的位置.遗憾的是,pygame.Rect
仅存储整数,因此对象的位置必须存储在
导入pygame随机导入类球(pygame.sprite.Sprite):def __init__(self、startpos、velocity、startdir):super().__init__()self.pos = pygame.math.Vector2(startpos)self.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)))定义反射(自我,NV):self.dir = self.dir.reflect(pygame.math.Vector2(NV))定义更新(自我):self.pos += self.dir * self.velocityself.rect.center = round(self.pos.x), round(self.pos.y)pygame.init()窗口 = pygame.display.set_mode((500, 500))时钟 = pygame.time.Clock()all_groups = pygame.sprite.Group()开始,速度,方向 = (250, 250), 5, (random.random(), random.random())球=球(开始,速度,方向)all_groups.add(球)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误all_groups.update()如果 ball.rect.left <= 100:ball.reflect((1, 0))如果 ball.rect.right >= 400:ball.reflect((-1, 0))如果 ball.rect.top <= 100:ball.reflect((0, 1))如果 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(窗口)pygame.display.flip()
假设您有一组块:
block_group = pygame.sprite.Group()
检测ball
和block_group
的碰撞.一旦发生碰撞(pygame.sprite.spritecollide()
) 被检测到,反射
块上的球:
block_hit = pygame.sprite.spritecollide(ball, block_group, False)如果 block_hit:bl = block_hit[0].rect.left - ball.rect.width/4br = block_hit[0].rect.right + ball.rect.width/4nv = (0, 1) 如果 bl
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:
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)
这篇关于在 pygame 中使用 vector2.与窗框碰撞,将球限制在矩形区域内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!