Advertisement
Guest User

Untitled

a guest
Dec 21st, 2014
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.15 KB | None | 0 0
  1. import random
  2.  
  3. from kivy.animation import Animation
  4. from kivy.core.window import Window
  5. from kivy.clock import Clock
  6. from kivy.uix.relativelayout import RelativeLayout
  7.  
  8. from common import config, FixedSizeImage
  9.  
  10.  
  11. class NewtonBehaviour:
  12.     def __init__(self, newton):
  13.         self.newton = newton
  14.  
  15.     def start(self, duration):
  16.         self.t = 0
  17.  
  18.     def tick(self, dt):
  19.         self.t += dt
  20.         return True
  21.  
  22. @config(
  23.     duration_range = (1, 2)
  24. )
  25. class IdleNewtonBehaviour(NewtonBehaviour):
  26.     def __init__(self, newton):
  27.         NewtonBehaviour.__init__(self, newton)
  28.  
  29.     def start(self, duration):
  30.         NewtonBehaviour.start(self, duration)
  31.         self.duration = duration
  32.  
  33.     def tick(self, dt):
  34.         if not NewtonBehaviour.tick(self, dt):
  35.             return False
  36.  
  37.         return self.t <= self.duration
  38.  
  39. class FramedNewtonBehaviour(IdleNewtonBehaviour):
  40.     def __init__(self, newton, interval, frames, loop):
  41.         IdleNewtonBehaviour.__init__(self, newton)
  42.         self.interval = interval
  43.         self.frames = frames
  44.         self.loop = loop
  45.  
  46.     def start(self, duration):
  47.         IdleNewtonBehaviour.start(self, duration)
  48.         self.prev_key = self.newton.image_key
  49.         self.frame_index = -1
  50.  
  51.         if not self.interval:
  52.             self.interval = float(duration) / len(self.frames)
  53.  
  54.     def tick(self, dt):
  55.         if not IdleNewtonBehaviour.tick(self, dt):
  56.             self.newton.set_image(self.prev_key)
  57.             return False
  58.  
  59.         if not self.frames and not self.loop:
  60.             return False
  61.  
  62.         frame_index = int(self.t/self.interval) % len(self.frames)
  63.  
  64.         if frame_index < self.frame_index and not self.loop:
  65.             return False
  66.  
  67.         if frame_index != self.frame_index:
  68.             self.frame_index = frame_index
  69.             frame_key = self.frames[self.frame_index]
  70.             self.newton.set_image(frame_key)
  71.  
  72.         return True
  73.  
  74. @config(
  75.     duration_range = (0.1, 10)
  76. )
  77. class WalkNewtonBehaviour(FramedNewtonBehaviour):
  78.     def __init__(self, newton):
  79.         IdleNewtonBehaviour.__init__(self, newton)
  80.  
  81.     def start(self, duration):
  82.         IdleNewtonBehaviour.start(self, duration)
  83.  
  84.         self.velocity = self.newton.width * (1 + 2*random.random())
  85.  
  86.         if random.randint(0,1):
  87.             self.velocity *= -1
  88.  
  89.     def tick(self, dt):
  90.         if not IdleNewtonBehaviour.tick(self, dt):
  91.             return False
  92.  
  93.         if self.velocity > 0:
  94.             dt = min(dt, (self.newton.max_x - self.newton.x)/self.velocity)
  95.         else:
  96.             dt = min(dt, (self.newton.min_x - self.newton.x)/self.velocity)
  97.  
  98.         if dt <= 0:
  99.             self.velocity *= -1
  100.             return True
  101.  
  102.         if self.newton.face_direction * self.velocity < 0:
  103.             self.newton.flip()
  104.  
  105.         self.newton.x += self.velocity * dt
  106.  
  107.         return True
  108.  
  109. @config(
  110.     duration_range = (0.3, 1)
  111. )
  112. class JumpNewtonBehaviour(IdleNewtonBehaviour):
  113.     def __init__(self, newton):
  114.         IdleNewtonBehaviour.__init__(self, newton)
  115.         self.g = 1500
  116.  
  117.     def start(self, duration):
  118.         IdleNewtonBehaviour.start(self, duration)
  119.  
  120.         self.start_y = self.newton.y
  121.         self.v0y = duration*self.g / 2.
  122.  
  123.     def tick(self, dt):
  124.         if not IdleNewtonBehaviour.tick(self, dt):
  125.             self.newton.y = self.start_y
  126.             return False
  127.  
  128.         t = self.t
  129.         self.newton.y = self.start_y + self.v0y*t - self.g*t*t / 2.
  130.  
  131.         if self.newton.y < self.start_y:
  132.             self.newton.y = self.start_y
  133.             return False
  134.  
  135.         return True
  136.  
  137. @config(
  138.     duration_range = (2, 4)
  139. )
  140. class CrouchNewtonBehaviour(FramedNewtonBehaviour):
  141.     def __init__(self, newton):
  142.         frames = ['crouch_' + str(i) for i in [1,2,1]]
  143.         FramedNewtonBehaviour.__init__(self, newton, None, frames, False)
  144.  
  145. class DeathNewtonBehaviour(FramedNewtonBehaviour):
  146.     def __init__(self, newton):
  147.         frames = ['death_' + str(i) for i in range(1, 6)]
  148.         FramedNewtonBehaviour.__init__(self, newton, 0.2, frames, False)
  149.  
  150.  
  151. class MuxNewtonBehaviour:
  152.     def __init__(self, b1, b2):
  153.         self.b1 = b1
  154.         self.b2 = b2
  155.  
  156.     def start(self, duration):
  157.         self.b1.start(duration)
  158.         self.b2.start(duration)
  159.  
  160.         self.b1_done, self.b2_done = False, False
  161.  
  162.     def tick(self, dt):
  163.         if not self.b1_done:
  164.             self.b1_done = not self.b1.tick(dt)
  165.         if not self.b2_done:
  166.             self.b2_done = not self.b2.tick(dt)
  167.  
  168.         return not (self.b1_done and self.b2_done)
  169.  
  170.  
  171. @config(
  172.     allowed_behaviours = ['walk', 'jump', 'walk+jump', 'idle', 'crouch']
  173. )
  174. class Newton(FixedSizeImage):
  175.     def __init__(self, **kwargs):
  176.         super(Newton, self).__init__(**kwargs)
  177.  
  178.         allowed = set(Newton.get_allowed_behaviours())
  179.  
  180.         self.behaviours = \
  181.             [behaviour for name, behaviour in self.get_behaviours().items()
  182.                          if name in allowed]
  183.  
  184.         self.face_direction = -1
  185.         self.set_image("stand_1")
  186.         self.tick = None
  187.         self.dead = False
  188.  
  189.         self.min_x = Newtons.get_min_x(self)
  190.         self.max_x = Newtons.get_max_x(self)
  191.  
  192.     def set_image(self, key):
  193.         self.image_key = key
  194.         self.image.source = 'images/new_{}{:+}.png'.format(key, self.face_direction)
  195.  
  196.     def flip(self):
  197.         self.face_direction *= -1
  198.  
  199.         src = self.image.source
  200.         key = self.image.source[src.rfind("/new_")+5:-6]
  201.         self.set_image(key)
  202.  
  203.  
  204.     def random_behaviour(self):
  205.         if self.behaviours:
  206.             return random.choice(self.behaviours)()
  207.         else:
  208.             return self.idle_behaviour()
  209.  
  210.     def get_behaviours(self):
  211.         return {
  212.             'walk':      self.walk_behaviour,
  213.             'jump':      self.jump_behaviour,
  214.             'walk+jump': self.walk_and_jump_behaviour,
  215.             'idle':      self.idle_behaviour,
  216.             'crouch':    self.crouch_behaviour
  217.         }
  218.  
  219.  
  220.     def walk_behaviour(self):
  221.         behaviour = MuxNewtonBehaviour(
  222.             WalkNewtonBehaviour(self),
  223.             FramedNewtonBehaviour(self, 0.2, ['walk_'+str(i) for i in range(1, 7)], True)
  224.         )
  225.         return behaviour, WalkNewtonBehaviour.get_duration_range()
  226.  
  227.     def jump_behaviour(self):
  228.         behaviour = MuxNewtonBehaviour(
  229.             JumpNewtonBehaviour(self),
  230.             FramedNewtonBehaviour(self, None, ['jump_'+str(i) for i in range(1, 3)], False)
  231.         )
  232.         return behaviour, JumpNewtonBehaviour.get_duration_range()
  233.  
  234.     def walk_and_jump_behaviour(self):
  235.         jump, duration = self.jump_behaviour()
  236.         return MuxNewtonBehaviour(WalkNewtonBehaviour(self), jump), duration
  237.  
  238.     def idle_behaviour(self):
  239.         return IdleNewtonBehaviour(self), IdleNewtonBehaviour.get_duration_range()
  240.  
  241.     def crouch_behaviour(self):
  242.         return CrouchNewtonBehaviour(self), CrouchNewtonBehaviour.get_duration_range()
  243.  
  244.  
  245.     def exec_random_behaviour_forever(self):
  246.         behaviour, duration_range = self.random_behaviour()
  247.         self.exec_behaviour(behaviour, duration_range, self.exec_random_behaviour_forever)
  248.  
  249.     def exec_behaviour(self, behaviour, duration_range, on_complete=None):
  250.         min_time, max_time = duration_range
  251.         duration = min_time + (max_time-min_time)*random.random()
  252.         behaviour.start(duration)
  253.  
  254.         def tick_behaviour(dt):
  255.             if not behaviour.tick(dt):
  256.                 self.stop_behaviour()
  257.                 if on_complete:
  258.                     on_complete()
  259.  
  260.         self.tick = tick_behaviour
  261.  
  262.     def stop_behaviour(self):
  263.         self.tick = None
  264.  
  265.  
  266.     def die(self, on_complete=None):
  267.         self.dead = True
  268.         self.stop_behaviour()
  269.         self.exec_behaviour(DeathNewtonBehaviour(self), (1,4), on_complete)
  270.  
  271.  
  272. @config(
  273.     num_newtons = 3,
  274.     left_margin = 200,
  275.     right_margin = 20
  276. )
  277. class Newtons(RelativeLayout):
  278.     def __init__(self, **kwargs):
  279.         super(Newtons, self).__init__(**kwargs)
  280.  
  281.     def watch(self):
  282.         def spawn_missing_newtons(dt):
  283.             if len(self.children) < Newtons.get_num_newtons():
  284.                 self.spawn_newton()
  285.  
  286.         self.spawner = spawn_missing_newtons
  287.         Clock.schedule_interval(self.tick_newtons, 1/60.)
  288.         Clock.schedule_interval(self.spawner, 0.5)
  289.  
  290.     @staticmethod
  291.     def get_min_x(newton):
  292.         return Newtons.get_left_margin()
  293.  
  294.     @staticmethod
  295.     def get_max_x(newton):
  296.         return Window.width - newton.width - Newtons.get_right_margin()
  297.  
  298.     def spawn_newton(self):
  299.         newton = Newton()
  300.         newton.x = random.randint(newton.min_x, newton.max_x)
  301.         newton.y = self.to_widget(0, Window.height)[1]
  302.  
  303.         newton.face_direction = random.choice([-1, 1])
  304.  
  305.         fall = Animation(y = 0, duration=1, t='in_quad')
  306.         fall.on_complete = lambda _: \
  307.                 newton.exec_random_behaviour_forever() if not newton.dead else None
  308.         fall.start(newton)
  309.         newton.falling_animation = fall
  310.  
  311.         self.add_widget(newton)
  312.  
  313.     def tick_newtons(self, dt):
  314.         for newton in self.children:
  315.             if newton.tick:
  316.                 newton.tick(dt)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement