Ipad рдкрд░ рдПрдХ рд╕рд╛рдВрдк рд▓рд┐рдЦрдирд╛ (pythonista)

... рдпрд╛ рдЖрдИрдкреАрдПрдб рдХреЗ рд╕рд╛рде рд╕рдордп рдХреИрд╕реЗ рдорд╛рд░рдирд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдирд╣реАрдВ ...

рдирдорд╕реНрддреЗ!

рдХреНрдпрд╛ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реЛ


рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЯреИрдмрд▓реЗрдЯ рдЕрднреА рддрдХ рдХрдВрдкреНрдпреВрдЯрд░реЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдПрдХ рд╕рд╡рд╛рд░реА / рдЙрдбрд╝рд╛рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдЖрдЗрдкреИрдб рдХреЗ рддрд╣рдд рдЖрдИрдбреА рдХреНрдпрд╛ рд╣реИрдВ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдЬ рдореИрдВ рдкрд╛рдпрдереЛрдирд┐рд╕реНрдЯрд╛ рдкрд░ рдЦреЗрд▓ рдХрд░реВрдВрдЧрд╛ред

рд╣рдо рдХреНрдпрд╛ рдХрд░реЗрдВрдЧреЗ?


рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд░рдо, рдЬреИрд╕реЗ рдХрд┐ рдХреНрд░рд┐рд╕реНрдЯрд▓ (рд╣рд╛рдБ, рд╣рд╛рдБ, рдмрд╣реБрдд рдЬреЛ рдЖрдк рдореЗрдЯреНрд░реЛ рдореЗрдВ рдЦреЗрд▓рддреЗ рд╣реИрдВ)ред рдЯреЗрдЯреНрд░рд┐рд╕, рд╕рд╛рдВрдк, рднрд░ - рдХрд┐рд╕реА рднреА рдирд╡рд╛рдЧрдВрддреБрдХ рдХреЛ, рдереЛрдбрд╝реА рд╕рдордЭ рд╣реЛрдиреЗ рдкрд░, рдЙрдиреНрд╣реЗрдВ 30 рдорд┐рдирдЯ рдореЗрдВ рд▓рд┐рдЦ рджреЗрдВрдЧреЗред Cutscene рдХреЗ рддрд╣рдд - рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ, рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓, рдХреЛрдбред

рдпрд╣рд╛рдБ рдХреБрдЫ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд╣реИрдВ рдЬреЛ рдореИрдВрдиреЗ рдЧрдбрд╝рдмрдбрд╝ рдХрд┐рдП рд╣реИрдВ:

рдХрдИ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ











рддреНрдпрд╛рдЧ
рдпрд╣ рд▓реЗрдЦ рдХреЗрд╡рд▓ рд╢реБрд░реБрдЖрддреА (рд▓реЗрдХрд┐рди рдЕрдЬрдЧрд░ рдХреЛ рдЬрд╛рдирдиреЗ рд╡рд╛рд▓рд╛) рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рджрд╕ рдорд┐рдирдЯ рдпрд╛ рдХрд┐рд╕реА рднреА рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЯреИрдВрдХ рдХреА рджреБрдирд┐рдпрд╛ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛, рд▓реЗрдХрд┐рди рд▓реЗрдЦрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдзрд░реНрдо рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рд╕реБрдВрджрд░ рдФрд░ рд╕рд╣реА рдХреЛрдб рд╡рд╛рд░рдВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡рд╣ рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ) ред рдФрд░ рдпрд╣ рднреА рдХреБрдЫ pythonista рдЙрджрд╛рд╣рд░рдг рдФрд░ рдкреНрд░рд▓реЗрдЦрди рд╕реЗ рдЪреЛрд░реА рд╣реЛ рдЧрдпрд╛ рд╣реИред

рд╕рднреА рдХреЛрдб рдЕрдВрдд рдореЗрдВ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗред

рдкрд╛рдЗрдереЛрдирд┐рд╕реНрдЯрд╛ рдореЗрдВ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЛ рдЬрд╛рдиреЗрдВ


рдЖрдпрд╛рдд
from scene import * import random 


рддреБрд░рдВрдд рдПрдХ рджреГрд╢реНрдп рдмрдирд╛рдПрдВ:

 class Game(Scene): def setup(self): self.background_color = "green" run(Game(), LANDSCAPE) 

рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдЕрднреА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣рд░реА рд╕реНрдХреНрд░реАрди рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЪрд▓рд┐рдП рдЧреЗрдо рдХреНрд▓рд╛рд╕ рдореЗрдВ рдЕрдкрдбреЗрдЯ рд╡рд┐рдзрд┐ (рдЬрд┐рд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдЦреБрдж рдХрд╣рддрд╛ рд╣реИ) рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдХрд▓рд░ рдХреЛ рдмрджрд▓рдХрд░ рдХреБрдЫ рдХреВрд▓ рдЪреАрдЬреЗрдВ рдХрд░рддреЗ рд╣реИрдВред

 class Game(Scene): #    def update(self): self.background_color = (1.0, 1.0, (math.sin(self.t) + 1) / 2) 

рдЕрдм рд╣рдорд╛рд░реА рд╕реНрдХреНрд░реАрди рдЖрд╕рд╛рдиреА рд╕реЗ рдкреАрд▓реЗ рд╕реЗ рд╕рдлреЗрдж рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдмрджрд▓ рд░рд╣реА рд╣реИред



