Fehler beim Klicken auf das gestapelte Bild in Pygame [Duplikat]
Ich habe einige Codes zum Klicken und Ziehen von Bildern erstellt, um sie irgendwann zu stapeln. Bei den ersten Klicks hat es gut funktioniert, aber wenn ich es mehrmals an derselben Stelle gestapelt habe, kann es plötzlich nicht mehr angeklickt werden. Wie kann ich das Problem beheben und wenn Sie in Ordnung sind, können Sie es kompakter gestalten?
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()
Der Code, der gif ausführt, befindet sich unten.
https://i.stack.imgur.com/vAQyU.gif
Antworten
Sie haben das rect
Attribut nicht aktualisiert , als die Maustaste losgelassen wurde. Wenn das Bild verschieben, führt dies zu einem Fehler zwischen der Versatz x
, y
und das rect
Attribut:
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

Allerdings müssen Sie nicht die x
und y
Attribute überhaupt. Verwenden Sie stattdessen den im Attribut rect gespeicherten Speicherort:
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()