大家好,我又双叒叕来提问了[doge]
最近在学pygame,学到制作打地鼠游戏时,我发现当我想通过点击来消除地鼠时,地鼠并不会消失
-------------------------------------------------------------下面是代码------------------------------------------------------------
import pygame
import random
pygame.init()
pygame.display.set_caption('打地鼠')
screen = pygame.display.set_mode((800, 600))
grass = pygame.image.load('D:\xxx\image\grass.png')
grass = pygame.transform.scale(grass, (800, 600))
hole = pygame.image.load('D:\xxx\image\hole.png')
mouse = pygame.image.load('D:\xxx\image\mouse.png')
hammer = pygame.image.load('D:\xxx\image\hammer.png')
mouse_list = []
mouse_list2 = []
rect_mouse = []
y = 3
x = 4
def new_mouse():
while True:
q = random.randint(0, x*y-1)
abc = mouse_list[q]
if mouse_list[q] not in mouse_list2:
mouse_list2.append(abc)
rect_mouse.append(pygame.Rect(abc[0], abc[1], 100, 112))
break
if len(mouse_list2) == x*y:
break
#用户事件
EVENT = pygame.USEREVENT + 1
#计时器
pygame.time.set_timer(EVENT, 1000)
while True:
pos = pygame.mouse.get_pos()
hole_y = 200
hole_x = 150
screen.blit(grass, (0, 0))
for i in range(y):
hole_x = 150
for o in range(x):
mouse_list.append([hole_x, hole_y])
screen.blit(hole, (hole_x, hole_y))
hole_x += 150
hole_y += 120
for a in mouse_list2:
screen.blit(mouse, [a[0], a[1]-40])
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == EVENT:
new_mouse()
if event.type == pygame.MOUSEBUTTONDOWN:
for a in rect_mouse:
if a.collidepoint(pos):
mouse_list2.remove([a[0], a[1]])
screen.blit(hammer, [pos[0], pos[1]])
pygame.display.update()
pygame.time.Clock().tick(120)
-----------------------------------------下面是报错--------------------------------------
Traceback (most recent call last):
File "D:\xxx\mouse.py", line 59, in <module>
mouse_list2.remove([a[0], a[1]])
ValueError: list.remove(x): x not in list
希望大家给个解答,谢谢!
方案来自 梦想橡皮擦 狂飙组基于 GPT 编写的 “程秘”
你的代码中,当地鼠被点击时,虽然你使用了 collidepoint 方法来判断鼠标是否与地鼠重叠,但是你在移除地鼠时使用的是地鼠坐标的列表 [a[0], a[1]],而不是 rect_mouse 列表中的 Rect 对象。这样就导致了即使你点击了地鼠,它也不会被移除。
你可以将 rect_mouse 列表改成存储 Rect 对象,然后在移除地鼠时使用 remove 方法移除对应的 Rect 对象。修改后的代码如下:
import pygame
import random
pygame.init()
pygame.display.set_caption('打地鼠')
screen = pygame.display.set_mode((800, 600))
grass = pygame.image.load('D:\xxx\image\grass.png')
grass = pygame.transform.scale(grass, (800, 600))
hole = pygame.image.load('D:\xxx\image\hole.png')
mouse = pygame.image.load('D:\xxx\image\mouse.png')
hammer = pygame.image.load('D:\xxx\image\hammer.png')
mouse_list = []
mouse_list2 = []
rect_mouse = []
y = 3
x = 4
def new_mouse():
while True:
q = random.randint(0, x*y-1)
abc = mouse_list[q]
if mouse_list[q] not in mouse_list2:
mouse_list2.append(abc)
rect_mouse.append(pygame.Rect(abc[0], abc[1], 100, 112))
break
if len(mouse_list2) == x*y:
break
#用户事件
EVENT = pygame.USEREVENT + 1
#计时器
pygame.time.set_timer(EVENT, 1000)
while True:
pos = pygame.mouse.get_pos()
hole_y = 200
hole_x = 150
screen.blit(grass, (0, 0))
for i in range(y):
hole_x = 150
for o in range(x):
mouse_list.append([hole_x, hole_y])
screen.blit(hole, (hole_x, hole_y))
hole_x += 150
hole_y += 120
for a in mouse_list2:
screen.blit(mouse, [a[0], a[1]-40])
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == EVENT:
new_mouse()
if event.type == pygame.MOUSEBUTTONDOWN:
for a in rect_mouse:
if a.collidepoint(pos):
rect_mouse.remove(a)
mouse_list2.remove([a[0], a[1]])
screen.blit(hammer, [pos[0], pos[1]])
pygame.display.update()
pygame.time.Clock().tick(120)
根据你的代码和报错信息,可以看出是因为尝试从列表 mouse_list2 中移除一个不存在的元素导致的错误。
具体来说,是因为在处理鼠标点击事件时,你尝试从 rect_mouse 中找到对应的地鼠矩形,并使用 remove 方法从 mouse_list2 中移除该地鼠,但是这里使用的元素 [a[0], a[1]] 并不是 mouse_list2 中的元素,而是 rect_mouse 中对应的矩形的坐标。因此在移除元素时出现了错误。
解决这个问题的方法有多种,以下是一种简单的方法:
在 new_mouse() 函数中创建一个 mouse_rects 列表,用于保存所有地鼠的矩形。
在 pygame.MOUSEBUTTONDOWN 事件处理中,遍历 mouse_rects 列表,找到与当前鼠标位置相交的矩形,并将对应的地鼠从 mouse_list2 中移除。
具体实现代码如下:
import pygame
import random
pygame.init()
pygame.display.set_caption('打地鼠')
screen = pygame.display.set_mode((800, 600))
grass = pygame.image.load('D:\xxx\image\grass.png')
grass = pygame.transform.scale(grass, (800, 600))
hole = pygame.image.load('D:\xxx\image\hole.png')
mouse = pygame.image.load('D:\xxx\image\mouse.png')
hammer = pygame.image.load('D:\xxx\image\hammer.png')
mouse_list = []
mouse_rects = []
y = 3
x = 4
def new_mouse():
while True:
q = random.randint(0, x*y-1)
abc = mouse_list[q]
if abc not in mouse_rects:
mouse_rects.append(abc)
break
if len(mouse_rects) == x*y:
break
#用户事件
EVENT = pygame.USEREVENT + 1
#计时器
pygame.time.set_timer(EVENT, 1000)
while True:
pos = pygame.mouse.get_pos()
hole_y = 200
hole_x = 150
screen.blit(grass, (0, 0))
for i in range(y):
hole_x = 150
for o in range(x):
mouse_list.append(pygame.Rect(hole_x, hole_y, 100, 112))
screen.blit(hole, (hole_x, hole_y))
hole_x += 150
hole_y += 120
for a in mouse_rects:
screen.blit(mouse, [a[0], a[1]-40])
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == EVENT:
new_mouse()
if event.type == pygame.MOUSEBUTTONDOWN:
for a in mouse_rects:
if a.collidepoint(pos):
mouse_rects.remove(a)
screen.blit(hammer, [pos[0], pos[1]])
pygame.display.update()
pygame.time.Clock().tick(120)
你的代码中,处理点击消除地鼠的部分似乎有点问题。你使用collidepoint()方法检测是否点击到了地鼠,但是你传递的是地鼠所在位置的列表 [a[0], a[1]],而不是 pygame.Rect 对象。
你可以尝试将 rect_mouse 列表中存储的 pygame.Rect 对象传递给 collidepoint() 方法,如下所示:
if event.type == pygame.MOUSEBUTTONDOWN:
for a in rect_mouse:
if a.collidepoint(pos):
mouse_list2.remove([a[0], a[1]])
rect_mouse.remove(a)
在这个例子中,当鼠标按下时,程序会遍历 rect_mouse 中的所有 pygame.Rect 对象,并使用 collidepoint() 方法检查鼠标点击是否在矩形内。如果点击在矩形内,则从 mouse_list2 和 rect_mouse 中删除对应的地鼠和矩形对象。
希望这可以解决你的问题!