【问题标题】:In Pygame, how to give different attributes to a circle in a while loop?在 Pygame 中,如何在 while 循环中为圆赋予不同的属性?
【发布时间】:2017-12-06 20:09:39
【问题描述】:

我正在创建一个类似于 Haxball 的 NBA 模拟器,其中每个圈子都应该有一个用户名并且是自己的东西,以便在程序运行期间单个圈子可以改变自己的属性,例如球员变慢但不是每个人都这样做。

我在团队类中使用了几行代码来创建 Player 并将它们放入 team1players 列表中。这确实适用于创建 5 个不同坐标的圆圈。但是,我需要 playername 属性(来自 Player 类)为每个圈子更改,因为只有某些玩家扮演某些位置。我曾尝试在 for 循环中使用 self.composition,但它不允许我将字典用作 int。我需要创建的每个玩家都是不同的玩家名称 - 玩家名称来自包含所有位置的组合字典。到目前为止,我已经在组合中的控球后卫位置上添加了 1 个名字(何塞卡尔德隆),并且我尝试在创建圈子时使用控卫名单,但是这导致所有球员都被命名为何塞卡尔德隆,而不仅仅是 team1players[0](作为控球后卫)叫 Jose。

以下是我需要帮助的代码部分 - 还有很多其他缺陷,但这是一个基本原型:

self.team1players = []
for i in range(numPlayers):
    self.team1players.append(Player('Ruari', 15, random.randint(0,470),random.randint(0,500), Team1Colour, 0, Team1Name, 0.01, 30))
self.team2players = []#
for i in range(numPlayers):
    self.team2players.append(Player(self.composition['point guard'], 15, random.randint(470,940),random.randint(0,500), Team2Colour, 0, Team2Name, 0.01, 30))

以下是完整的代码,因为任何人都可能需要它来了解正在发生的事情。现在有点乱,抱歉。 :'(

import pygame
import random
import math
pygame.init()#initialising python

(width, height) = (940,500)#variables for screen
screen = pygame.display.set_mode((width, height)) #sets the screen size as "screen"
pygame.display.set_caption('Basketball Simulator') #sets the title of the window
background_image = pygame.image.load("bballcourt.jpg") #setting the background image as a variable to be used to display on the screen
icon_image = pygame.image.load("basketball-tiny.png") #setting the icon image

numPlayers = 5

class teams():

    def __init__(self, teamname = "unknown", wins = "0", losses = "0", team1player = "unknown", team2player ="unknown", colour = "255,255,255"):
        #above I have created all the attributes of teams
        self.teamname = teamname #sets teamname
        self.composition = {
            'point guard' : [],
            'shooting guard': [],
            'small forward': [],
            'power forward': [],
            'centre': []
        }
        self.wins = wins #number of wins
        self.losses = losses #number of losses
        self.team1player = team1player #holds a player and can be used to create players I have made this here so that the players are a part of the team
        self.team2player = team2player

        self.colour = colour #holds the rgb colour specific to the team

    def startTeam(self):
        validTeamChoice1 = False #creating a while loop to only allow valid inputs for the first team choice
        validTeamChoice2 = False #loop for second team choice
        userChoice1 = " " 
        Team1Colour = userChoice1
        Team1Name = " "
        userChoice2 = " "
        Team2Colour = userChoice2
        Team2Name = " "
        while validTeamChoice1 == False:
            userChoice1 = self.teamname = input("Please select a team // GSW or CAVS: ") #allowing user input
            if userChoice1.upper() == "GSW":
                userChoice1 = self.teamname = ("Golden State Warriors")
                Team1Colour = self.colour = (0,107,182) #rgb colour for GSW yellow
                Team1Name = self.teamname
                if userChoice1 == self.teamname:
                    validTeamChoice1 = True
            else:
                validTeamChoice1 = False #continues loop
        while validTeamChoice2 == False:
            userChoice2 = self.teamname = input("Please select an opposing team // GSW or CAVS: ")
            if userChoice2.upper() == "CAVS":
                userChoice2 = self.teamname = ("Cleveland Cavaliers")
                Team2Colour = self.colour = (134,0,56) #rgb colour for CAVS red
                Team2Name = self.teamname
                self.composition['point guard'].append('Jose Calderon')
                if userChoice2 == self.teamname:
                    validTeamChoice2 = True
            else:
                validTeamChoice2 = False

        self.team1players = []
        for i in range(numPlayers):
            self.team1players.append(Player('Ruari', 15, random.randint(0,470),random.randint(0,500), Team1Colour, 0, Team1Name, 0.01, 30))
        self.team2players = []#
        for i in range(numPlayers):
            self.team2players.append(Player(self.composition['point guard'], 15, random.randint(470,940),random.randint(0,500), Team2Colour, 0, Team2Name, 0.01, 30))
    def displayPlayers(self): #displays the player using the player attributes and the display method from the Player class
        for n in range(numPlayers):
            self.team1players[n].displayCircle() 
            self.team2players[n].displayCircle()
    def printPlayers(self):
        print(self.team2players[1].playername)

