[Tutor PyCZ] Help
Petr Prikryl
PrikrylP na skil.cz
Středa Únor 22 08:46:05 CET 2006
Úvodem, neznám Livewires, takže se na to dívám
jako externista.
geon napsal...
> [...] Taky bych zkusil naznačit jak se zbavit
> toho "proklatého" ;-) global v první funkci:
>
> def vyrobHrace():
> xh=random.randint(0, 630)
> yh=random.randint(0, 479)
> Hrac_telo = circle( xh, yh, 5, filled=1)
> return xh, yh, Hrac_telo
>
>
> xh, yh, Hrac_telo= vyrobHrace()
>
> while 1:
> klavesy = keys_pressed()
> xh, yh = posunHrace(xh, yh)
> if "q" in klavesy:
> break
> [...]
A pak už je to jen krůček k používání tříd.
Kdykoliv se dá něco personifikovat, je to
dobrý kandidát pro instanci nějaké třídy...
class Hrac(object):
"""Třída pro objekt hráče."""
def __init__(self, x, y):
"""Při vytváření hráče se zadává počáteční pozice."""
self.x = x
self.y = y
self.telo = circle(self.x, self.y, 5, filled=1)
def posunRel(dx, dy):
"""Relativní posun v souřadnicích."""
self.moveAbs(self.x + dx, self.y + dy)
def posunAbs(x, y):
"""Posun na absolutní souřadnice."""
self.x = x
self.y = y
# Tady nevím, jak je v původním příkladu
# realizována funkce move_to(), ale mohlo
# by to být použito nějak takto:
move_to(self.telo, self.x, self.y)
Hráč by se pak vyrobil nějak takto:
hrac = Hrac(random.randint(0, 630),
random.randint(0, 479))
A posunoval by se takto:
hrac.posunRel(+1, 0)
Další problém, který vidím v původním zdrojovém textu
spočívá v tom, že se testuje moc kláves najednou a
po testu každé klávesy se počká...
if "8" in klavesy:
yh=yh+1
move_to(Hrac_telo, xh, yh)
sleep(1)
if "9" in klavesy:
xh=xh+1
yh=yh+1
move_to(Hrac_telo, xh, yh)
sleep(1)
[...]
if "3" in klavesy:
yh=yh-1
xh=xh+1
move_to(Hrac_telo, xh, yh)
sleep(1)
Správně by se v ostatních větvích mělo použít elif,
to znamená, že po úspěšném testu by se měly provést
příslušné příkazy a dál už nic (jen ten sleep jedenkrát).
Protože vždycky testujeme jednu z osmi kláves
a výsledkem je zjištění, o kolik se máme posunout
ve směru x a o kolik ve směru y (tj. o +1, 0 nebo -1).
Pokud vím přesně, kterou klávesu chci obsloužit
(tedy ne množinu kláves, ale jen jednu), pak může
být výhodné předem nadefinovat a potom využívat
takovouto tabulku:
delta = { "1": (-1, -1),
"2": ( 0, -1),
"3": (+1, -1),
"4": (-1, 0),
"5": ( 0, 0), # viz dále
"6": ( 0, +1),
"7": (-1, +1),
"8": ( 0, +1),
"9": (+1, +1),
}
A cyklus by pak vypadal nějak takto:
klavesy = keys_pressed() # nebo jiná inicializace
while "q" not in klavesy:
for k in klavesy:
dx, dy = delta[k]
hrac.moveRel(dx, dy)
# Šlo by taky napsat...
# d = delta[k]
# hrac.moveRel(d)
# ... nebo jednoduše
# hrac.moveRel(delta[k])
sleep(1)
klavesy = keys_pressed()
S tím for je to ještě zbytečně zamotané. Dalo by se to
dále vylepšit. Kdyby například existovala funkce, která
by vracela buď číselnou klávesu nebo "q", mohla by v případě
nestisknutí žádné klávesy vracet například "5" (žádný
posun). Výsledný cyklus by pak vypadal takto:
k = "5"
while k != "q":
hrac.moveRel(delta[k])
sleep(1)
k = stiknutaKlavesa()
Pro testování kolizí se dají přímo testovat vnitřní
proměnné objektu hrac.x a hrac.y, které nahrazují
původní xh a yh. Případně se dá nadefinovat metoda
třídy Hrac takto:
def kolize(self, x, y):
return (self.x == x) and (self.y == y)
a pak někde použít...
if hrac.kolize(x, y):
akce("Byl jsi sežrán robotem.")
pepr
P.S. Nezkoušel jsem to. Budou tam asi chyby.
Další informace o konferenci Tutor