矩形和圆形之间的碰撞

时间:2015-11-18 13:03:01

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

问题是接下来,我有圈子,如果他们与玩家重叠,我需要删除它们。我试图创建一堆方法来获取圆和矩形的坐标但是当我尝试检查它们是否重叠时我得到一个错误。

TypeError:unorderable类型:method()>方法()

以下是代码:

# Colour
# Created by Niktia Kotter

#!/usr/bin/env python
import pygame, sys, random, time
from pygame.locals import*

# set up pygame
pygame.init()
FPS=60
fpsclock = pygame.time.Clock()

# colours   R    G    B
WHITE   = (255, 255, 255)
BLACK   = (0  , 0  , 0  )
RED     = (237, 28 , 36 )

# set up screen
SCREEN_W = 800
SCREEN_H = 480
SCREEN =  pygame.display.set_mode((SCREEN_W,SCREEN_H),0,32)            
snapMultX = SCREEN_W / 5
snapMultY = SCREEN_H / 5
basicFont = pygame.font.SysFont(None, 32)

# set up functions
def isPointInsideRect(Cx, Cy, rectX, rectY, rectW, rectH ):
    if ((Cx > rectX) and \
    (Cx < rectY) and \
    (Cy > rectW) and \
    (Cy < rectH)):
        return True
    else:
        return False

"""
def doRectsOverlap(rect1, rect2):
    for a,b in [(rect1, rect2), (rect2, rect1)]:
        # check if a's corners are inside b
        if ((isPointInsideRect(a.left, a.top, b)) or
            (isPointInsideRect(a.left, a.bottom, b)) or
            (isPointInsideRect(a.right, a.top, b)) or
            (isPointInsideRect(a.right, a.bottom, b))):
            return True

    return False
"""

# set up calsses
class Actor:

    def __init__ (self):


        self._x = snapMultX*2
        self._y = SCREEN_H - snapMultX/5 -(snapMultX/2)
        self._w = snapMultX
        self._h = snapMultX/2
        self._colour = WHITE
        self._Rect = pygame.Rect(self._x, self._y, self._w, self._h)

    def moveRight(self):
        self._x += snapMultX

    def moveLeft(self):
        self._x -= snapMultX

    def draw(self):
        pygame.draw.rect(SCREEN, self._colour, (self._x, self._y, self._w, self._h))
        return 
    def rectX(self):
        return self._x
    def rectY(self):
        return self._y
    def rectW(self):
        return self._w
    def rectH(self):
        return self._h

class Enemy:

    def __init__ (self, location):

        self._x = snapMultX*location+snapMultX/2
        self._y = 0
        self._r = snapMultX/10
        self._colour = WHITE

    def move(self, dy):

        self._y += dy

    def draw(self):
        pygame.draw.circle(SCREEN, self._colour, (int(self._x),int(self._y)), int(self._r), 0)
        return

    def GetCircleX(self):
        return self._x

    def GetCircleY(self):
        return self._y

class Capture(object):

    def __init__(self):

        self.caption = pygame.display.set_caption('Space Invaders')
        self.screen = SCREEN
        self.startGame = True
        self.gameOver = False
        self.enemyCount = 0
        self.timer = 50
        self.score = 0

    def main(self):

        clock = pygame.time.Clock()
        enemy =[]
        player = Actor()

        while True:
            if self.startGame:

                SCREEN.fill(BLACK)

                pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*1-snapMultX/5*2,0), (snapMultX*0+snapMultX/5*2,0), (snapMultX*0+snapMultX/2,snapMultY/4)])
                pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*2-snapMultX/5*2,0), (snapMultX*1+snapMultX/5*2,0), (snapMultX*1+snapMultX/2,snapMultY/4)])
                pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*3-snapMultX/5*2,0), (snapMultX*2+snapMultX/5*2,0), (snapMultX*2+snapMultX/2,snapMultY/4)])
                pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*4-snapMultX/5*2,0), (snapMultX*3+snapMultX/5*2,0), (snapMultX*3+snapMultX/2,snapMultY/4)])
                pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*5-snapMultX/5*2,0), (snapMultX*4+snapMultX/5*2,0), (snapMultX*4+snapMultX/2,snapMultY/4)])                

                player.draw()