рдЕрдм рдХреБрдЫ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВред рд╣рдо рдЗрд╕реЗ рд╕реЗрдЯрдЕрдк рд╡рд┐рдзрд┐ рдореЗрдВ рднреА рдмрдирд╛рддреЗ рд╣реИрдВ:

 class Game(Scene): def setup(self): self.background_color = "white" mypath = ui.Path.rect(0, 0, 50, 50) self.obj = ShapeNode(mypath) self.obj.color = "purple" #      html,  #FF00FF.   tuple,   (1.0, 0.0, 1.0).       alpha,    self.add_child(self.obj) def update(self): self.obj.position = (500 + 200 * math.sin(self.t), 500 + 200 * math.cos(self.t)) 

рд╣рдордиреЗ рд▓рд╛рдЗрди (рдорд╛рдИрдкрд╛рде) рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА, рдЙрд╕ рдкрд░ рдПрдХ рд╢реЗрдкрдПрдиреЛрдб рдмрдирд╛рдпрд╛, рдЗрд╕реЗ рдПрдХ рд░рдВрдЧ рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд┐рдпрд╛, рдФрд░ рдлрд┐рд░ рдПрдХ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ (рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рдмрд╛рдд - рдмрдирд╛рддреЗ рд╕рдордп рдПрдХ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ, рдЕрд░реНрдерд╛рдд рд╢реЗрдкрдХреЛрдб (* ..., рдкреИрд░реЗрдВрдЯ = рд╕реНрд╡) рдпрд╛ self.add_child (obj))ред

рдЦреИрд░, Game.update () рдореЗрдВ рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ (рдЯрдкрд▓) рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдкрд┐рдХреНрд╕рд▓ рдореЗрдВ рд╣реИ рдФрд░ рдирд┐рдЪрд▓реЗ рдмрд╛рдПрдВ рдХреЛрдиреЗ рд╕реЗ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдореЗрдВ рджреГрд╢реНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ)ред рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдФрд░ рдиреЛрдбреНрд╕ рдЬрд┐рдирдХреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рджреГрд╢реНрдп рд╣реИрдВ (рдпрд╛ рдЗрд╕рдХреЗ рдХреБрдЫ рдмрдЪреНрдЪреЗ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕) рдЦреБрдж рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
рдЗрд╕ рдЦрдВрдб рдореЗрдВ рд╣рдо рдЬрд┐рд╕ рдЕрдВрддрд┐рдо рдЪреАрдЬ рд╕реЗ рдЧреБрдЬрд░реЗрдВрдЧреЗ, рд╡рд╣ рд╣реИ рдЯрдЪ_рдмреЗрдЧрди (рд╕рд╛рде рд╣реА рдЯрдЪ_рдореЗрдб рдФрд░ рдЯрдЪ_рдбреЗрдВрдб)ред рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдпрд╣ рд╡рд┐рдзрд┐ рд╕реНрдХреНрд░реАрди рдкрд░ рдХреНрд▓рд┐рдХ рдкрдХрдбрд╝рддреА рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рдЖрдЬрдорд╛рдПрдБ:

 class Game(Scene): def touch_began(self, touch): mypath = ui.Path.oval(0, 0, 50, 50) obj = ShapeNode(mypath) obj.color = (0.5, 0.5, 1.0) self.add_child(obj) obj.position = touch.location 



рд╣рд░ рдмрд╛рд░ рдЬрдм рдЖрдк рд╕реНрдХреНрд░реАрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рд╕рд░реНрдХрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рдХреНрд▓рд┐рдХ рдХрд╛ рд╕реНрдерд╛рди рдЯрдЪ.рд▓реЛрдХреЗрд╢рди рд╣реИред

рд╕рд╛рдВрдк рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░


рдЦреЗрд▓ рддрдВрддреНрд░
рдПрдХ рд╕рд╛рдБрдк рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдПрдХ рд╕рд░рдгреА рд╣реИ, рдЬрдм рд╕рд┐рд░ рдЪрд▓рддрд╛ рд╣реИ - рджреВрд╕рд░рд╛ рдЯреБрдХрдбрд╝рд╛ рдкрд╣рд▓реЗ, рддреАрд╕рд░реЗ рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдЪрд▓рддрд╛ рд╣реИ - рджреВрд╕рд░реЗ рдХреЗ рд╕реНрдерд╛рди рдкрд░, рдЖрджрд┐ред рдкреВрдВрдЫ рдХреЗ рд╕рд╛рде рд╕рд┐рд░ рдХреЗ рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреВрдВрдЫ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЯреБрдХрдбрд╝реЗ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗред

рд╣рдо рд╕рднреА рд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЗрд╕реЗ рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рд▓реЗрдХрд┐рди, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдо рд╕рд╛рдЗрдХрд┐рд▓ рдХрд░реЗрдВрдЧреЗ)ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, PhyObj рдХреНрд▓рд╛рд╕ рдмрдирд╛рдПрдБ:

 class PhyObj: def __init__(self, path, color, parent): self.graph_obj = ShapeNode(path, parent=parent) self.parent = parent self.graph_obj.color = color def setpos(self, x, y): self.graph_obj.position = (x, y) def getpos(self): return self.graph_obj.position def move(self, x, y): self.graph_obj.position += (x, y) 

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рддреБрдЪреНрдЫ рд╣реИред рдХрдХреНрд╖рд╛ рдХреЗ рдЕрдВрджрд░ рд╣реА, рд╣рдордиреЗ рдПрдХ рдиреЛрдб рдмрдирд╛рдпрд╛, рдФрд░ рдХреБрдЫ рддрд░реАрдХреЛрдВ рдХрд╛ рднреА рд╡рд░реНрдгрди рдХрд┐рдпрд╛, рдЬреЛ рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рдкрдардиреАрдп рдмрдирд╛рдПрдВрдЧреЗред

