使光标无法通过精灵pygame的移动

问题描述 投票:2回答:1

所以我的问题很简单:如何让我的鼠标不能穿过精灵?我一直在尝试,我发现了一个不可靠的方式做到这一点,这也是超级出问题。如果有谁知道我怎么可能会去这一点,请大家帮忙。

下面是我目前使用的代码:

import pygame
import pyautogui
import sys
import time

pygame.init()
game_display = pygame.display.set_mode((800,600))
pygame.mouse.set_visible(True)
pygame.event.set_grab(True)
exit = False

class Wall(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((30, 100))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.center = (200, 200)

    def collision(self):
        loc = pygame.mouse.get_pos()
        yy = loc[1]
        xx = loc[0]
        if yy >= self.rect.top and yy <= self.rect.bottom and xx >= self.rect.left and xx <= self.rect.right:
            if xx >= 200: 
                pyautogui.move(216 - xx, 0)
            if xx <= 200: 
                pyautogui.move(-xx + 184, 0)            

w = Wall()
all_sprites = pygame.sprite.Group()
all_sprites.add(w)
print(w.rect.top)
print(w.rect.bottom)
while (not exit):
    mouse_move = (0,0)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                exit = True 
    w.collision()
    clock = pygame.time.Clock()
    game_display.fill((0, 0, 0))
    clock.tick(30)
    all_sprites.update()
    all_sprites.draw(game_display)
    pygame.display.flip()
pygame.quit()

注意:请忽略我的额外的import语句,我会使用他们的后面。

python python-3.x pygame
1个回答
3
投票

要做到你有你想要的检查,如果线形成之前的鼠标位置到新的鼠标位置相交的矩形。写的函数IntersectLineRec其检查的交点,并使用它,并返回的交叉点的列表,由距离排序。该函数返回tules蒙山点和距离的列表:

EG

[((215.0, 177.0), 12.0), ((185.0, 177.0), 42.0)]
prev_loc = pygame.mouse.get_pos()

class Wall(pygame.sprite.Sprite):

    # [...]

    def collision(self):

        global prev_loc

        loc = pygame.mouse.get_pos()
        intersect = IntersectLineRec(prev_loc, loc, self.rect)
        prev_loc = loc

        if intersect:
            ip = [*intersect[0][0]]
            for i in range(2):
                tp = self.rect.center[i] if ip[i] == loc[i] else loc[i]
                ip[i] += -3 if ip[i] < tp else 3
            pyautogui.move(ip[0]-loc[0], ip[1]-loc[1])
            prev_loc = loc = ip

功能IntersectLineRec必须检查如果4个角矩形间门下鼠标位置之间的线之间的4个外行之一:

def IntersectLineRec(p1, p2, rect):
    iL = [
        IntersectLineLine(p1, p2, rect.bottomleft, rect.bottomright),
        IntersectLineLine(p1, p2, rect.bottomright, rect.topright),
        IntersectLineLine(p1, p2, rect.topright, rect.topleft),
        IntersectLineLine(p1, p2, rect.topleft, rect.bottomleft) ]
    iDist = [(i[1], pygame.math.Vector2(i[1][0] - p1[0], i[1][1] - p1[1]).length()) for i in iL if i[0]]
    iDist.sort(key=lambda t: t[1])
    return iDist

IntersectLineRec检查是否到环形输送线,其通过来分定义的相交。然后,它检查该交点是其中由每行(该行是对角线的矩形的)的所定义的矩形:

def IntersectLineLine(l1_p1, l1_p2, l2_p1, l2_p2):
    isect, xPt = IntersectEndlessLineLine(l1_p1, l1_p2, l2_p1, l2_p2)
    isect = isect and PtInRect(xPt, l1_p1, l1_p2) and PtInRect(xPt, l2_p1, l2_p2)
    return isect, xPt

如要检查点是在一个轴对齐矩形具有以检查点的两个坐标是在矩形的坐标范围:

def InRange(coord, range_s, range_e):
    if range_s < range_e:
        return coord >= range_s and coord <= range_e
    return coord >= range_e and coord <= range_s

def PtInRect(pt, lp1, lp2):
    return InRange(pt[0], lp1[0], lp2[0]) and InRange(pt[1], lp1[1], lp2[1])

的无休止的线的交叉点可以被计算如下:

def IntersectEndlessLineLine(l1_p1, l1_p2, l2_p1, l2_p2):

    # calculate the line vectors and test if both lengths are > 0
    P = pygame.math.Vector2(*l1_p1)
    Q = pygame.math.Vector2(*l2_p1)
    line1 = pygame.math.Vector2(*l1_p2) - P
    line2 = pygame.math.Vector2(*l2_p2) - Q
    if line1.length() == 0 or line2.length() == 0:
        return (False, (0, 0))

    # check if the lines are not parallel
    R, S = (line1.normalize(), line2.normalize())
    dot_R_nvS = R.dot(pygame.math.Vector2(S[1], -S[0]))
    if abs(dot_R_nvS) < 0.001:
        return (False, (0, 0))

    # calculate the intersection point of the lines
    # t  =  dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x))
    # X  =  P + R * t
    ptVec = Q-P
    t = ptVec.dot(pygame.math.Vector2(S[1], -S[0])) / dot_R_nvS
    xPt = P + R * t
    return (True, (xPt[0], xPt[1]))

看动画:

© www.soinside.com 2019 - 2024. All rights reserved.