Pygame与面具的碰撞不起作用 [英] Pygame collision with masks is not working

查看:68
本文介绍了Pygame与面具的碰撞不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个推杆游戏,现在我想添加一个倾斜的墙类型.因此,我需要为碰撞使用蒙版(直到现在我才使用rects).我花了数小时学习有关掩码的知识,并试图弄清为什么我的代码无法正常工作.没有错误,只是没有检测到冲突.

我已将代码简化为小得多的代码,以方便我高效地对其进行测试.从我所看到的一切来看,这似乎应该可行,但事实并非如此.在这里:

  import pygame#Pygame初始化的东西pygame.init()wind_width = 1200wind_height = 700gameDisplay = pygame.display.set_mode((wind_width,wind_height))pygame.display.set_caption(迷你高尔夫!")pygame.display.update()gameExit =假时钟= pygame.time.Clock()#班级设置球类:def __init __(self,x,y):self.x = xself.y = yself.image = pygame.image.load("sball.png")self.rect = self.image.get_rect()self.mask = pygame.mask.from_surface(self.image)def render():self.rect.topleft =(self.x,self.y)gameDisplay.blit(self.image,self.rect)倾斜类:def __init __(self,x,y):self.x = xself.y = yself.image = pygame.image.load("posslant.png")self.rect = self.image.get_rect()self.mask = pygame.mask.from_surface(self.image)def render():self.rect.topleft =(self.x,self.y)gameDisplay.blit(self.image,self.rect)#创建对象球=球(250,250)倾斜=倾斜(270,250)#游戏循环gameExit =假而没有(gameExit):#移动球对于pygame.event.get()中的事件:如果event.type == pygame.QUIT:gameExit =真elif event.type == pygame.KEYDOWN:如果event.key == pygame.K_UP:ball.y-= 1elif event.key == pygame.K_DOWN:ball.y + = 1elif event.key == pygame.K_LEFT:ball.x-= 1elif event.key == pygame.K_RIGHT:ball.x + = 1# 碰撞检测offset_x,offset_y =(slant.rect.x-ball.rect.x),(slant.rect.y-ball.rect.y)如果slant.mask.overlap(ball.mask,(offset_x,offset_y)):打印(命中")#绘制所有内容gameDisplay.fill((0,0,0))ball.render()slant.render()pygame.display.update()clock.tick(100) 

解决方案

方法

另请参见:面具

I have made a putt-putt game and now I want to add a slanted wall type. Because of this, I need to use masks for the collision (until now I have just used rects). I have spent hours learning about masks and trying to figure out why my code won't work. There are no errors, the collision just isn't detected.

I have simplified my code down to something much smaller just as a way for me to test it efficiently. From everything I've seen this seems like it should work, but it doesnt. Here it is:

import pygame

# Pygame init stuff
pygame.init()

wind_width = 1200
wind_height = 700

gameDisplay = pygame.display.set_mode((wind_width, wind_height))
pygame.display.set_caption("Mini Golf!")

pygame.display.update()

gameExit = False

clock = pygame.time.Clock()

# Class setups
class Ball:

    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.image = pygame.image.load("sball.png")
        self.rect = self.image.get_rect()
        self.mask = pygame.mask.from_surface(self.image)

    def render(self):
        self.rect.topleft = (self.x, self.y)
        gameDisplay.blit(self.image, self.rect)

class Slant:

    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.image = pygame.image.load("posslant.png")
        self.rect = self.image.get_rect()
        self.mask = pygame.mask.from_surface(self.image)

    def render(self):
        self.rect.topleft = (self.x, self.y)
        gameDisplay.blit(self.image, self.rect)

# Creating objects
ball = Ball(250, 250)

slant = Slant(270, 250)

# Game loop
gameExit = False
while not(gameExit):

    # Moves ball
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                ball.y -= 1
            elif event.key == pygame.K_DOWN:
                ball.y += 1
            elif event.key == pygame.K_LEFT:
                ball.x -= 1
            elif event.key == pygame.K_RIGHT:
                ball.x += 1

    # Collision detection
    offset_x, offset_y = (slant.rect.x - ball.rect.x), (slant.rect.y - ball.rect.y)
    if slant.mask.overlap(ball.mask, (offset_x, offset_y)):
        print("hit")

    # Draws everything
    gameDisplay.fill((0, 0, 0))
    ball.render()
    slant.render()

    pygame.display.update()

    clock.tick(100)

解决方案

The offset parameter of the method overlap() is the relative position of the othermask in relation to the pygame.mask.Mask object.
So the offset is calculated by subtracting the coordinates of slant from the coordinates of ball:

offset_x, offset_y = (slant.rect.x - ball.rect.x), (slant.rect.y - ball.rect.y)

offset = (ball.rect.x - slant.rect.x), (ball.rect.y - slant.rect.y)
if slant.mask.overlap(ball.mask, offset):
    print("hit")
    


When you create the mask images, then I recommend to ensure that the image has per pixel alpha format by calling .convert_alpha():

class Ball:

    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.image = pygame.image.load("sball.png")
        self.rect = self.image.get_rect()
        self.mask = pygame.mask.from_surface(self.image.convert_alpha()) # <---

class Slant:

    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.image = pygame.image.load("posslant.png")
        self.rect = self.image.get_rect()
        self.mask = pygame.mask.from_surface(self.image.image.convert_alpha()) # <---


Minimal example:

See also: Mask

这篇关于Pygame与面具的碰撞不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