[Tutor PyCZ] Livewires V - seznam a proměnné
Tomáš Bělonožník
rebelme na gmail.com
Neděle Březen 5 21:04:25 CET 2006
Ahoj,
opět jsem se zasekl a potřeboval bych pomoct. Ke konci tutoriálu už
totiž potřebných a nových věcí přibývá a nápověd rapidně ubývá. Sice
se mi podařilo program napsat tak, aby jakž takž celý fungoval, ale je
tam spousta malých chybiček, je to rozvleklý a úplně jiný než to mělo
být. Vrátím se k počátku problému. Mám program, kde hráče posunovaného
stisky kláves honí "robot" a když ho dožene, hráč prohrál. Měl bych
přidělat další roboty. Autor tutoriálu dává rady:
* Vytvořte prázdný list robots.
* Opakujte pro každého robota, kterého chceme:
o Přidejte robota do seznamu robotů.
o Vytvořte náhodně souřadnice místa, kde by se měl robot
narodit. Nezapomeňte nastavit atribut srot na 0.
o Opakujte while "pokud se tento robot srazil s jiným":
+ Zkuste jiné místo.
o Vytvořte tělo robota a uložte ho do jeho atributu telo.
Když jsem se to snažil dělat takto, třeba se mi i podařilo vyrobit pět
robotích těl, ale pohybovalo se pouze jedno a ostatní nereagovaly ani
na kontakt. Dejme tomu tedy, že mám tuto funkci pro tvorbu robotů:
def vyrobRobota(pocet_opakovani, seznam):
robot = Robot()
while pocet_opakovani < 5:
# Budoucí souřadnice robota
robot.x=random.randint(8, 631)
robot.y=random.randint(8, 471)
# Část funkce zajišťující, že hráč a robot nezačnou na sobě.
robot_x_round = robot.x / 10
hrac_x_round = hrac.x / 10
robot_y_round = robot.y / 10
hrac_y_round = hrac.y / 10
while robot_x_round == hrac_x_round and robot_y_round == hrac_y_round:
robot.x=random.randint(8, 631)
robot.y=random.randint(8, 471)
hrac.x=random.randint(8, 631)
hrac.y=random.randint(8, 471)
seznam.append(robot)
robot.telo = box(robot.x-5,robot.y-5,robot.x+5,robot.y+5,
filled=1, colour=Colour.dark_blue) # Popis těla robota
Toto mi vytvoří seznam s pěti instancemi robot třídy Robot. Jak ale
udělat, aby se v této funkci všichni hýbali?
def posunRobota(hrac):
for robot in seznam: #tahle řádka je tu navíc, tak jsem to zkoušel
if robot.x < hrac.x:
robot.x = robot.x + 5
elif robot.x > hrac.x:
robot.x = robot.x - 5
if robot.y < hrac.y:
robot.y = robot.y + 5
elif robot.y > hrac.y:
robot.y = robot.y - 5
move_to(robot.telo, robot.x, robot.y)
sleep(0.2)
Přijde mi, jako by si ti roboti v seznamu nedokázali pamatovat svoje
.x a .y nebo spíš za toho robota, kterým se má hýbat, byl pokládán
pořád jeden a ten samý, protože se hýbe mnohem rychleji než hráč. Tomu
by nasvědčovalo i to, že jsem kdesi četl, že jména v Pythonu jsou
prakticky jen odkazy na objekty.
Nakonec jsem to vyřešil metodami třídy Robot:
#Metoda na výrobu robotů
def vyrobRoboty(self):
self.x = random.randint(8, 631)
self.y = random.randint(8, 471)
self.srot = 0
hrac.xround = hrac.x / 10
hrac.yround = hrac.y / 10
self.telo = box(self.x-5, self.y-5, self.x+5, self.y+5,
filled=1, colour=Colour.dark_blue)
# Metoda na posun roboty
def posunRobota(self):
if self.srot == 0:
if self.x < hrac.x:
self.x = self.x + 5
elif self.x > hrac.x:
self.x = self.x - 5
if self.y < hrac.y:
self.y = self.y + 5
elif self.y > hrac.y:
self.y = self.y - 5
sleep(0.02)
move_to(self.telo, self.x, self.y)
robot.vyrobRoboty()
robot2.vyrobRoboty()
robot3.vyrobRoboty()
robot4.vyrobRoboty()
robot5.vyrobRoboty()
robot.posunRobota()
robot2.posunRobota()
robot3.posunRobota()
robot4.posunRobota()
robot5.posunRobota()
Ale jak vidíte, už tohle je příšerně zdlouhavé a ještě při běhu musím
volat další tři metody a funkce, která má zajišťovat, aby při narození
neskončil jeden robot na druhém je dlouhá pomalu jako epos o
Gilgamešovi. Ukázka:
elif self == robot3:
while self.xround == robot.xround and self.xround == robot.yround:
self.x = random.randint(8, 631)
self.y = random.randint(8, 471)
while self.xround == robot2.xround and self.xround == robot2.yround:
self.x = random.randint(8, 631)
self.y = random.randint(8, 471)
V tutoriálech které jsem četl se při psaní o seznamech věnují spíše
textovým řetězcům. Věřím, že kdyby se dal v tomto případě použít
seznam, o něco by se to zkrátilo a navíc by to zjednodušilo přidávání
dalších robotů v dalších levelech atd. atd. Asi bych mohl ten program
sice dodělat tímto stylem, ale s výsledkem bych nemohl být spokojen.
Díky za jakékoliv rady.
Tomáš Bělonožník
--
"Any fool who would die for honor is better off dead." - Cabal Patriarch
"I don't know what the next World War will be fought with, but the
World War after that will be fought with sticks and stones." - Albert
Einstein
Další informace o konferenci Tutor