holivary
рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдореИрдВ рдкрд╣рд▓реЗ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ рдЬрд┐рдирдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рддрд░реАрдХреЗ рдФрд░ рдЧреБрдг рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рд▓реЛрдЧреЛрдВ рдореЗрдВ рдХреЛрдб рдмрд╣реБрдд рд╕реБрдВрджрд░ рдФрд░ рдкрдардиреАрдп рдмрди рдЬрд╛рддрд╛ рд╣реИред

PhyObj рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдореЗрдВ рд╕рдмрд╕реЗ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдХреА рд╡рд╕реНрддреБ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдПрдХ рдЕрдореВрд░реНрдд рднреМрддрд┐рдХ рд╡рд╕реНрддреБ рд╣реИред

рд╕рд╛рдБрдк рдХрд╛ рд╡рд░реНрдгрди


рдЕрдм рд╣рдореЗрдВ рд╕рд╛рдБрдк рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдЯреБрдХрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВ, рд╣рдо рдкрд╣рд▓реЗ рдПрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ:

 class Tile(PhyObj): def __init__(self, parent, size, margin=4): super().__init__(ui.Path.rect(0, 0, size[0] - margin, size[1] - margin), "#66FF66", parent) def die(self): self.graph_obj.color = "red" 

рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ, рд╣рдо рдХрдХреНрд╖рд╛ рдХреА рдореВрд▓ рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ рдЦреБрдж рдХреЛ рдЖрдХрд╛рд░ рдФрд░ рд░рдВрдЧ рджреЗрддреЗ рд╣реИрдВред рдорд╛рд░реНрдЬрд┐рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рддрд╛рдХрд┐ рд╡рд░реНрдЧ рдПрдХ рд╕рд╛рде рдЪрд┐рдкрдХ рди рдЬрд╛рдПрдВ рдФрд░ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЬрд╛рд▓ рдмрдирд╛рдПрдВред

 class Game(Scene): def setup(self): self.tile = Tile(self, (40, 40)) self.tile.setpos(100, 100) 

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ:



рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдорд╛рд░реНрдЬрд┐рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ:

 class Game(Scene): def setup(self): tile1 = Tile(self, (40, 40)) tile1.setpos(100, 100) tile2 = Tile(self, (40, 40)) tile2.setpos(140, 100) 



рдЦреИрд░, рдЕрдм рдЗрди рдЯреБрдХрдбрд╝реЛрдВ рд╕реЗ рдЖрдкрдХреЛ рд╕рд╛рдВрдк рдХреЛ рдЧреЛрдВрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдПрдХ рдЖрд░рдВрднреАрдХрд░рдг рд╡рд┐рдзрд┐ рдФрд░ рдПрдХ рдЪрд╛рд▓ рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдмрдирд╛рдПрдБ:

 class Snake: def __init__(self, length, width, initpos, parent): self.width = width #     self.tiles = [Tile(parent, (width, width)) for i in range(length)] #        for i, tile in enumerate(self.tiles): tile.setpos(initpos[0] + i * self.width, initpos[1]) #        

рдЖрдЗрдП рдЗрд╕реЗ рддреБрд░рдВрдд рдЦреАрдВрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ:

 class Game(Scene): def setup(self): self.snake = Snake(10, 40, (200, 200), self) 



рдЦреИрд░, рдЪрд╛рд▓ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВред

 class Snake: def move(self, x, y): for i in range(len(self.tiles) - 1, 0, -1): self.tiles[i].setpos(*self.tiles[i - 1].getpos()) self.tiles[0].move(x * self.width, y * self.width) 

рдкрд╣рд▓реЗ рд╣рдо рдЕрдВрддрд┐рдо рдХреЛ рддрдкрд╕реНрдпрд╛ рдХреА рдУрд░ рдмрдврд╝рд╛рддреЗ рд╣реИрдВ, рдлрд┐рд░ рддрдкрд╕реНрдпрд╛ рдХреЛ рддрдкрд╕реНрдпрд╛ рдХреЛ ... рдлрд┐рд░ рджреВрд╕рд░реЗ рдХреЛ рдкреНрд░рдердо рдХреЛред рдФрд░ рдкрд╣рд▓реЗ (x, y) рдкрд░ред

рджрд░рдЕрд╕рд▓, рд╣рдорд╛рд░рд╛ рд╕рд╛рдВрдк рд╕реАрдзрд╛ рдЪрд▓рддрд╛ рд╣реИред рдЖрдЗрдП рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:

 class Game(self): # <...> def update(self): self.snake.move(0, 1) 

рдпрджрд┐ рдЖрдк рджреЗрдЦрдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ, рддреЛ рд╡рд╣ рджреВрд░ рд░реЗрдВрдЧрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЕрдкрдбреЗрдЯ рдХреЛ рдЕрдХреНрд╕рд░ (рдФрд░ рд╡реИрд╕реЗ, рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде) рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЕрдВрддрд┐рдо рдХреЙрд▓ рдХреЗ рдмрд╛рдж рдХрд┐рддрдирд╛ рд╕рдордп рдмреАрдд рдЪреБрдХрд╛ рд╣реИ рдФрд░ рдЬрдм рддрдХ рдпрд╣ "рдкрд░реНрдпрд╛рдкреНрдд" рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рддрдм рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╣рдо рдХрд░рддреЗ рд╣реИрдВ:

 class Game(Scene): def time_reset(self): self.last_time = self.t def time_gone(self, t): if self.t - self.last_time > t: res = True self.time_reset() else: res = False return res def setup(self): self.snake = Snake(10, 40, (200, 200), self) self.time_reset() def update(self): if self.time_gone(0.3): self.snake.move(0, 1) 

