Erro ao clicar na imagem empilhada no Pygame [duplicado]
Dec 01 2020
Fiz alguns códigos de clicar e arrastar imagens para empilhar em algum ponto. Funcionou bem nos primeiros cliques, mas quando o empilhei várias vezes no mesmo lugar, de repente ele se tornou impossível de clicar. Como posso consertar e se você estiver bem, pode torná-lo mais compacto?
import pygame
from pygame import *
import sys
import os
pygame.init()
s_width = 640
s_height = 480
screen = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption("TITLE")
bigfont = pygame.font.SysFont(None, 50)
smallfont = pygame.font.SysFont(None, 25)
title = bigfont.render("TITLE", True, (0,0,0))
current_path = os.path.dirname(__file__)
img_path = os.path.join(current_path, "images")
img_list = []
place_list = []
temp = []
class Img_Set:
def __init__(self, path, x_pos, y_pos):
self.image = pygame.image.load(path)
self.x_pos = x_pos
self.y_pos = y_pos
self.rect = self.image.get_rect()
self.rect.left = self.x_pos
self.rect.top = self.y_pos
img_list.append(self)
self.click = False
def offset(self):
self.offset_len_x = event.pos[0] - self.x_pos
self.offset_len_y = event.pos[1] - self.y_pos
def drag(self):
self.x_pos = event.pos[0] - self.offset_len_x
self.y_pos = event.pos[1] - self.offset_len_y
self.rect.left = self.x_pos
self.rect.top = self.y_pos
class Place_Set:
def __init__(self, path, x_pos, y_pos):
self.image = pygame.image.load(path)
self.x_pos = x_pos
self.y_pos = y_pos
self.rect = self.image.get_rect()
self.rect.left = self.x_pos
self.rect.top = self.y_pos
place_list.append(self)
self.click = False
img1 = Img_Set("images/80x80_blueball.png", s_width/3, s_height/3)
img2 = Place_Set("images/80x80_ball.png", s_width/2, s_height/3)
img3 = Place_Set("images/80x80_greenball.png", s_width/3*2, s_height/3)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if event.button == 1:
for x in img_list:
if x.rect.collidepoint(event.pos):
temp.append(x)
if len(temp) > 0:
temp[-1].offset()
temp[-1].click = True
img_list.remove(temp[-1])
img_list.append(temp[-1])
temp = []
elif event.type == MOUSEMOTION:
for x in img_list:
if x.click:
x.drag()
elif event.type == MOUSEBUTTONUP:
for x in img_list:
for y in place_list:
if x.rect.colliderect(y.rect):
x.x_pos = y.x_pos
x.y_pos = y.y_pos
for x in img_list:
x.click = False
screen.fill((255, 255, 255))
for x in place_list:
screen.blit(x.image, (x.x_pos, x.y_pos))
for x in img_list:
screen.blit(x.image, (x.x_pos, x.y_pos))
pygame.display.update()
O código em execução no gif está abaixo.
https://i.stack.imgur.com/vAQyU.gif
Respostas
2 Rabbid76 Dec 01 2020 at 23:31
Você perdeu a atualização do rect
atributo, quando o botão do mouse é liberado. Ao arrastar a imagem, isso leva a um erro de deslocamento entre o x
, y
e o rect
atributo:
while True:
for event in pygame.event.get():
# [...]
elif event.type == MOUSEBUTTONUP:
for x in img_list:
for y in place_list:
if x.rect.colliderect(y.rect):
x.x_pos = y.x_pos
x.y_pos = y.y_pos
x.rect.left = y.x_pos # <-- ADD
x.rect.top = y.y_pos # <-- ADD

No entanto, você não precisa dos atributos x
e de forma y
alguma. Em vez disso, use o local salvo no atributo rect:
import pygame
from pygame import *
import sys
import os
pygame.init()
s_width = 640
s_height = 480
screen = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption("TITLE")
bigfont = pygame.font.SysFont(None, 50)
smallfont = pygame.font.SysFont(None, 25)
title = bigfont.render("TITLE", True, (0,0,0))
current_path = os.path.dirname(__file__)
img_path = os.path.join(current_path, "images")
img_list = []
place_list = []
temp = []
class Img_Set:
def __init__(self, path, x_pos, y_pos):
self.image = path # pygame.image.load(path)
self.rect = self.image.get_rect()
self.rect.left = x_pos
self.rect.top = y_pos
img_list.append(self)
self.click = False
def offset(self):
self.offset_len_x = event.pos[0] - self.rect.x
self.offset_len_y = event.pos[1] - self.rect.y
def drag(self):
self.rect.x = event.pos[0] - self.offset_len_x
self.rect.y = event.pos[1] - self.offset_len_y
class Place_Set:
def __init__(self, path, x_pos, y_pos):
self.image = path # pygame.image.load(path)
self.rect = self.image.get_rect()
self.rect.left = x_pos
self.rect.top = y_pos
place_list.append(self)
self.click = False
img1 = Img_Set("images/80x80_blueball.png", s_width/3, s_height/3)
img2 = Place_Set("images/80x80_ball.png", s_width/2, s_height/3)
img3 = Place_Set("images/80x80_greenball.png", s_width/3*2, s_height/3)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if event.button == 1:
for x in img_list:
if x.rect.collidepoint(event.pos):
temp.append(x)
if len(temp) > 0:
temp[-1].offset()
temp[-1].click = True
img_list.remove(temp[-1])
img_list.append(temp[-1])
temp = []
elif event.type == MOUSEMOTION:
for x in img_list:
if x.click:
x.drag()
elif event.type == MOUSEBUTTONUP:
for x in img_list:
for y in place_list:
if x.rect.colliderect(y.rect):
x.rect.x = y.rect.x
x.rect.y = y.rect.y
for x in img_list:
x.click = False
screen.fill((255, 255, 255))
for x in place_list:
screen.blit(x.image, x.rect)
for x in img_list:
screen.blit(x.image, x.rect)
pygame.display.update()
O que significa um erro “Não é possível encontrar o símbolo” ou “Não é possível resolver o símbolo”?
Christopher Nolan uma vez se arrependeu de ter lido o 'roteiro de Pulp Fiction' de Quentin Tarantino