首页 > 解决方案 > 如何让我的图像(矩形)与我随机生成的圆圈碰撞以结束游戏?

问题描述

几个星期以来,我一直在努力解决这个问题。这是一个自由落体的坑游戏,我的角色(在本例中为黑猩猩 png)在试图躲避随机的黑色圆圈时从屏幕顶部跌落到底部。我已经尝试了很多角度来解决这个问题,我已经尝试过我教过的标准碰撞(pygame.sprite.groupcollide(Group1,Group2,False,True,collided = None)我尝试过只用黑色进行碰撞,不同生成我的图像和所有这些的格式,我找不到任何适用于我的代码的东西。这导致代码非常混乱。我试图为此清理它,但它仍然可能是很难理解,但如果有人对此有任何解决方案,请告诉我,因为我已经被难住了好几个星期了。我只想关闭游戏或“游戏结束”

import sys
import pygame as pg
RED = (255, 0, 0)
GRAY = (150, 150, 150)
GREEN =(34, 177, 76)
BLACK = (0,0,0)

import random
import math




def main():
    width, height = 1024, 768
    hbox, vbox = 80, 80
    w, h = 640, 240
    screen = pg.display.set_mode((width, height))
    BG = pg.image.load('jungle.jpg').convert()
    img = pg.image.load('MONKEY.png')
    img = pg.transform.scale(img, (80, 80))
    img.convert()
    rect = img.get_rect()
    rect.center = w//2, h//2
    clock = pg.time.Clock()
    Score = 0
    class Circle(pg.sprite.Sprite):
        def __init__(self):
            #You can initialise the size to a random value
            self.pos = [random.randint(0, 1000), random.randint(180, 600)]
            self.color = (0,0, 0)
            self.radius = 20

        def draw(self):
            pg.draw.circle(screen, self.color, (self.pos[0], self.pos[1]), self.radius)


    circles = []

    for i in range(20):
        circles.append(Circle())

    def checkIntersection(c1, c2):
        dx = c1.pos[0] - c2.pos[0]
        dy = c1.pos[1] - c2.pos[1]
        d = math.hypot(dx, dy)
        if d < c1.radius + c2.radius:
            return True
        return False


    for i in range(19):
        while checkIntersection(circles[i], circles[i + 1]):
            circles[i].pos = random.randint(0, 1000), random.randint(0, 700)
        
        velocity = (0, 0)
        done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        keys = pg.key.get_pressed()

        # booster
        move = 8 if keys[pg.K_LSHIFT] else 4

        if keys[pg.K_a]:  #to move left
            rect.x -= move
        if rect.x < 0 : rect.x = 0

        if keys[pg.K_d]: #to move right
            rect.x += move
        if rect.x > width-hbox : rect.x = width - hbox
        
        
        Score += 1
        rect.y += 2.5
        screen.blit(BG, (0,0))    
        screen.blit(img,rect)
        pg.draw.rect(screen, RED, rect, 1)
        pg.draw.polygon(screen, GREEN, ((1024,768), (0,768), (0,640),(1024,640)))
        font = pg.font.SysFont("comicsansms", 45)
        text = font.render (" " + str(Score), 1, BLACK)
        screen.blit(text,(480,700))
        pg.event.get()
        for circle in circles:
            circle.draw()
        pg.display.update()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

标签: pythonrandompygamecollision-detection

解决方案


使用“掩码”碰撞。请参阅如何制作碰撞蒙版?Pygame 蒙版碰撞

创建一个带有掩码的Spritepygame.mask.from_surface类(请参阅 参考资料):

class Circle(pg.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.pos = [random.randint(0, 1000), random.randint(180, 600)]
        self.color = (0,0, 0)
        self.radius = 20
        self.image = pg.Surface((self.radius*2, self.radius*2), pg.SRCALPHA)
        pg.draw.circle(self.image , self.color, (self.radius, self.radius), self.radius)
        self.rect = self.image.get_rect(center = self.pos)
        self.mask = pg.mask.from_surface(self.image)

为玩家创建一个Sprite类(也带有面具)

class Player(pg.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pg.image.load('MONKEY.png')
        self.image = pg.transform.scale(self.image, (80, 80)).convert()
        self.rect = self.image.get_rect()
        self.rect.center = x, y
        self.mask = pg.mask.from_surface(self.image)

管理Spritespygame.sprite.Group使用pygame.sprite.spritecollidepygame.sprite.collide_mask() 进行碰撞测试:

if pg.sprite.spritecollide(player, circles, False, collided  = pg.sprite.collide_mask):
    done = True

完整示例:

import sys
import pygame as pg
RED = (255, 0, 0)
GRAY = (150, 150, 150)
GREEN =(34, 177, 76)
BLACK = (0,0,0)

import random
import math

class Circle(pg.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.pos = [random.randint(0, 1000), random.randint(180, 600)]
        self.color = (0,0, 0)
        self.radius = 20
        self.image = pg.Surface((self.radius*2, self.radius*2), pg.SRCALPHA)
        pg.draw.circle(self.image , self.color, (self.radius, self.radius), self.radius)
        self.rect = self.image.get_rect(center = self.pos)
        self.mask = pg.mask.from_surface(self.image)

class Player(pg.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pg.image.load('MONKEY.png')
        self.image = pg.transform.scale(self.image, (80, 80)).convert()
        self.rect = self.image.get_rect()
        self.rect.center = x, y
        self.mask = pg.mask.from_surface(self.image)

def main():
    width, height = 1024, 768
    hbox, vbox = 80, 80
    w, h = 640, 240
    screen = pg.display.set_mode((width, height))
    BG = pg.image.load('jungle.jpg').convert()
    clock = pg.time.Clock()
    Score = 0
    player = Player(w//2, h//2)
    all_sprites = pg.sprite.Group(player)
    circles = pg.sprite.Group()

    for i in range(20):
        circle = Circle()
        circles.add(circle)
        all_sprites.add(circle)

    def checkIntersection(c1, c2):
        dx = c1.pos[0] - c2.pos[0]
        dy = c1.pos[1] - c2.pos[1]
        d = math.hypot(dx, dy)
        if d < c1.radius + c2.radius:
            return True
        return False


    c = circles.sprites()
    for i in range(19):
        while checkIntersection(c[i], c[i + 1]):
            c[i].pos = random.randint(0, 1000), random.randint(0, 700)
        
        velocity = (0, 0)
        done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        keys = pg.key.get_pressed()

        # booster
        move = 8 if keys[pg.K_LSHIFT] else 4

        if keys[pg.K_a]:  #to move left
            player.rect.x -= move
        if player.rect.x < 0 : player.rect.x = 0

        if keys[pg.K_d]: #to move right
            player.rect.x += move
        if player.rect.x > width-hbox : player.rect.x = width - hbox
        
        
        Score += 1
        player.rect.y += 2.5
        screen.blit(BG, (0,0))    
        pg.draw.rect(screen, RED, player.rect, 1)
        pg.draw.polygon(screen, GREEN, ((1024,768), (0,768), (0,640),(1024,640)))
        font = pg.font.SysFont("comicsansms", 45)
        text = font.render (" " + str(Score), 1, BLACK)
        screen.blit(text,(480,700))
        pg.event.get()
        all_sprites.draw(screen)
        pg.display.update()
        clock.tick(30)

        if pg.sprite.spritecollide(player, circles, False, collided  = pg.sprite.collide_mask):
            done = True


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

推荐阅读