我正试图制作这款游戏的近乎抄本:
https://yppedia.puzzlepirates.com/Carpentry
它使用pentominos,它是由5个块组成的对象。我有一个Piece类,它将每个块存储在一个列表中。当我点击一个块来移动它时,我也会移动每个共享同一个父对象的块,所以我可以用鼠标拖动整个块。
我遇到的问题是,当我点击其中一个块时,该部分会从光标移开。拖动很好,但我希望它能更准确地跟踪光标。
我正在使用Mouse类,因此我可以在鼠标点击和Blocks之间实现简单的碰撞,但我认为这是我遇到问题的原因。
编辑:我可以通过硬编码更改每个块的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)
答案 0 :(得分:1)
我是这样做的:如果单击了一个块,将其父片段分配给变量并计算块的偏移量,如下所示:block.offset = block.rect.topleft - Vec(event.pos)
。在文件顶部,您需要导入from pygame.math import Vector2 as Vec
。现在,您可以检查pygame.MOUSEMOTION
个事件并将块移动到新的event.pos + block.offset
。
Mouse