在pygame中使用vector2.与窗框碰撞并将球限制在矩形区域 [英] Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area

查看:133
本文介绍了在pygame中使用vector2.与窗框碰撞并将球限制在矩形区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我正在尝试使用pyame创建突破克隆,而我使用了

  self.course(180-self.course)%360 

要弹起桨的球,但是我一直在研究vector 2类,但是我不知道如何使用该类转换我的Ball类.如果有人可以引导我朝正确的方向前进.

这是我要使用vector2转换的代码.

  import pygame导入数学球类(pygame.sprite.Sprite):路线= 130def __init __():#调用父类(Sprite)pygame.sprite.Sprite .__ init __(自己)#创建球并加载球图像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-=差异#创建将更新球的函数.def更新(自己):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:自我反弹(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:返回True别的:返回False 

解决方案

向量定义方向和数量.您必须将矢量添加到球的位置.遗憾的是 pygame.Rect 仅存储整数,因此对象的位置必须存储在

  import pygame随机导入球类(pygame.sprite.Sprite):def __init __(self,startpos,velocity,startdir):super().__ init __()self.pos = pygame.math.Vector2(startpos)自速度=速度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体现(自我,内华达州):self.dir = self.dir.reflect(pygame.math.Vector2(NV))def更新(自己):self.pos + = self.dir * self.velocityself.rect.center =圆(self.pos.x),圆(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(球)运行=真运行时:clock.tick(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(窗口,(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/4如果b1 <nv,则nv =(0,1).ball.rect.centerx<br else(1、0)ball.reflect(nv) 

Hey i am trying to create a breakout clone with pyame, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