微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

圆圈在 pygame 中显示为正方形

如何解决圆圈在 pygame 中显示为正方形

我正在 pygame 中制作乒乓球,目前我已经完成了桨和它们的动作。我正在尝试创建球,但是当球在屏幕上呈现时,它是一个矩形,而不是一个圆形。这是我的代码

import pygame

pygame.init()

from pygame.locals import (
K_UP,K_DOWN,K_s,K_w,QUIT
)

class Ball(pygame.sprite.Sprite): 
    def __init__(self,color,left,top): # circle is getting drawn in this constructor
        pygame.sprite.Sprite.__init__(self) 
        radius = 40 
        self.surface = pygame.Surface((radius,radius)) 
        self.surface.fill(color) 
        self.rect = pygame.draw.circle(self.surface,(left,top),radius)
        self.rect.update(left,top,radius,radius)

    # a temporary implementation of the move function that keeps the ball displayed on the screen 
    def move(self,screen): 
        screen.blit(self.surface,self.rect,self.rect)
        screen.blit(self.surface,self.rect)  


class Paddle(pygame.sprite.Sprite):
    # initializes the paddle surface,rect,pos_y
    def __init__(self,top): 
        pygame.sprite.Sprite.__init__(self) 
        width,height = 40,120
        self.surface = pygame.Surface((width,height))
        self.surface.fill(color)
        self.rect = self.surface.get_rect()
        self.rect.update(left,width,height)
        self.pos_y = self.rect.top

    # updates the paddles position based on key presses 
    def move(self,pressed_keys,keys,screen):
        dy = 0 
        screen.blit(self.surface,self.rect) 
        l_bound,u_bound = 5,750 - self.rect.height - 5 
        if pressed_keys[keys[0]] and self.rect.top > l_bound: 
            dy = -.2  
            
        if pressed_keys[keys[1]] and self.rect.top < u_bound: 
            dy = .2

        self.pos_y += dy
        self.rect.top = self.pos_y  
        screen.blit(self.surface,self.rect) 

class Main: 
    def __init__(self):
        self.height,self.width = 750,1000
        self.screen = pygame.display.set_mode((self.width,self.height)) 
        pygame.display.set_caption("pong") 
        self.loop()

    def loop(self): 
        blue = [0,255]
        red = [255,0]

        # create the paddles and the ball 
        paddle1 = Paddle(blue,30,30) 
        paddle2 = Paddle(blue,930,30)
        ball = Ball(red,self.width // 2,self.height // 2)
        
        # the buffer (I think) expands the area updated at the end of the game loop so that it can delete where the old rectangle was and change where the new rectangle is,but I'm not 100% sure 
        BUFFER = .01 

        running = True 
        while running:
            self.screen.fill([0,0]) 
            for event in pygame.event.get():
            if event.type == QUIT: 
                running = False 
        
            pressed_keys = pygame.key.get_pressed()
     
            paddle1.move(pressed_keys,[K_w,K_s],self.screen)
            paddle2.move(pressed_keys,[K_UP,K_DOWN],self.screen)
            ball.move(self.screen)
            update_rect1 = pygame.Rect(30,paddle1.rect.top - BUFFER,40,paddle1.rect.top + 150 + BUFFER) 
            update_rect2 = pygame.Rect(930,paddle2.rect.top - BUFFER,paddle2.rect.top + 150 + BUFFER)
            pygame.display.update([update_rect1,update_rect2,ball.rect])

        pygame.quit()


Main()

我见过这种在线画圆的方法

 pygame.draw.circle(screen,(0,255),(150,50),15,1)

问题是我需要一个中间表面来在我 blit 到屏幕上时使用,例如当我 blit 桨时使用这行代码在这种情况下,该表面是 self.surface:

screen.blit(self.surface,self.rect) 

因此,我必须像这样在球的表面场上绘制圆圈:

pygame.draw.circle(self.surface,radius)

然后我可以将 self.surface blit 到屏幕上。这种方法中的某些东西导致了问题。

总而言之,我尝试采用的方法是为每个游戏对象提供自己的表面,但这(大概)会导致尝试绘制圆时出现问题。我希望得到一些关于这种方法是否错误以及如何解决圆圈问题的反馈。谢谢!

解决方法

这是问题代码:

self.surface = pygame.Surface((radius,radius)) 
self.surface.fill(color) 
self.rect = pygame.draw.circle(self.surface,color,(left,top),radius)

您正在创建一个(正方形)曲面并用圆的颜色填充它,然后在其顶部以相同的颜色绘制圆。您应该使表面(即背景)透明。最好的方法是使用 set_colorkey

另一个问题是这一行:

self.rect = pygame.draw.circle(self.surface,radius)

您是在 self.surface 上而不是在屏幕上绘制它,因此您希望 center 参数是 self.surface 的中心,而不是屏幕的中心。此外,由于表面的边是 radius,所以圆实际上会占据整个表面。您可能正在考虑直径。在创建 self.surface 时,您应该将半径加倍,但在这里我将其减半作为圆:

self.rect = pygame.draw.circle(self.surface,((radius/2),(radius/2)),radius/2)

总而言之,这应该有效:

self.surface = pygame.Surface((radius,radius))
self.surface.set_colorkey((255,255)) # set it to some color you are not using
self.surface.fill((255,255)) # fill the surface with that color
self.rect = pygame.draw.circle(self.surface,radius/2) # draw the circle in the correct color

当你将这个表面 blit 到另一个表面时,传递给 set_colorkey 的颜色将不包括在内,圆的“背景”将是透明的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。