gpt4 book ai didi

python - Pygame 中鼠标的对象移动不准确

转载 作者:太空宇宙 更新时间:2023-11-03 15:01:53 25 4
gpt4 key购买 nike

我正在尝试制作该游戏的近似副本:

https://yppedia.puzzlepirates.com/Carpentry

它使用五联骨牌,即由 5 个方 block 组成的物体。我有一个 Piece 类,它将每个 block 存储在列表中。当我单击一个 block 来移动它时,我还会移动共享同一父 block 对象的所有其他 block ,因此我可以用鼠标拖动整个 block 。

我遇到的问题是,当我单击其中一个 block 时,该 block 会远离我的光标。拖动效果很好,但我希望它能够更精确地跟随光标。

我正在使用鼠标类,因此我可以实现鼠标单击和 block 之间的简单碰撞,但我认为这是我的问题的原因。

编辑:我可能可以通过对每个 block 的 x 和 y 位置进行硬编码更改来解决此问题,但理想情况下我更喜欢更模块化的解决方案,因为我认为我误解了鼠标位置在 pygame 中的工作原理。

import pygame
import sys
import collections
import random

pygame.init()
FPS = 25
fpsClock = pygame.time.Clock()

# -----------SCREEN----------------#
WIN_WIDTH = 680 # width of window
WIN_HEIGHT = 500 # height of window
DISPLAY = (WIN_WIDTH, WIN_HEIGHT) # variable for screen display
DEPTH = 32 # standard
FLAGS = 0 # standard
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption('Carpentry')
# ---------------------------------#

# ---------------colours-----------#
WOOD = (182, 155, 76)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
# ---------------------------------#

blocks = pygame.sprite.Group()
pieces = []

class Block(pygame.sprite.Sprite):
def __init__(self, x, y, parent):
super().__init__()
self.image = pygame.Surface([15, 15])
self.colour = WOOD
self.parent = parent
self.image.fill(self.colour)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.original_x = x
self.original_y = y
self.drag = False

class Mouse(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface([15, 15])
self.colour = RED
self.image.fill(self.colour)
self.rect = self.image.get_rect()
self.rect.x = pygame.mouse.get_pos()[0]
self.rect.y = pygame.mouse.get_pos()[1]

def update_mouse(self):
self.rect.x = pygame.mouse.get_pos()[0]
self.rect.y = pygame.mouse.get_pos()[1]

class Piece:
def __init__(self):
self.blocks = []
self.c = 0

def insert(self, template):
for direction in template:
self.blocks.append([])
x = 0
y = 0
for line in direction:
for character in line:
if character == "O":
my_block = Block(x, y, self)
self.blocks[self.c].append(my_block)
blocks.add(my_block)

x += 15
y += 15
x = 0
self.c += 1

J_TEMPLATE = [['..O..',
'..O..',
'..O..',
'.OO..',
'.....']]
templates = {}

my_piece = Piece()
my_piece.insert(J_TEMPLATE)
pieces.append(my_piece)

mouse = Mouse()
while True:
screen.fill(BLACK)

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
bool = pygame.sprite.spritecollide(mouse, blocks, False)
if len(bool) > 0:
target = bool[0]
target.drag = True
for block in blocks:
if block.parent == target.parent: #if blocks are part of the same piece
block.drag = True
else:
for block in blocks:
block.drag = False
mouse.update_mouse()
for block in blocks:
if block.drag == True:
block.rect.x = mouse.rect.x + block.original_x
block.rect.y = mouse.rect.y + block.original_y

blocks.draw(screen)
pygame.display.update()
fpsClock.tick(FPS)

最佳答案

我会这样做:如果单击了一个 block ,则将其父 block 分配给一个变量并计算 block 的偏移量,如下所示:block.offset = block.rect.topleft - Vec(事件.pos)。在文件顶部,您需要导入 from pygame.math import Vector2 as Vec。现在,您可以检查 pygame.MOUSEMOTION 事件并将 block 移动到新的 event.pos + block.offset。不再需要 Mouse 类。

selected = None

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if selected: # If a piece was selected ...
selected = None # Deselect it.
else:
# Find a colliding block.
collided_sprites = [block for block in blocks
if block.rect.collidepoint(event.pos)]
if collided_sprites: # If we clicked a block ...
# Select the parent of the block.
selected = collided_sprites[0].parent
# Calculate the offsets for the blocks.
for block in selected.blocks[0]:
block.offset = block.rect.topleft - Vec(event.pos)
elif event.type == pygame.MOUSEMOTION:
if selected:
# Update the block positions by adding their offsets to the mouse pos.
for block in selected.blocks[0]:
block.rect.topleft = event.pos + block.offset

screen.fill(BLACK)
blocks.draw(screen)
pygame.display.update()
fpsClock.tick(25)

关于python - Pygame 中鼠标的对象移动不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45007854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com