рдпрджрд┐ рд╕рдордп рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рдмреАрдд рдЪреБрдХрд╛ рд╣реИ, рддреЛ time_gone рд╕рд╣реА рд╣реИред рдЕрдм рд╕рд╛рдВрдк рд╣рд░ 0.3 рд╕реЗрдХрдВрдб рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝реЗрдЧрд╛ред рдпрд╣ рдХрд╛рдо рдХрд┐рдпрд╛?



рдкреНрд░рдмрдВрдз


рдЕрдм рдЖрдкрдХреЛ рдирд┐рдпрдВрддреНрд░рдг рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдЪрд╛рд░реЛрдВ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рдПрдХ рдореЛрдбрд╝:



 class Game(Scene): # <...> def setup(self): # <...> self.dir = (0, 1) #     def update(self): if self.time_gone(0.3): self.snake.move(*self.dir) 

рдФрд░ рдЕрдм рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдХрд┐рд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рд╣реИ, рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЯрдЪ_рдмреЗрдЧрди рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдЙрддрдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рдерд╛ рдЬрд┐рддрдирд╛ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ рдЖрдк рдмрд╕ рдХреЙрдкреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 class Game(Scene): # <...> def touch_began(self, touch): ws = touch.location[0] / self.size.w hs = touch.location[1] / self.size.h aws = 1 - ws if ws > hs and aws > hs: self.dir = (0, -1) elif ws > hs and aws <= hs: self.dir = (1, 0) elif ws <= hs and aws > hs: self.dir = (-1, 0) else: self.dir = (0, 1) 

рдЦреИрд░, рдЕрдм рдореБрдбрд╝рдХрд░ рджреЗрдЦреЗрдВ



рдореБрдЦреНрдп рддрдВрддреНрд░ рдкрд░ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдЯрдХрд░рд╛рд╡ рдФрд░ рд╕реЗрдм рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред

рдкреВрдВрдЫ рдХреА рдЯрдХреНрдХрд░


рдЖрдЗрдП рдЬрд╛рдБрдЪ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░реЗрдВ рдФрд░ рд╕рд╛рдБрдк рдореЗрдВ find_collisions рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ

 class Snake: # <...> def find_collisions(self): for i in range(1, len(self.tiles)): if self.tiles[i].getpos() == self.tiles[0].getpos(): return self.tiles[i], self.tiles[0] return False 

рдЕрдм рд╣рдо рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрдж рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд▓рд╛рд▓ рд░рдВрдЧ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдорд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдХреЛ рдЯрд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:

 class Tile(PhyObj): # <...> def die(self): self.graph_obj.color = "red" 

рдЕрдкрдбреЗрдЯ рдФрд░ рд╕реЗрдЯрдЕрдк рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХ рдЬреЛрдбрд╝реЗрдВ:

 class Game(Scene): # <...> def setup(self): self.snake = Snake(30, 40, (200, 200), self) #   self.time_reset() self.dir = (0, 1) self.game_on = True #   ? def update(self): if not self.game_on: #  ,  return col = self.snake.find_collisions() #  ? if col: for tile in col: tile.die() #     self.game_on = False #   if self.time_gone(0.3): self.snake.move(*self.dir) 

рдореЗрд░реЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реБрдЖ:



рдпрд╣ рд╕реЗрдм рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред

рдмрдврд╝рд╛рд╡ рдФрд░ рд╕реЗрдм


рд╣рдо рд╕рд╛рдВрдк рдХреЛ рд▓рдВрдмрд╛ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЗрд╕реЗ рд╕реБрдВрджрд░ рджрд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд┐рдЫрд▓реЗ рджреЛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рдирдпрд╛ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛:



рд╕рд╛рдБрдк рдХреЗ рд▓рд┐рдП рддрд░реАрдХреЗ рдЬреЛрдбрд╝реЗрдВ:

 class Snake: # <...> def find_dir(self, x1, y1, x2, y2): if x1 == x2 and y1 > y2: return (0, 1) elif x1 == x2 and y1 < y2: return (0, -1) elif y1 == y2 and x1 > x2: return (1, 0) elif y1 == y2 and x1 < x2: return (-1, 0) else: assert False, "Error!" def append(self): if len(self.tiles) > 1: lastdir = self.find_dir(*self.tiles[-1].getpos(), *self.tiles[-2].getpos()) else: lastdir = (-self.parent.dir[0], -self.parent.dir[1]) self.tiles.append(Tile(self.parent, (self.width, self.width))) x_prev, y_prev = self.tiles[-2].getpos() self.tiles[-1].setpos(x_prev + lastdir[0] * self.width, y_prev + lastdir[1] * self.width) 

find_dir рд╡рд╣ рджрд┐рд╢рд╛ рдкрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░реА рдирд╛рдпрд┐рдХрд╛ рдХреА рдкреВрдВрдЫ рдХреА рдиреЛрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реЛрддреА рд╣реИред рдпрд╣ рдХрд╣рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдПрдХ рд╕реЗрд▓ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЦреЗрд▓ рдореЗрдВ рдПрдХ рдФрд░ рд╕рд╛рдБрдк_рд▓рдЧрдбрд╝реА рдкрджреНрдзрддрд┐ рдЬреЛрдбрд╝реЗрдВ:

 class Game(Scene): # <...> def snake_lengthen(self): self.snake.append() self.time_reset() 

рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╕рд╛рдВрдк рдереЛрдбрд╝рд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рдпрд╣ рджреЗрдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реЛ рдХрд┐ рдЯреБрдХрдбрд╝рд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред

рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╕рд╛рдВрдк рдХреЗ рд╕рд╛рде рдХреБрдЫ рдЕрдВрддрд░ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВред

 class Snake: # <...> def getpos(self): return self.tiles[0].getpos() def intersect(self, x, y): return self.getpos() == (x, y) 

рд╣реБрд░реНрд░реЗ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╕реЗрдм рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред рджрд░рдЕрд╕рд▓, рд╣рдо рдПрдХ рдмрд╛рд░ рдореЗрдВ рд╕реЗрдм рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:

 class Apple(PhyObj): def __init__(self, width, size, parent): super().__init__(ui.Path.oval(0, 0, size[0], size[1]), "#55AAFF", parent) self.parent = parent self.width = width self.dislocate() def dislocate(self): a = random.randint(2, int(self.parent.size.w / self.width) - 2) b = random.randint(2, int(self.parent.size.h / self.width) - 2) self.setpos(a * self.width, b * self.width) 

рдЧреНрд░рд┐рдб рдкрд░ рд╣рдорд╛рд░реЗ рдмреИрд▓ рдХреА рдЖрдВрдЦ рдХреЛ рдлрд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рдЕрдЬреАрдм рдпрд╛рджреГрдЪреНрдЫрд┐рдХрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдлрд┐рд░ рдереВрдерди рдФрд░ рд╕реЗрдм рдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рджреЗрдЦрдиреЗ рдФрд░ рдЗрд╕рдХреА рдкрд╛рдпрд░-рдкреАрд░ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдмрд╕ рдЗрдлрд╛рд╕ рдкрд░ред рдЖрдЗрдП рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрдд рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд▓рд╛рдЗрдиреЗрдВ рдЬреЛрдбрд╝реЗрдВ:

 class Game(Scene): # <...> def setup(self): self.apple = Apple(40, (50, 50), self) # 40 -  ,       Snake() # <...> def update(self): # <...> if self.snake.intersect(*self.apple.getpos()): self.snake_lengthen() self.apple.dislocate() 

рдЦреИрд░, рд╕рдм рдХреБрдЫ рд▓рдЧрддрд╛ рд╣реИ, рдЕрдм рд╕рд╛рдВрдк рд▓рдВрдмрд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЕрдЧрд░ рд╡рд╣ рдПрдХ рд╕реЗрдм рдХреЛ рдорд╛рд░рддрд╛ рд╣реИ рдФрд░ рдЕрдЧрд░ рд╡рд╣ рдЦреБрдж рдХреЛ рдорд╛рд░рддрд╛ рд╣реИ рддреЛ рд╡рд╣ рдорд░ рдЬрд╛рддрд╛ рд╣реИред



рдмреЛрдирд╕


рдЖрдк рдзреНрд╡рдирд┐ рдкреНрд░рднрд╛рд╡ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 import sound class Game(Scene): # <...> def snake_lengthen(self): self.snake.append() self.time_reset() sound.play_effect('arcade:Powerup_1', 0.25, 0.8) 

рдирд┐рд░реНрд╡рд┐рдШреНрди рдЧрддрд┐ рдХрд░реЗрдВ:

 class Game(Scene): # <...> def setup(self): self.game_on = False self.GLOBAL_TIMING = 0.2 self.GLOBAL_WIDTH = 40 self.apple = Apple(self.GLOBAL_WIDTH, (50, 50), self) self.snake = Snake(10, self.GLOBAL_WIDTH, (200, 200), self) self.time_reset() self.dir = (0, 1) self.game_on = True class Snake: # <...> def move(self, x, y): for i in range(len(self.tiles) - 1, 0, -1): self.tiles[i].setpos(*self.tiles[i - 1].getpos(), self.parent.GLOBAL_TIMING) self.tiles[0].move(x * self.width, y * self.width, self.parent.GLOBAL_TIMING) class PhyObj: def __init__(self, path, color, parent): self.graph_obj = ShapeNode(path, parent=parent) self.parent = parent self.graph_obj.color = color self.pos = self.graph_obj.position def setpos(self, x, y, t=0.0): self.pos = (x, y) self.graph_obj.run_action(Action.move_to(x, y, t)) #    x, y    t def getpos(self): return self.pos def move(self, x, y, t=0.0): self.pos = (self.pos[0] + x, self.pos[1] + y) self.graph_obj.run_action(Action.move_by(x, y, t)) 

рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рд╣рдордиреЗ рд╕реНрдерд┐рддрд┐ PhyObj рдХреЗ рддрд░реНрдХ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред рдкрд╣рд▓реЗ, рд╣рдордиреЗ рдЧреНрд░рд╛рдлрд┐рдХ рддрддреНрд╡ рдХреА рд╕реНрдерд┐рддрд┐ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд┐рдпрд╛ рдерд╛, рдФрд░ рдЕрдм рддрд╛рд░реНрдХрд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХреНрд╖реЗрддреНрд░ рд╣реИ (рдЬреЛ рдХрд┐ рдЧреЗрдо рд▓реЙрдЬрд┐рдХ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдФрд░ рдЧреНрд░рд╛рдлрд┐рдХ рддрддреНрд╡ рдХреА рд╕реНрдерд┐рддрд┐ рдЕрдм рд╕реНрд╡рддрдВрддреНрд░ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЕрдкрдиреЗ рддрд░реАрдХреЗ рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрд░реНрдерд╛рддреН, рдПрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдЙрд╕реЗ рдПрдХ рд╕рдорд╛рдирд╛рдВрддрд░ рдзрд╛рд░рд╛ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдБ рд╡рд╣ рдЪрд▓рддреА рд╣реИред

рдРрд╕рд╛ рдЪрд┐рдХрдирд╛ рд╕рд╛рдВрдк рдирд┐рдХрд▓рд╛:



рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╕рд╛рдВрдк рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рд▓реЗрдмрд▓:

 class Game(Scene): # <...> def setup(self): self.game_on = False self.GLOBAL_TIMING = 0.2 self.GLOBAL_WIDTH = 40 self.apple = Apple(self.GLOBAL_WIDTH, (50, 50), self) self.snake = Snake(30, self.GLOBAL_WIDTH, (200, 200), self) self.time_reset() self.dir = (0, 1) self.label = LabelNode("", font=("Chalkduster", 20), parent=self, position=(self.size.w / 2, self.size.h - 100)) #    self.update_labels() self.game_on = True def update_labels(self): self.label.text = "Length: " + str(len(self.snake.tiles)) def update(self): if not self.game_on: return col = self.snake.find_collisions() if col: for tile in col: tile.die() self.game_on = False if self.time_gone(self.GLOBAL_TIMING): self.snake.move(*self.dir) if self.snake.intersect(*self.apple.getpos()): self.snake_lengthen() self.apple.dislocate() self.update_labels() #  



рджреЛрд╕реНрддреЛрдВ, рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! рдпрджрд┐ рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдкреВрдЫреЗрдВред рдФрд░ рдЕрдЧрд░ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ - рдореИрдВ рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛, рдЕрднреА рднреА рдХреБрдЫ рдмрддрд╛рдирд╛ рдмрд╛рдХреА рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рд▓реЗрдЦ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рдВрдмрд╛ рд╣реИ)ред

рд╕рднреА рд╕рд╛рдВрдк рдХреЛрдб
 from scene import * import random import math import sound class PhyObj: def __init__(self, path, color, parent): self.graph_obj = ShapeNode(path, parent=parent) self.parent = parent self.graph_obj.color = color self.pos = self.graph_obj.position def setpos(self, x, y, t=0.0): self.pos = (x, y) self.graph_obj.run_action(Action.move_to(x, y, t)) def getpos(self): return self.pos def move(self, x, y, t=0.0): self.pos = (self.pos[0] + x, self.pos[1] + y) self.graph_obj.run_action(Action.move_by(x, y, t)) class Tile(PhyObj): def __init__(self, parent, size, margin=4): super().__init__(ui.Path.rect(0, 0, size[0] - margin, size[1] - margin), "#66FF66", parent) def die(self): self.graph_obj.color = "red" class Snake: def __init__(self, length, width, initpos, parent): self.width = width self.tiles = [Tile(parent, (width, width)) for i in range(length)] for i, tile in enumerate(self.tiles): tile.setpos(initpos[0] + i * self.width, initpos[1]) self.parent = parent def move(self, x, y): for i in range(len(self.tiles) - 1, 0, -1): self.tiles[i].setpos(*self.tiles[i - 1].getpos(), self.parent.GLOBAL_TIMING) self.tiles[0].move(x * self.width, y * self.width, self.parent.GLOBAL_TIMING) def find_collisions(self): for i in range(1, len(self.tiles)): if self.tiles[i].getpos() == self.tiles[0].getpos(): return self.tiles[i], self.tiles[0] return False def find_dir(self, x1, y1, x2, y2): if x1 == x2 and y1 > y2: return (0, 1) elif x1 == x2 and y1 < y2: return (0, -1) elif y1 == y2 and x1 > x2: return (1, 0) elif y1 == y2 and x1 < x2: return (-1, 0) else: assert False, "Error!" def append(self): if len(self.tiles) > 1: lastdir = self.find_dir(*self.tiles[-1].getpos(), *self.tiles[-2].getpos()) else: lastdir = (-self.parent.dir[0], -self.parent.dir[1]) self.tiles.append(Tile(self.parent, (self.width, self.width))) x_prev, y_prev = self.tiles[-2].getpos() self.tiles[-1].setpos(x_prev + lastdir[0] * self.width, y_prev + lastdir[1] * self.width) def getpos(self): return self.tiles[0].getpos() def intersect(self, x, y): return self.getpos() == (x, y) class Apple(PhyObj): def __init__(self, width, size, parent): super().__init__(ui.Path.oval(0, 0, size[0], size[1]), "#55AAFF", parent) self.parent = parent self.width = width self.dislocate() def dislocate(self): a = random.randint(2, int(self.parent.size.w / self.width) - 2) b = random.randint(2, int(self.parent.size.h / self.width) - 2) self.setpos(a * self.width, b * self.width) class Game(Scene): def snake_lengthen(self): self.snake.append() self.time_reset() sound.play_effect('arcade:Powerup_1', 0.25, 0.8) def time_reset(self): self.last_time = self.t def time_gone(self, t): if self.t - self.last_time > t: res = True self.time_reset() else: res = False return res def setup(self): self.game_on = False self.GLOBAL_TIMING = 0.2 self.GLOBAL_WIDTH = 40 self.apple = Apple(self.GLOBAL_WIDTH, (50, 50), self) self.snake = Snake(30, self.GLOBAL_WIDTH, (200, 200), self) self.time_reset() self.dir = (0, 1) self.label = LabelNode("", font=("Chalkduster", 20), parent=self, position=(self.size.w / 2, self.size.h - 100)) self.update_labels() self.game_on = True def update_labels(self): self.label.text = "Length: " + str(len(self.snake.tiles)) def update(self): if not self.game_on: return col = self.snake.find_collisions() if col: for tile in col: tile.die() self.game_on = False if self.time_gone(self.GLOBAL_TIMING): self.snake.move(*self.dir) if self.snake.intersect(*self.apple.getpos()): self.snake_lengthen() self.apple.dislocate() self.update_labels() def touch_began(self, touch): ws = touch.location[0] / self.size.w hs = touch.location[1] / self.size.h aws = 1 - ws if ws > hs and aws > hs: self.dir = (0, -1) elif ws > hs and aws <= hs: self.dir = (1, 0) elif ws <= hs and aws > hs: self.dir = (-1, 0) else: self.dir = (0, 1) run(Game(), LANDSCAPE) 


рдХреНрд░рд┐рд╕реНрдЯрд▓ рдХреЛрдб WhiteBlackGoose рд╕рдВрд╕реНрдХрд░рдг
рдпрд╣ рдордЬрд╝реЗрджрд╛рд░ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рдЕрдЬрдЧрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рдХреБрдЫ рдмрд╣реБрдд рд╣реА рд╕рдорд╛рди рдкрд╛рдпрд╛ред рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ :)

 from scene import * from math import pi from random import uniform as rnd, choice, randint import sys import random A = Action sys.setrecursionlimit(1000000) colors = ['pzl:Green5', "pzl:Red5", "pzl:Blue5"] + ["pzl:Purple5", "pzl:Button2"] + ["plf:Item_CoinGold"] global inited inited = False class Explosion (Node): def __init__(self, brick, *args, **kwargs): Node.__init__(self, *args, **kwargs) self.position = brick.position for dx, dy in ((-1, -1), (1, -1), (-1, 1), (1, 1)): p = SpriteNode(brick.texture, scale=0.5, parent=self) p.position = brick.size.w/4 * dx, brick.size.h/4 * dy p.size = brick.size d = 0.6 r = 30 p.run_action(A.move_to(rnd(-r, r), rnd(-r, r), d)) p.run_action(A.scale_to(0, d)) p.run_action(A.rotate_to(rnd(-pi/2, pi/2), d)) self.run_action(A.sequence(A.wait(d), A.remove())) class Brick (SpriteNode): def __init__(self, brick_type, *args, **kwargs): img = colors[brick_type] SpriteNode.__init__(self, img, *args, **kwargs) self.brick_type = brick_type self.is_on = True self.lf = True self.enabled = True def destroy(self): self.remove_from_parent() self.is_on = False def mark(self): self.lf = False def demark(self): self.lf = True class Game(Scene): def brickgetpos(self, i, j): return (self.Woff + j * self.W, self.Hoff + i * self.H) def brick(self, ty, i, j): b = Brick(ty, size=(self.W, self.H), position=self.brickgetpos(i, j), parent=self.game_node) b.rotation = random.random() return b def random_brick_type(self): if random.random() < 0.992: return random.randint(0, 3) else: if random.random() < 0.8: return 5 else: return 4 def setup(self): FONT = ('Chalkduster', 20) self.score_label = LabelNode('Score: 0', font=FONT, position=(self.size.w/2-100, self.size.h-40), parent=self) self.score = 0 self.last_score_label = LabelNode('Delta: +0', font=FONT, position=(self.size.w/2-300, self.size.h-40), parent=self) self.last_score = 0 #self.avg_label = LabelNode('Speed: +0/s', font=FONT, position=(self.size.w/2+100, self.size.h-40), parent=self) #self.max_label = LabelNode('Peak: +0/s', font=FONT, position=(self.size.w/2+300, self.size.h-40), parent=self) #self.max_speed = 0 self.game_time = 120 self.timel = LabelNode('Time: ' + str(self.game_time) + "s", font=FONT, position=(self.size.w/2+300, self.size.h-40), parent=self) self.gems = [0 for i in colors] self.effect_node = EffectNode(parent=self) self.game_node = Node(parent=self.effect_node) self.l = [0 for i in colors] self.lt = [0 for i in colors] for i in range(len(colors)): R = 50 if i == 6 else 35 self.l[i] = Brick(i, size=(R, R), position=(40, self.size.h-100-i*40), parent=self.game_node) self.lt[i] = LabelNode(": 0", font=FONT, position=(self.l[i].position[0] + 40, self.l[i].position[1]), parent=self) self.WB = 30 self.HB = 30 self.W = 900 // self.WB self.H = 900 // self.HB self.colcount = 4 self.Woff = (int(self.size.w) - self.W * self.WB + self.W) // 2 self.Hoff = self.H + 10 self.net = [[self.brick(self.random_brick_type(), i, j) for i in range(self.HB)] for j in range(self.WB)] #self.touch_moved = self.touch_began self.start_time = self.t self.game_on = True global inited inited = True def demark(self): for bricks in self.net: for brick in bricks: brick.demark() def howfar(self, x, y): alt = 0 for i in range(y): if not self.net[x][i].is_on: alt += 1 return alt def update(self): global inited if not inited: return self.game_on = self.t - self.start_time < self.game_time if self.game_on: self.timel.text = "Time: " + str(round(self.game_time - (self.t - self.start_time))) + "s" else: self.timel.text = "Game over" #if speed > self.max_speed: # self.max_speed = speed # self.max_label.text = "Peak: +" + str(round(self.max_speed)) + "/s" def gravity(self, x, y): alt = self.howfar(x, y) if alt == 0: return self.net[x][y].destroy() self.net[x][y - alt] = self.brick(self.net[x][y].brick_type, y, x) self.net[x][y - alt].position = self.net[x][y].position self.net[x][y - alt].rotation = self.net[x][y].rotation self.net[x][y - alt].enabled = False self.net[x][y - alt].run_action(A.sequence(A.move_to(*self.brickgetpos(y - alt, x), 0.2 * alt ** 0.5, TIMING_EASE_IN_2), A.call(lambda: self.enable_cell(x, y - alt)))) def enable_cell(self, x, y): self.net[x][y].enabled = True def fall(self): for x in range(self.WB): for y in range(self.HB): if self.net[x][y].is_on: self.gravity(x, y) def update_scores(self): self.score += self.last_score self.score_label.text = "Score: " + str(self.score) self.last_score_label.text = "Delta: +" + str(self.last_score) self.last_score = 0 def update_cells(self): for i in range(self.WB): for j in range(self.HB): if not self.net[i][j].is_on: self.net[i][j] = self.brick(self.random_brick_type(), j + self.HB, i) self.net[i][j].enabled = True self.net[i][j].run_action(A.sequence(A.move_to(*self.brickgetpos(j, i), 0.2 * self.HB ** 0.5, TIMING_EASE_IN_2), A.call(lambda: self.enable_cell(i, j)))) def inbounds(self, x, y): return (x >= 0) and (y >= 0) and (x < self.WB) and (y < self.HB) def bomb(self, x, y, radius): score = 0 bc = 0 for i in range(round(4 * radius ** 2)): rad = random.random() * radius ang = random.random() * 2 * pi xp, yp = x + sin(ang) * rad, y + cos(ang) * rad xp, yp = int(xp), int(yp) if self.inbounds(xp, yp): score += self.explode(xp, yp) self.fall() self.give_score(round(score / 1.7), self.brickgetpos(y, x)) def laser(self, x, y): score = 0 coords = [] for i in range(self.HB): for j in range(-1, 1 + 1, 1): coords.append((x + j, i)) for i in range(self.WB): coords.append((i, y)) for i in range(-self.HB, self.HB): coords.append((x + i, y + i)) for i in range(-self.WB, self.WB): coords.append((x - i, y + i)) bc = 0 for x, y in coords: if not self.inbounds(x, y): continue score += self.explode(x, y) self.fall() self.give_score(score, self.brickgetpos(y, x)) def getty(self, x, y): if not self.inbounds(x, y) or not self.net[x][y].is_on: return -1 else: return self.net[x][y].brick_type def popupt(self, text, position_, font_=("Arial", 30), color_="white"): label = LabelNode(text, font=font_, color=color_, parent=self, position=position_) label.run_action(A.sequence(A.wait(1), A.call(label.remove_from_parent))) def give_score(self, count, xy): self.last_score = int(count ** 2.5) size = 10 if self.last_score > 50000: size = 60 elif self.last_score > 20000: size = 40 elif self.last_score > 10000: size = 30 elif self.last_score > 5000: size = 25 elif self.last_score > 2000: size = 20 elif self.last_score > 1000: size = 15 if self.last_score > 0: self.popupt("+" + str(self.last_score), xy, font_=("Chalkduster", int(size * 1.5))) self.update_scores() def touch_began(self, touch): if not self.game_on: return x, y = touch.location x, y = x + self.W / 2, y + self.H / 2 W, H = get_screen_size() x, y = x, y x, y = int(x), int(y) x, y = x - self.Woff, y - self.Hoff x, y = x // self.W, y // self.H if not self.inbounds(x, y): return count = self.react(self.net[x][y].brick_type, x, y, True) self.demark() if self.getty(x, y) in [0, 1, 2, 3]: if count >= 2: self.react(self.net[x][y].brick_type, x, y) self.fall() self.give_score(count, touch.location) elif self.getty(x, y) == 4: self.bomb(x, y, 5 * count) elif self.getty(x, y) == 5: self.explode(x, y) self.fall() self.update_cells() def explode(self, x, y): if self.net[x][y].is_on: self.net[x][y].destroy() self.gems[self.net[x][y].brick_type] += 1 s = str(self.gems[self.net[x][y].brick_type]) self.lt[self.net[x][y].brick_type].text = " " * len(s) + ": " + s self.game_node.add_child(Explosion(self.net[x][y])) return True else: return False def react(self, col, x, y, ignore=False): if self.inbounds(x, y) and self.net[x][y].brick_type == col and self.net[x][y].is_on and self.net[x][y].lf and self.net[x][y].enabled: if not ignore: self.explode(x, y) else: self.net[x][y].mark() r = 1 r += self.react(col, x + 1, y + 0, ignore) r += self.react(col, x - 1, y - 0, ignore) r += self.react(col, x + 0, y + 1, ignore) r += self.react(col, x - 0, y - 1, ignore) return r else: return 0 def destroy_brick(self, x, y): self.net[x][y].destroy() run(Game(), LANDSCAPE, show_fps=True) 


рдХреНрд░рд┐рд╕реНрдЯрд▓ рдХреЗ рдХрд╛рдо рдХрд╛ рдкреНрд░рджрд░реНрд╢рди:

Source: https://habr.com/ru/post/hi464805/


All Articles