class Player(): #the player class holds information on the player symbol
    def __init__(self, playername, size, x, y, colour, thickness,teamname,speed, angle): #teamname is predetermined
        self.playername = playername
        self.size = size #size is a unit for the radius
        self.x = x #x, y are position on the court 
        self.y = y
        self.speed = speed
        self.angle = angle
        self.colour = colour
        self.thickness = 0 #thickness is set to 0

    def displayCircle(self): #drawing the circle onto the screen using colour, co-ordinates and radii
            pygame.draw.circle(screen, self.colour, (self.x, self.y), self.size, self.thickness)




pygame.display.set_icon(icon_image)
screen.blit(background_image, [0,0]) #this sets the background court image (note: its outside all the classes) 
myTeam1 = teams() #creates a myTeam1 object from the teams class
myTeam1.startTeam() #runs the startTeam method from the teams class
myTeam1.displayPlayers() #runs the displayPlayers method from the teams
pygame.display.flip() #updates the screen based on current events ("flip" is the same as "update()")
myTeam1.printPlayers()
#the below code monitors current on screen events should they be needed for movement etc. it also allows the window to be closed.
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            quit

感谢您的帮助!

编辑 下面我做了它,以便在用户选择一个团队后将相关球员附加到他们的位置(每个球队都有不同的球员),我还创建了一个新的组成属性在teams类中-现在有team1composition和team2composition,这样两支球队都有不同的控球后卫,得分后卫等。有没有更有效的方法?起初我计划将两支球队的球员都列在字典的列表中,然后我会使用数组来选择哪个球员是哪个球队的,但我认为这样会更好?

