Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- from kivy.animation import Animation
- from kivy.core.window import Window
- from kivy.clock import Clock
- from kivy.uix.relativelayout import RelativeLayout
- from common import config, FixedSizeImage
- class NewtonBehaviour:
- def __init__(self, newton):
- self.newton = newton
- def start(self, duration):
- self.t = 0
- def tick(self, dt):
- self.t += dt
- return True
- @config(
- duration_range = (1, 2)
- )
- class IdleNewtonBehaviour(NewtonBehaviour):
- def __init__(self, newton):
- NewtonBehaviour.__init__(self, newton)
- def start(self, duration):
- NewtonBehaviour.start(self, duration)
- self.duration = duration
- def tick(self, dt):
- if not NewtonBehaviour.tick(self, dt):
- return False
- return self.t <= self.duration
- class FramedNewtonBehaviour(IdleNewtonBehaviour):
- def __init__(self, newton, interval, frames, loop):
- IdleNewtonBehaviour.__init__(self, newton)
- self.interval = interval
- self.frames = frames
- self.loop = loop
- def start(self, duration):
- IdleNewtonBehaviour.start(self, duration)
- self.prev_key = self.newton.image_key
- self.frame_index = -1
- if not self.interval:
- self.interval = float(duration) / len(self.frames)
- def tick(self, dt):
- if not IdleNewtonBehaviour.tick(self, dt):
- self.newton.set_image(self.prev_key)
- return False
- if not self.frames and not self.loop:
- return False
- frame_index = int(self.t/self.interval) % len(self.frames)
- if frame_index < self.frame_index and not self.loop:
- return False
- if frame_index != self.frame_index:
- self.frame_index = frame_index
- frame_key = self.frames[self.frame_index]
- self.newton.set_image(frame_key)
- return True
- @config(
- duration_range = (0.1, 10)
- )
- class WalkNewtonBehaviour(FramedNewtonBehaviour):
- def __init__(self, newton):
- IdleNewtonBehaviour.__init__(self, newton)
- def start(self, duration):
- IdleNewtonBehaviour.start(self, duration)
- self.velocity = self.newton.width * (1 + 2*random.random())
- if random.randint(0,1):
- self.velocity *= -1
- def tick(self, dt):
- if not IdleNewtonBehaviour.tick(self, dt):
- return False
- if self.velocity > 0:
- dt = min(dt, (self.newton.max_x - self.newton.x)/self.velocity)
- else:
- dt = min(dt, (self.newton.min_x - self.newton.x)/self.velocity)
- if dt <= 0:
- self.velocity *= -1
- return True
- if self.newton.face_direction * self.velocity < 0:
- self.newton.flip()
- self.newton.x += self.velocity * dt
- return True
- @config(
- duration_range = (0.3, 1)
- )
- class JumpNewtonBehaviour(IdleNewtonBehaviour):
- def __init__(self, newton):
- IdleNewtonBehaviour.__init__(self, newton)
- self.g = 1500
- def start(self, duration):
- IdleNewtonBehaviour.start(self, duration)
- self.start_y = self.newton.y
- self.v0y = duration*self.g / 2.
- def tick(self, dt):
- if not IdleNewtonBehaviour.tick(self, dt):
- self.newton.y = self.start_y
- return False
- t = self.t
- self.newton.y = self.start_y + self.v0y*t - self.g*t*t / 2.
- if self.newton.y < self.start_y:
- self.newton.y = self.start_y
- return False
- return True
- @config(
- duration_range = (2, 4)
- )
- class CrouchNewtonBehaviour(FramedNewtonBehaviour):
- def __init__(self, newton):
- frames = ['crouch_' + str(i) for i in [1,2,1]]
- FramedNewtonBehaviour.__init__(self, newton, None, frames, False)
- class DeathNewtonBehaviour(FramedNewtonBehaviour):
- def __init__(self, newton):
- frames = ['death_' + str(i) for i in range(1, 6)]
- FramedNewtonBehaviour.__init__(self, newton, 0.2, frames, False)
- class MuxNewtonBehaviour:
- def __init__(self, b1, b2):
- self.b1 = b1
- self.b2 = b2
- def start(self, duration):
- self.b1.start(duration)
- self.b2.start(duration)
- self.b1_done, self.b2_done = False, False
- def tick(self, dt):
- if not self.b1_done:
- self.b1_done = not self.b1.tick(dt)
- if not self.b2_done:
- self.b2_done = not self.b2.tick(dt)
- return not (self.b1_done and self.b2_done)
- @config(
- allowed_behaviours = ['walk', 'jump', 'walk+jump', 'idle', 'crouch']
- )
- class Newton(FixedSizeImage):
- def __init__(self, **kwargs):
- super(Newton, self).__init__(**kwargs)
- allowed = set(Newton.get_allowed_behaviours())
- self.behaviours = \
- [behaviour for name, behaviour in self.get_behaviours().items()
- if name in allowed]
- self.face_direction = -1
- self.set_image("stand_1")
- self.tick = None
- self.dead = False
- self.min_x = Newtons.get_min_x(self)
- self.max_x = Newtons.get_max_x(self)
- def set_image(self, key):
- self.image_key = key
- self.image.source = 'images/new_{}{:+}.png'.format(key, self.face_direction)
- def flip(self):
- self.face_direction *= -1
- src = self.image.source
- key = self.image.source[src.rfind("/new_")+5:-6]
- self.set_image(key)
- def random_behaviour(self):
- if self.behaviours:
- return random.choice(self.behaviours)()
- else:
- return self.idle_behaviour()
- def get_behaviours(self):
- return {
- 'walk': self.walk_behaviour,
- 'jump': self.jump_behaviour,
- 'walk+jump': self.walk_and_jump_behaviour,
- 'idle': self.idle_behaviour,
- 'crouch': self.crouch_behaviour
- }
- def walk_behaviour(self):
- behaviour = MuxNewtonBehaviour(
- WalkNewtonBehaviour(self),
- FramedNewtonBehaviour(self, 0.2, ['walk_'+str(i) for i in range(1, 7)], True)
- )
- return behaviour, WalkNewtonBehaviour.get_duration_range()
- def jump_behaviour(self):
- behaviour = MuxNewtonBehaviour(
- JumpNewtonBehaviour(self),
- FramedNewtonBehaviour(self, None, ['jump_'+str(i) for i in range(1, 3)], False)
- )
- return behaviour, JumpNewtonBehaviour.get_duration_range()
- def walk_and_jump_behaviour(self):
- jump, duration = self.jump_behaviour()
- return MuxNewtonBehaviour(WalkNewtonBehaviour(self), jump), duration
- def idle_behaviour(self):
- return IdleNewtonBehaviour(self), IdleNewtonBehaviour.get_duration_range()
- def crouch_behaviour(self):
- return CrouchNewtonBehaviour(self), CrouchNewtonBehaviour.get_duration_range()
- def exec_random_behaviour_forever(self):
- behaviour, duration_range = self.random_behaviour()
- self.exec_behaviour(behaviour, duration_range, self.exec_random_behaviour_forever)
- def exec_behaviour(self, behaviour, duration_range, on_complete=None):
- min_time, max_time = duration_range
- duration = min_time + (max_time-min_time)*random.random()
- behaviour.start(duration)
- def tick_behaviour(dt):
- if not behaviour.tick(dt):
- self.stop_behaviour()
- if on_complete:
- on_complete()
- self.tick = tick_behaviour
- def stop_behaviour(self):
- self.tick = None
- def die(self, on_complete=None):
- self.dead = True
- self.stop_behaviour()
- self.exec_behaviour(DeathNewtonBehaviour(self), (1,4), on_complete)
- @config(
- num_newtons = 3,
- left_margin = 200,
- right_margin = 20
- )
- class Newtons(RelativeLayout):
- def __init__(self, **kwargs):
- super(Newtons, self).__init__(**kwargs)
- def watch(self):
- def spawn_missing_newtons(dt):
- if len(self.children) < Newtons.get_num_newtons():
- self.spawn_newton()
- self.spawner = spawn_missing_newtons
- Clock.schedule_interval(self.tick_newtons, 1/60.)
- Clock.schedule_interval(self.spawner, 0.5)
- @staticmethod
- def get_min_x(newton):
- return Newtons.get_left_margin()
- @staticmethod
- def get_max_x(newton):
- return Window.width - newton.width - Newtons.get_right_margin()
- def spawn_newton(self):
- newton = Newton()
- newton.x = random.randint(newton.min_x, newton.max_x)
- newton.y = self.to_widget(0, Window.height)[1]
- newton.face_direction = random.choice([-1, 1])
- fall = Animation(y = 0, duration=1, t='in_quad')
- fall.on_complete = lambda _: \
- newton.exec_random_behaviour_forever() if not newton.dead else None
- fall.start(newton)
- newton.falling_animation = fall
- self.add_widget(newton)
- def tick_newtons(self, dt):
- for newton in self.children:
- if newton.tick:
- newton.tick(dt)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement