【问题标题】:How to make a window border for a circle object in pygame [duplicate]如何在pygame中为圆形对象制作窗口边框[重复]
【发布时间】:2020-10-26 18:15:35
【问题描述】:

我写了一个小足球游戏。它有一个用箭头控制的球员(圆圈)、一个球(也是圆圈)和左右两侧的两个球门(矩形)。到目前为止,如果我越过屏幕,球员和球就会出现在另一侧。我现在需要设置一个窗口边界:如果球(和玩家靠近边界,他们就无法逃离窗口。对于球来说,碰撞也是可能的。我尝试了不同的方法,但它们没有用。

这是我尝试过的一些事情:

def checkballborder():
global ballX
global ballY

if  ballX  >  windowsize[0]:
    ballX *= -1
    
if  ballX  <  windowsize[0]:
    ballX *= -1


if  ballY  >  windowsize[1]:
    ballY *= -1
    
if  ballY  <  windowsize[0]:
    ballY *= -1

和:

#borders
if  ballX < ballradius:
    ballX = ballradius

if  ballX > windowsize[0] - ballradius:
    ballX = windowsize[0] - ballradius


if  ballY > ballradius:
    ballY = ballradius

if  ballY > windowsize[1] - ballradius:
    ballY = windowsize[1] - ballradius

这是我的全部代码:

import pygame, time, sys, math, random

pygame.init()

#Farben bestimmen
red = pygame.color.Color("red")
blue = pygame.color.Color("blue")
white = pygame.color.Color("white")
black = pygame.color.Color("black")
green = pygame.color.Color("green")
beige = pygame.color.Color("#F5F5DC")

#Fenster
width = 200
height = 200
windowsize = [width, height]
fps = 60
window = pygame.display.set_mode (windowsize)



#Uhr
clock = pygame.time.Clock()

#Position Spieler
playerX = random.randrange (0, windowsize[0])
playerY = random.randrange (0, windowsize[1])

#Position Ball
ballX = random.randrange(0, windowsize[0])
ballY = random.randrange(0, windowsize[1])
ballradius = 6
#Mittellinie
midlineA = int (windowsize [0] / 2)
midlineB = int (windowsize [0] / 2)
#Anstoßkreiß 
midcircleX = int (windowsize[0] / 2)
midcircleY = int (windowsize[1] / 2)
#Position Tor links
lgoalX = 0
lgoalY = int (windowsize [1] / 2 - 10)
lgoalW = 15
lgoalH = 25

#Position Tor rechts
rgoalX = int (windowsize [0] - 15)
rgoalY = int (windowsize [1] / 2 - 10)
rgoalW = 15
rgoalH = 25

def checkOffWindowX(playerX) :
    return playerX % windowsize[0]

def checkOffWindowY(playerY):
    return playerY % windowsize[1]

    

        
def checkTouching():
    global playerX
    global ballX
    global playerY
    global ballY
    if -10 < playerY - ballY < 10 and -10 < playerX - ballX < 10:
        xDiff = playerX - ballX
        yDiff = playerY - ballY
        #Spielball verschieben
        ballX -= xDiff *2
        ballY -= yDiff *2
        #Falls der Spielball in einer Ecke sein sollte
        if   ballY == 0:
             xDiff -= 5
        elif ballX == windowsize[0]:
             xDiff += 5
        if   ballY == windowsize[1]:
             yDiff += 5
        elif ballY == windowsize[1]:
             yDiff +=5

       

    
        
            

done = False
while not done:
    window.fill(green)
    #Bewegung Spieler
    keys = pygame.key.get_pressed()
    if keys [pygame.K_UP]:
        playerY -= 1
    if keys [pygame.K_DOWN]:
        playerY += 1
    if keys [pygame.K_LEFT]:
        playerX -= 1
    if keys[pygame.K_RIGHT]:
        playerX += 1
    #Positionsbestimmung
    playerX = checkOffWindowX(playerX)
    playerY = checkOffWindowY(playerY)

    #Auf Berührung testen
    checkTouching()


    #borders
    if  ballX < ballradius:
        ballX = ballradius

    if  ballX > windowsize[0] - ballradius:
        ballX = windowsize[0] - ballradius


    if  ballY > ballradius:
        ballY = ballradius

    if  ballY > windowsize[1] - ballradius:
        ballY = windowsize[1] - ballradius

    

    
    
    #Anstoßkreis zeichnen
    pygame.draw.circle (window, white, [midcircleX,midcircleY], 20, 3)
    #Mittelpunkt zeichnen
    pygame.draw.circle (window, white, [midcircleX,midcircleY], 5)
    #Mittellinie zeichnen
    pygame.draw.line (window, white, (midlineA , 0), (midlineB,200),4)
    #Spieler zeichnen
    pygame.draw.circle (window, red, [playerX, playerY], 8)  
    #Spielball zeichnen
    pygame.draw.circle (window, blue, [ballX,ballY], ballradius)

    

#####~Toren zeichnen und Torerkennung~#######################################
                                                                            #
    #Tor links zeichnen                                                     #
    pygame.draw.rect(window, white, (lgoalX, lgoalY, lgoalW, lgoalH))       #
    #Tor rechts zeichnen                                                    #
    pygame.draw.rect(window, white, (rgoalX, rgoalY, rgoalW, rgoalH))       #
                                                                            #
                                                                            #
    #Rechte Tor                                                             #
    distancer = int(math.hypot(ballX - rgoalX, ballY - rgoalY))             #
    #Linke Tor                                                              #
    distancel = int(math.hypot(ballX - lgoalX, ballY - lgoalY))             #
                                                                            #
    if  distancer < 20 >= 0:                                                #
        done = True                                                         #
    if  distancel < 20 >= 0:                                                #
        done = True                                                         #
                                                                            #
    #if  ballX < ballradius:                                                #
    #    ballX = ballradius                                                 #
                                                                            #
    #if  ballY < ballradius:                                                #
     #   ballY = ballradius                                                 #
                                                                            #
#############################################################################    
        
    pygame.display.update()
    clock.tick(fps)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

pygame.quit()

cmets 是德文的,但如果你需要什么,我可以翻译给你

【问题讨论】:

    标签: python python-3.x pygame collision-detection collision


    【解决方案1】:

    使用pygame.Rect 对象作为对象的边界框,使用clamp_ip() 将对象保持在边界内:

    例如:

    def ClampToRect(x, y, radius, border_rect):
        
        # define a rectangle by the center of the object and the radius 
        object_rect = pygame.Rect(x-radius, y-radius, radius*2, radius*2)
        
        # "clamp" to border 
        #     move the rectangle inside the border rectangle
        #     if the rectangle is not completely inside
        object_rect.clamp_ip(border_rect)
        
        # return the new center point of the rectnagle
        return object_rect.center
    
    window = pygame.display.set_mode(windowsize)
    
    # [...]
    
    done = False
    while not done:
        # [...]
    
        # playerX = checkOffWindowX(playerX)
        # playerY = checkOffWindowY(playerY)
    
        player_radius = 8
        playerX, playerY = ClampToRect(playerX, playerY, player_radius, window.get_rect())
    
        # [...]
    

    对球做同样的事情

    def checkTouching():
        global playerX
        global ballX
        global playerY
        global ballY
        if -10 < playerY - ballY < 10 and -10 < playerX - ballX < 10:
            xDiff = playerX - ballX
            yDiff = playerY - ballY
            #Spielball verschieben
            ballX -= xDiff *2
            ballY -= yDiff *2
            ballX, ballY = ClampToRect(ballX, ballY, ballradius, window.get_rect())
    

    【讨论】:

    • 但是球员和球都是圆形,不是矩形
    • 我得到了这个:ball = pygame.Rect([ballX,ballY], ballradius) TypeError: Argument must be rect style object
    • 我认为在 def ClampToRect(x, y, radius, rect): 'rect' 之前需要定义。我错过了什么?
    • 我已经阅读了你的答案,但我不太明白。边框表面是什么意思,是窗口还是我需要预先定义的其他东西?
    • 现在可以使用了,谢谢。我会为我的播放器做同样的事情
    猜你喜欢
    • 1970-01-01
    • 2020-09-09
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多