class teams(): 

    def __init__(self, teamname = "unknown", wins = "0", losses = "0", team1player = "unknown", team2player ="unknown", colour = "255,255,255"):
        #above I have created all the attributes of teams
        self.teamname = teamname #sets teamname
        self.team1composition = {
            'point guard' : [],
            'shooting guard': [],
            'small forward': [],
            'power forward': [],
            'centre': []
        }
        self.team2composition = {
            'point guard' : [],
            'shooting guard': [],
            'small forward': [],
            'power forward': [],
            'centre': []
        }
        self.wins = wins #number of wins
        self.losses = losses #number of losses
        self.team1player = team1player #holds a player and can be used to create players I have made this here so that the players are a part of the team
        self.team2player = team2player

        self.colour = colour #holds the rgb colour specific to the team

    def startTeam(self):
        validTeamChoice1 = False #creating a while loop to only allow valid inputs for the first team choice
        validTeamChoice2 = False #loop for second team choice
        userChoice1 = " " 
        Team1Colour = userChoice1
        Team1Name = " "
        userChoice2 = " "
        Team2Colour = userChoice2
        Team2Name = " "
        while validTeamChoice1 == False:
            userChoice1 = self.teamname = input("Please select a team // GSW or CAVS: ") #allowing user input
            if userChoice1.upper() == "GSW":
                userChoice1 = self.teamname = ("Golden State Warriors")
                Team1Colour = self.colour = (0,107,182) #rgb colour for GSW yellow
                Team1Name = self.teamname
                if userChoice1 == self.teamname:
                    validTeamChoice1 = True
            else:
                validTeamChoice1 = False #continues loop
        while validTeamChoice2 == False:
            userChoice2 = self.teamname = input("Please select an opposing team // GSW or CAVS: ")
            if userChoice2.upper() == "CAVS":
                userChoice2 = self.teamname = ("Cleveland Cavaliers")
                Team2Colour = self.colour = (134,0,56) #rgb colour for CAVS red
                Team2Name = self.teamname
                self.team2composition['point guard'].append('Jose Calderon')
                self.team2composition['shooting guard'].append('J.R Smith')
                self.team2composition['small forward'].append('LeBron James')
                self.team2composition['power forward'].append('Jae Crowder')
                self.team2composition['centre'].append('Kevin Love')
                if userChoice2 == self.teamname:
                    validTeamChoice2 = True
            else:
                validTeamChoice2 = False

        self.team1players = []
        for position , name in self.team1composition.items():
            print (position, name)
            self.team1players.append(Player(name, 15, random.randint(0,470),random.randint(0,500), Team1Colour, 0, Team1Name, 0.01, 30))
        self.team2players = []#
        for position, name in self.team2composition.items():
            print(position , name)
            self.team2players.append(Player(name, 15, random.randint(470,940),random.randint(0,500)

现在在这里运行代码时的结果(不是 Pygame 窗口)...

Please select a team // GSW or CAVS: gsw
Please select an opposing team // GSW or CAVS: cavs
point guard []
shooting guard []
small forward []
power forward []
centre []
point guard ['Jose Calderon']
shooting guard ['J.R Smith']
small forward ['LeBron James']
power forward ['Jae Crowder']
centre ['Kevin Love']

【问题讨论】:

  • 可以使用for position in self.composition:for positon, name in self.composition.items() 而不是for i in range(numPlayers)
  • 顺便说一句:你可以用for player in self.team1players: players.displayCircle()代替for n in range(numPlayers): self.team1players[n].displayCircle() - 它更具可读性。
  • 顺便说一句:阅读PEP 8 -- Style Guide for Python Code
  • 谢谢,我知道它的结构确实很糟糕,但我在 OOP 方面没有太多经验,这是我需要在 10 周内完成的大型项目的原型。喊:'(

标签: python arrays list dictionary pygame


【解决方案1】:

代替

for i in range(numPlayers): 
    self.team2players.append(Player(self.composition['point guard'], ...))

您可以将fordictionary 一起使用

self.team2players = []#

for position, name in self.composition.items():
    #print(position, name)
    self.team2players.append(Player(name, ...))

顺便说一句:

因为self.composition中只有一名玩家
所以它只会在self.team2players 中创建一个玩家。

字典不会保持顺序,所以当您在self.composition中有更多玩家时@
那么for ... in self.composition可能会以不同的顺序创建玩家。


编辑:

当我查看Player(self.composition['point guard'], 时,似乎您只有一个字符串分配给self.composition['point guard'],并且之前的代码应该可以工作,
但是当我查看您的字典时,您似乎有许多名称分配给self.composition['point guard'] 的列表:

    self.composition = {
        'point guard' : [],
        'shooting guard': [],
        'small forward': [],
        'power forward': [],
        'centre': []
    }

这意味着你需要两个 for 循环

self.team2players = []#

for position, names_list in self.composition.items():
    #print(position, names_list)
    for name in names_list:
        #print(name)
        self.team2players.append(Player(name, ...))

编辑:

如果您为每个职位只保留一个名称,则不需要列表,但如果没有名称,您可以使用带名称的字符串或空字符串(或None)。

self.composition = {
    'point guard' : None,
    'shooting guard': None,
    'small forward': None,
    'power forward': None,
    'centre': None
}

而你分配的名字没有append()

self.composition['point guard'] = 'Jose Calderon'

要创建播放器,您需要使用if 来检查None

self.team2players = []

for position, name in self.composition.items():
    if name: # the same as `if (name is not None) and (name != "") and (name != 0) and (name != False) ...: 
        self.team2players.append(Player(name, ...))
    #else:
    #   print("you don't have player on position", position)

【讨论】:

  • 感谢您的帮助,我在 for 循环中使用字典,但出现了一些错误。看来你的方法更好。将来用户将输入球队选择,然后相应的球员将被分配到“控球后卫”或“得分后卫”等。这意味着字典中的列表中希望永远不会超过 1 个字符串。也许我误解了你的意思,你在考虑这个吗?
  • 如果那里永远不会超过 1 个字符串,您不必创建列表,而是使用名称或空字符串(或 None)分配字符串并检查您是否有空字符串(或 None ) 在创建新的 Player 之前
  • 我在回答中放了新的例子。
  • 我使用了你所说的 for self.composition 方法。现在我添加了两个组合(每个团队 1 个)。现在有一个团队 1 的组合和一个团队 2 的组合,它们可以根据用户输入而有所不同。我将编辑问题,以便您查看:)
  • 不要编辑问题 - 之后答案将不适合提问。使用按钮Add Question 更好地创建新问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多