如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象
Posted
技术标签:
【中文标题】如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象【英文标题】:How to create multiple objects of a class with unique name values gathered from a list in a csv file 【发布时间】:2021-06-04 08:42:55 【问题描述】:我是编程新手,我正在努力弄清楚如何让它发挥作用。我正在尝试构建一个名为“宠物流行病”的简单游戏,您基本上只需按开始键,用不同颜色的点标记的“宠物”就会在窗口的网格上四处游荡。一些宠物与“病毒”一起产卵。在漫游时,宠物会查看它们是否彼此相距一定距离,如果是,它们会将病毒传播给尚未感染病毒的另一只,进而更新该宠物的状态以具有“病毒”和点图像将更新为红色。游戏将一直运行,直到每个“宠物”都感染了“病毒”。我正在努力实现一种方法来生成具有独特名称的“宠物”,例如“Alex”或“Doug”。我想为此使用 .csv 文件中的名称列表。
感谢您的宝贵时间。 以下是文件: https://drive.google.com/drive/folders/1tjEY6Eo1nKKtEr0st1CUFkcnBvvbiMn1?usp=sharing
import pygame
import random
import math
import time
# Window settings
WIDTH = 960
HEIGHT = 660
TITLE = "PET PANDEMIC"
FPS = 60
#create window
pygame.init()
screen = pygame.display.set_mode([WIDTH, HEIGHT])
pygame.display.set_caption(TITLE)
clock = pygame.time.Clock()
#Game Stages
START = 0
PLAYING = 1
END = 2
#Define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (132, 201, 217)
# Load fonts
title_font = default_font = pygame.font.Font("fonts/recharge bd.ttf", 60)
default_font = pygame.font.Font(None, 55)
# Load images
has_v_img = pygame.image.load("red_dot.png").convert_alpha()
no_v_img = pygame.image.load("grey_dot.png").convert_alpha()
no_v_mask_img = pygame.image.load("black_dot.png").convert_alpha()
#Game classes
class Pet(pygame.sprite.Sprite):
def __init__(self, name, x, y):
super().__init__()
self.wearing_mask = random.randint(0, 1) # 0 = no, 1 = yes.
self.has_virus = random.randint(0, 6) # 6 = Virus
if self.has_virus == 6:
self.image = has_v_img
elif self.wearing_mask != 1 and self.has_virus != 6:
self.image = no_v_mask_img
else:
self.image = no_v_img
self.rect = self.image.get_rect()
self.rect.center = x, y
self.name = name
self.dir = random.randint(0, 3)
self.is_alive = True
self.print_name()
def print_name(self):
amnt_w_virus = 0
if self.has_virus == 6:
print("Spawned ".format(self.name) + "With The Virus!")
amnt_w_virus += 1
else:
print("Spawned .".format(self.name))
return amnt_w_virus
def check_distance(self, other):
distance = math.sqrt(((self.x - other.x) ** 2) + ((self.y - other.y) ** 2))
if distance < 6 and self.has_virus == 6:
other.has_virus = 6
print(self.name + " Was In Range Of " + other.name + " And Gave Them The Virus.")
amnt_w_virus += 1
else:
return amnt_w_virus
def roam(self):
while game_running:
if self.is_alive == True:
time.sleep(1.5)
self.dir = random.randint(0, 3)
self.move()
def move(self):
if self.dir == 0:
self.rect.y += 1
elif self.dir == 1:
self.rect.x += 1
elif self.dir == 2:
self.rect.y -= 1
elif self.dir == 3:
self.rect.x -= 1
if self.rect.left < 0:
self.rect.left = 0
elif self.rect.top > HEIGHT:
self.rect.top = HEIGHT
elif self.rect.right > WIDTH:
self.rect.right = WIDTH
print(self.name + " Moved Forward In Direction " + str(self.dir) + " (" + str(self.x) + "," + str(self.y) + ").")
class Players(pygame.sprite.Group):
def __init__(self, *sprites):
super().__init__(*sprites)
def update(self, *args):
super().update(*args)
self.check_distance()
self.roam()
# Setup
def new_game():
global players
#Random Spawn Location Inside Window
start_x = random.randint(0,WIDTH)
start_y = random.randint(0,HEIGHT)
#Open List Of Names To Use For The Pets
f = open("names.csv", "r")
reader = csv.reader(f)
name = []
for row in reader:
name.append(row)
pet =
#Here Im trying to spawn the pets and assign them unique names from the list but this code is all messed up
for item in name:
name = ''.format(item)
pet[name] = pet.get(name, Pet(name=name))
pets = Pet([name], start_x, start_y)
#making players = a sprite group of all the pets
players = Players(pets)
#trying to calculate the number of pets without the virus
players.amount_alive = len(players) - amnt_w_virus
print(players.amnt_alive)
#grid overlay
def draw_grid(width, height, scale):
for x in range(0, WIDTH, scale):
pygame.draw.line(screen, WHITE, [x, 0], [x, HEIGHT], 1)
for y in range(0, HEIGHT, scale):
pygame.draw.line(screen, WHITE, [0, y], [WIDTH, y], 1)
def display_stats():
infected_text = default_font.render("Infected: " + str(amnt_w_virus), True, WHITE)
rect = infected_text.get_rect()
rect.top = 20
rect.left = 20
screen.blit(infected_text, rect)
non_infected_text = default_font.render("Non-Infected: " + str(players.amount_alive), True, WHITE)
rect = non_infected_text.get_rect()
rect.top = 20
rect.right = WIDTH - 20
screen.blit(non_infected_text, rect)
time_text = default_font.render("Time: " + str(time.time), True, WHITE)
rect = time_text.get_rect()
rect.bottom = HEIGHT - 20
rect.left = 20
screen.blit(time_text, rect)
def start_screen():
screen.fill(BLACK)
title_text = title_font.render(TITLE, True, WHITE)
rect = title_text.get_rect()
rect.centerx = WIDTH // 2
rect.bottom = HEIGHT // 2 - 15
screen.blit(title_text, rect)
sub_text = default_font.render("Press Any Key To Start The Spread", True, WHITE)
rect = sub_text.get_rect()
rect.centerx = WIDTH // 2
rect.top = HEIGHT // 2 + 15
screen.blit(sub_text, rect)
def end_screen():
end_text = default_font.render("GAME OVER, EVERYONE IS INFECTED.", True, WHITE)
rect = end_text.get_rect()
rect.centerx = WIDTH // 2
rect.centery = HEIGHT // 2
screen.blit(end_text, rect)
# Game loop
new_game()
stage = START
running = True
while running:
# Input handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if stage == START:
stage = PLAYING
elif stage == END:
if event.key == pygame.K_r:
new_game()
stage = START
# Game logic
if stage != START:
players.update()
if len(players) == 0:
stage = END
# Drawing Code
screen.fill(BLUE)
draw_grid(960, 660, 20)
players.draw(screen)
display_stats()
pygame.display.flip()
if stage == START:
start_screen()
elif stage == END:
end_screen()
# Update screen
pygame.display.update()
# Limit refresh rate of game loop
clock.tick(FPS)
# Close window and quit
pygame.quit() ```
【问题讨论】:
【参考方案1】:您正在覆盖名为 name
的对象:
for item in name:
name = ''.format(item) ### BAD BAD BAD BAD BAD
pet[name] = pet.get(name, Pet(name=name))
pets = Pet([name], start_x, start_y)
#making players = a sprite group of all the pets
players = Players(pets)
如果您真的想这样做,那么您需要通过将其转换为列表来保留 name
中的项目。
for item in list(name):
name = ''.format(item)
pet[name] = pet.get(name, Pet(name=name))
pets = Pet([name], start_x, start_y)
#making players = a sprite group of all the pets
players = Players(pets)
我确定您实际上并不想这样做,所以只需使用不同的变量名(例如 _name
)。
for item in name:
_name = ''.format(item)
pet[_name] = pet.get(_name, Pet(name=_name))
pets = Pet([_name], start_x, start_y)
#making players = a sprite group of all the pets
players = Players(pets)
【讨论】:
当我运行你的代码时,它给了我这个错误。line 219, in new_game pet[_name] = pet.get(_name, Pet(name=_name)) TypeError: __init__() missing 2 required positional arguments: 'x' and 'y'
以上是关于如何创建具有从 csv 文件中的列表收集的唯一名称值的类的多个对象的主要内容,如果未能解决你的问题,请参考以下文章
Ms-Access 尝试使用“传输文本”创建具有唯一文件名的 csv 文件