【问题标题】:Rotating Mask collision in PygamePygame中的旋转蒙版碰撞
【发布时间】:2018-05-30 17:12:42
【问题描述】:

所以我正在尝试制作一个有 2 个对象的游戏,并尝试让我的程序知道 2 个对象何时发生碰撞。

if players[0].mask.overlap(players[1].mask, offset):
    print("collided")`

我的对象顺时针和逆时针旋转,头部和身体都有面具。 (我有两张相同大小的图片,但一张只包含头部,另一张只包含身体,以便使用mask.from_surface()。)

def turn(self, event):
    self.surface = self.ojSurface
    if event == 0:
        self.deg -= self.turnSpd
    elif event == 1:
        self.deg += self.turnSpd
    self.surface = pygame.transform.rotate(self.surface, self.deg)
    self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
    self.mask = pygame.mask.from_surface(self.surface)

但是,我发现当我尝试在它们旋转时检查碰撞时,蒙版与图像不在同一个位置。它应该通过调用每个循环的移动函数每帧更新掩码

def move(self):
    self.pos[0] = pygame.mouse.get_pos()[0]
    self.pos[1] = pygame.mouse.get_pos()[1]
    self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
    self.mask = pygame.mask.from_surface(self.surface)

Faulty Hit Detection

如果您想仔细阅读我到目前为止所拥有的内容,那就是:

import pygame

class Player:

    def __init__(self, pos,surface,screen):
        self.pos = [pos[0],pos[1]]
        self.newPos = (pos[0] - surface.get_width()/2, pos[1] - surface.get_height()/2)
        self.deg = 0
        self.surface = surface
        self.ojSurface = surface
        self.screen = screen
        self.mask = pygame.mask.from_surface(self.surface)

    def turn(self, event):
        self.surface = self.ojSurface

        #clockwise
        if event == 0:
            self.deg -= 0.1

        #counter clockwise
        elif event == 1:
            self.deg += 0.1
        self.surface = pygame.transform.rotate(self.surface, self.deg)

        #resetting pos and mask
        self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
        self.mask = pygame.mask.from_surface(self.surface)

    def move(self):
        self.pos[0] = pygame.mouse.get_pos()[0]
        self.pos[1] = pygame.mouse.get_pos()[1]
        self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
        self.mask = pygame.mask.from_surface(self.surface)

    def draw(self):
        self.screen.blit(self.surface, self.newPos)

screenRes = (640,480)
screen = pygame.display.set_mode(screenRes)
closed = False
players = [Player((320,240),pygame.image.load("body.png"), screen),Player((480,240),pygame.image.load("body.png"), screen)]

controls = [[pygame.K_a,pygame.K_s],[pygame.K_k,pygame.K_l]]
while not closed:
    screen.fill((0, 0, 0))
    keys = pygame.key.get_pressed()
    offset = (int(players[0].newPos[0] - players[1].newPos[0]), int(players[0].newPos[1] - players[1].newPos[1]))

    #collision
    if players[0].mask.overlap(players[1].mask, offset):
        print("collided")

    #controls
    for i in range(len(players)):
        if keys[controls[i][0]]:
            players[i].turn(0)
        if keys[controls[i][1]]:
            players[i].turn(1)
        players[i].draw()

    players[0].move()
    pygame.display.update()
    for event in pygame.event.get():
        # standard quit
        if event.type == pygame.QUIT:
            pygame.display.quit()
            closed = True
            pygame.quit()

【问题讨论】:

  • 请阅读minimal, complete and verifiable example 页面。我们不喜欢阅读和调试数百行未知代码。
  • 谢谢,这个简短的例子更容易阅读。我忘了提到项目的外部链接在这里也是不受欢迎的,因为代码可能会更改或链接可能会丢失。最好将 Test.py 文件的内容添加到您的问题中。

标签: python pygame


【解决方案1】:

您以错误的顺序计算 offset。从players[1] 的位置减去players[0] 的位置:

offset = (
    int(players[1].newPos[0] - players[0].newPos[0]),
    int(players[1].newPos[1] - players[0].newPos[1]),
)

【讨论】:

    【解决方案2】:

    所以我查看了您的 GitHub 代码,虽然我不完全确定(我浏览了您的代码,寻找某些被调用的方法),但我相信您不会每帧都更新掩码。在您的代码中的某处,您必须在每帧/循环中更新掩码,以使碰撞正常工作。尝试更新所有的面具,头部、身体和 Player 类中的面具。希望这会有所帮助!

    【讨论】:

    • 我已经通过self.mask = pygame.mask.from_surface(self.surface) 更新了我的面具,面具应该通过move() 函数更新,它移动播放器并在每次主循环循环时调用。它还应该通过转动播放器的turn() 函数进行更新。我还尝试在屏幕更新之前通过调用players[0].body.mask = pygame.mask.from_surface(players[0].body.surface) 来更新面具本身。我更新面具了吗?
    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多