首页 > 解决方案 > Pygame rect.colliderect() 不工作,因为没有检测到碰撞

问题描述

我正在尝试从 Python 中的 Game Maker 教程中重新创建 Evil Clutches 以完成作业。我能够让一切正常,但是与母龙和小龙/恶魔等的碰撞似乎不起作用。就像小龙一样,什么不会通过母龙而没有检测到它相互碰撞. 任何帮助表示赞赏。

这是一些代码:

import pygame
import random
import os
import sys
import math

class Player(object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 8
        self.walkCount = 0
        self.floating = True
        self.health = 10
        self.rect = pygame.Rect(self.x, self.y, 140, 160)

class Projectile(object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 8
        
class BabyDragon(Projectile):
    def __init__(self,x,y,width,height):
        super().__init__(x,y,width,height)
        self.rect = (self.x, self.y, 55, 55)
        
    bbydra = pygame.image.load(os.path.join('images', 'sprite_baby_0.png'))
    def draw(self,win):
        self.hitbox = (self.x, self.y, 55, 55)
        pygame.draw.rect(win, (255,0,0), self.hitbox, 2)
        win.blit(self.bbydra, (self.x,self.y))
        
    def collide(self, rect):
        if rect[0] + rect[2] > self.hitbox[0] and rect[0] < self.hitbox[0] + self.hitbox[2]:
            if rect[1] + rect[3] > self.hitbox[1]:
                return True
        return False
    
class EvilBaby(Projectile):
    def __init__(self,x,y,width,height):
        super().__init__(x,y,width,height)
        self.rect = (self.x, self.y, 55, 55)

        
    evbby = pygame.image.load(os.path.join('images', 'sprite_evilbaby_0.png'))
    def draw(self,win):
        self.hitbox = (self.x, self.y, 55, 55)
        pygame.draw.rect(win, (255,0,0), self.hitbox, 2)
        win.blit(self.evbby, (self.x,self.y))
        
    def collide(self, rect):
        if rect[0] + rect[2] > self.hitbox[0] and rect[0] < self.hitbox[0] + self.hitbox[2]:
            if rect[1] + rect[3] > self.hitbox[1]:
                return True
        return False
    
class Demon(Projectile):
    def __init__(self,x,y,width,height):
        super().__init__(x,y,width,height)
        self.health = 5
        self.rect = pygame.Rect(self.x+10, self.y+20, 120, 120)
        
    dem = pygame.image.load(os.path.join('images', 'sprite_demon_0.png'))
    def draw(self,win):
        self.hitbox = (self.x+10, self.y+20, 120, 120)
        pygame.draw.rect(win, (255,0,0), self.hitbox, 2)
        win.blit(self.dem, (self.x,self.y))
        #pygame.draw.rect(win, (255,0,0),(self.hitbox[0], self.hitbox[1] - 20,120,10))
        #pygame.draw.rect(win, (0,128,0),(self.hitbox[0], self.hitbox[1] - 20,120 - (24 *(5 - self.health)),10))
        
    def collide(self, rect):
        if rect[0] + rect[2] > self.hitbox[0] and rect[0] < self.hitbox[0] + self.hitbox[2]:
            if rect[1] + rect[3] > self.hitbox[1]:
                return True
        return False
mother = Player(15, 200, 64, 64)

bullets = []
babydragon = BabyDragon(50,48,64,64)
evilbaby = EvilBaby(50,48,64,64)
demon = Demon(50,48,64,64)
run = True

while run:
 for bullet in bullets:
    if bullet.x < -64:
        bullets.pop(bullets.index(bullet))
    else:
        bullet.x -= 4
    
    if pygame.sprite.collide_rect(mother,babydragon):
        print('collided with baby dragon')
        score += 100
        bullets.pop(bullets.index(bullet))
    elif pygame.sprite.collide_rect(mother,evilbaby):
        print('collided w/ evil baby')
    elif pygame.sprite.collide_rect(mother,evilbaby):
        print('collided w/ demon')

标签: pythonpygamerect

解决方案


pygame.sprite.collide_rect使用.rect属性进行碰撞检测。因此,当您移动对象时,您必须更新存储在.rect属性中的位置:

for bullet in bullets:
    if bullet.x < -64:
        bullets.pop(bullets.index(bullet))
    else:
        bullet.x -= 4
    bullet.rect.x = bullet.x # <---

我建议使用pygame.sprite.Spritepygame.sprite.Group对象。


推荐阅读