# enemy move/spawn timer
                self.timer -= 1

# enemy spawner
                if self.timer <= 0:

                    num = random.randint(0, 5)

                    if num == 0:
                        print (0)
                        enemy.append(Enemy(0))
                    if num == 1:
                        print (1)
                        enemy.append(Enemy(1))
                    if num == 2:
                        print (2)
                        enemy.append(Enemy(2))
                    if num == 3:
                        print (3)
                        enemy.append(Enemy(3))
                    if num == 4:
                        print (4)
                        enemy.append(Enemy(4))

# player mover
                for event in pygame.event.get():

                    if player._x != snapMultX*4 and (event.type == KEYDOWN) and (event.key == K_d):
                        player.moveRight()

                    if player._x != 0 and(event.type == KEYDOWN) and (event.key == K_a):
                        player.moveLeft()   

                    if event.type == QUIT:
                        pygame.quit()
                        sys.exit()
# enemy logic
                if self.timer <= 0:
                    for e in enemy:
                        e.move(snapMultY)

                        if isPointInsideRect(e.GetCircleX, e.GetCircleY, player.rectX, player.rectY, player.rectW, player.rectH):
                            self.score += 1
                            enemy.remove(e)

                        if e._y > snapMultY*5:      
                            enemy.remove(e)
# reste timer
                    self.timer = 50                    

                for e in enemy:
                    e.draw()

# score
                self.myScore = "Score = " + str(self.score)
                text = basicFont.render(self.myScore, True, RED, WHITE)
                textRect = text.get_rect()
                textRect.centerx = SCREEN.get_rect().centerx
                textRect.centery = SCREEN.get_rect().centery
                SCREEN.blit(text, textRect)

                pygame.display.update()
                fpsclock.tick(FPS) 

if __name__ == '__main__':
    game = Capture()
    game.main()       

1 个答案:

答案 0 :(得分:1)

您的错误原因实际上是一个拼写错误和Python Duck Typing的乐趣。调试的关键是理解错误的含义。

您的错误&#34; TypeError:无法解决的类型:method()&gt;方法()&#34 ;.这是什么意思? 显然你有一个类型错误,但这究竟是什么意思。这意味着Python正在尝试完成具有某些要求的操作。在这种情况下,我们正在尝试对不可订购的类型进行比较 - 我们试图对两个没有可订购属性的事物进行比较,以便不能以这种方式对它们进行比较。下一部分说&#34;方法()&gt;方法()&#34 ;.这意味着我们试图比较一种方法比另一种方法更大。这可能不是预期的。

所以现在我们必须在ifs中查看这些比较。让我们看一下isPointInsideRect。

def isPointInsideRect(Cx, Cy, rectX, rectY, rectW, rectH ):
    if ((Cx > rectX) and (Cx < rectY) and (Cy > rectW) and (Cy < rectH)):
        return True
    else:
        return False

这里我们对六个值进行了大量的比较。让我们看看这个方法被调用的位置?该函数在一个未注释的行中被调用(第175行)。

if isPointInsideRect(e.GetCircleX, e.GetCircleY, player.rectX, player.rectY, player.rectW, player.rectH):

你看到这个问题吗?您传递给函数的每个值都不是值,它们是方法定义。因此,每次isPointInsideRect都在进行那些比较,他们将一种方法与另一种方法进行比较。这不是一个有效的比较。

尝试将第175行更改为:

if isPointInsideRect(e.GetCircleX(), e.GetCircleY(), player.rectX(), player.rectY(), player.rectW(), player.rectH()):