python - 如何调用特定对象的方法并仅影响作为pygame中字典键值的对象?
问题描述
我是编程新手。我正在练习 python 并使用 pygame 编写一个小游戏。我在 pygame 窗口上有十个圆圈,每个圆圈都有一个计数器。单击圆圈时,我想将计数器增加 1。我首先使用 .sprite.Group() 创建了组,但我无法获得所需的结果。因为那时计数器甚至没有得到更新。所以我创建了两个列表,一个用于圆圈,一个用于计数器。对于圆圈列表中的每个圆圈,我创建了一个以圆圈为键的字典,圆圈列表中的每个计数器都是圆圈的值。现在,当点击圆圈时,所有计数器都会更新,而不是圆圈持有的计数器。但目标是为其圈子更新特定的计数器。(孔==圆)
dig_hole.py(这是主文件。)
import pygame
import sys
from pygame.sprite import Group
from counter import Counter
from hole import Hole
from settings import Settings
class DigHole:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Dig Hole")
pygame.display.set_icon(Hole(self).image)
self.count = Counter(self)
self.counter_group = list()
self.holes = list()
self.dict = dict()
self._create_holes()
self.hole = Hole(self)
self.mouse_pos = (0, 0)
def run_dig_hole(self):
while True:
self._check_events()
self._update_screen()
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
self.mouse_pos = pygame.mouse.get_pos()
self._check_hole_clicked_events(self.mouse_pos)
def _check_hole_clicked_events(self, mouse_pos):
for key in self.dict:
if key.rect.collidepoint(mouse_pos):
self.dict[key].count_clock += 1
self.dict[key].prep_counter()
self.count.prep_counter()
def _create_holes(self):
for row_number in range(2):
for hole_number in range(5):
self._create_hole(row_number, hole_number)
for hole in self.holes:
counter = Counter(self)
counter.counter_rect.midbottom = hole.rect.midtop
self.counter_group.append(counter)
for hole in self.holes:
for counter in self.counter_group:
self.dict[hole] = counter
def _create_hole(self, row_number, hole_number):
hole = Hole(self)
hole_width, hole_height = hole.rect.size
available_space_x = self.settings.screen_width - (2 * hole_width)
available_space_y = self.settings.screen_height - (2 * hole_height)
hole.x =(((available_space_x // 5) - hole_width) // 2) + (available_space_x // 5) * hole_number
hole.rect.x = hole.x
hole.rect.y = 2 * hole.rect.height + (available_space_y - (4 * hole_height)) * row_number
self.holes.append(hole)
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
for key in self.dict:
key.draw()
for key in self.dict:
self.dict[key].counter_rect.midbottom = key.rect.midtop
self.dict[key].show_counter()
self.count.show_counter()
pygame.display.flip()
if __name__ == '__main__':
dh = DigHole()
dh.run_dig_hole()
孔.py
import pygame
from pygame.sprite import Sprite
class Hole():
def __init__(self, dh):
# super().__init__()
self.screen = dh.screen
self.image = pygame.image.load("images/circle.bmp")
self.rect = self.image.get_rect()
self.rect.x = self.rect.width
self.rect.y = self.rect.height
self.x = float(self.rect.x)
def draw(self):
self.screen.blit(self.image, self.rect)
计数器.py
import pygame.font
from pygame.sprite import Sprite
class Counter():
def __init__(self, dh):
# super().__init__()
self.screen = dh.screen
self.screen_rect = self.screen.get_rect()
self.settings = dh.settings
self.count_clock = 0
self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)
self.prep_counter()
def prep_counter(self):
counter_str = str(self.count_clock)
self.counter_image = self.font.render(counter_str, True, self.text_color, self.settings.bg_color)
self.counter_rect = self.counter_image.get_rect()
self.counter_rect.right = self.screen_rect.right - 20
self.counter_rect.top = 20
def show_counter(self):
self.screen.blit(self.counter_image, self.counter_rect)
解决方案
问题在于,在 中_create_holes
,您将每个圆圈的计数器设置为相同的 Counter 对象。
for hole in self.holes:
for counter in self.counter_group:
self.dict[hole] = counter
展开内部循环,这与
for hole in self.holes:
self.dict[hole] = self.counter_group[0]
self.dict[hole] = self.counter_group[1]
self.dict[hole] = self.counter_group[2]
...
self.dict[hole] = self.counter_group[-1]
第一个分配都立即被覆盖,因此此代码将每个self.dict
值设置为self.counter_group[-1]
. 你想做的是
for hole, counter in zip(self.holes, self.counter_group):
self.dict[hole] = counter
self.holes
它同时迭代两者self.counter_group
。在您的情况下,您实际上可以将其重写为
self.dict = dict(zip(self.holes, self.counter_group))
哪个更好。
我不确定,但我认为你打算self.count
成为一个总。如果是这种情况,它就不会起作用了:你从_check_hole_clicked_events
. 它应该如下所示:
def _check_hole_clicked_events(self, mouse_pos):
for key in self.dict:
if key.rect.collidepoint(mouse_pos):
self.dict[key].count_clock += 1
self.dict[key].prep_counter()
self.count.count_clock += 1
self.count.prep_counter()
作为旁注,我注意到您还编写list()
并dict()
创建了空列表和字典。仅编写文字 ([]
和{}
) 会更有效和更惯用。
推荐阅读
- git - Git - 将生产仓库下载到本地仓库
- javascript - 打开时的 Magnific Popup 焦点按钮
- xaml - 如何在 uwp 10 应用程序下将笔划应用于 xaml 中的文本块
- android - Google Play In-app Billing API 版本低于 3
- c# - Xamarin.Forms.Theme.Dark xmls 声明导致错误“无法创建相对 URI...”
- javascript - 我的 javascript 触发器在我的 CSS 媒体查询代码中不起作用
- json - JSON 的骆驼绑定模式不起作用,无法将其解组为 POJO
- python - 仅重命名熊猫数据框中的最后一列(考虑重复的标题)
- sql - 在 SQL 中取 dummy 的平均值
- postgresql - PostgreSQL 视图查询的性能