def main(): pygame.init() global HEADER_FONT HEADER_FONT = pygame.font.SysFont("freeserif", 25, bold=1) window = pygame.display.set_mode((WIDTH, HEIGHT)) fps = pygame.time.Clock() start_time = time.time() human = Human() human.setDaemon(True) human.start() while True: quit_flag = handle_event(human) if quit_flag: return window.fill(COLOR_WHITE) draw_header(window, start_time) draw_fps(window) # pdb.set_trace() human.draw(window) pygame.display.update() fps.tick(30)
class Game: FPS = 60 BLACK = (0, 0, 0) WHITE = (255, 255, 255) PLAY = 0 PAUSE = 1 GOAL = 2 WIN = 3 LOSE = 4 MENU = 5 EXIT = 6 GOAL_TIME = 2 * FPS # 2 sec WIN_TIME = 3 * FPS LOSE_TIME = 3 * FPS MAX_SCORE = 3 def __init__(self): self.bg = pygame.image.load("images/bg.jpg") self.bg = pygame.transform.scale(self.bg, (SCREEN_WIDTH, SCREEN_HEIGHT)) self.bgrect = self.bg.get_rect() self.ball = Ball() self.human = Human() self.robot = Robot() self.goal = Goal(0) self.win = Win(0) self.lose = Lose(0) self.menu = Menu() self.mouse = (0, 0) self.sounds = Sounds() self.sounds.music() self.status = Game.MENU self.reset() def reset(self): self.ball.set_pos(0.3 * SCREEN_WIDTH, 0.3 * SCREEN_HEIGHT) self.human.set_pos(0.05 * SCREEN_WIDTH, SCREEN_HEIGHT / 2 - self.human.height() / 2) self.robot.set_pos(0.8 * SCREEN_WIDTH, SCREEN_HEIGHT / 2 - self.robot.height() / 2) self.human.score = 0 self.robot.score = 0 self.last_detect = 0 self._key_up = False self._key_down = False self.status = Game.MENU def goal_start(self): self.status = Game.GOAL self.goal = Goal(Game.GOAL_TIME) def win_start(self): self.status = Game.WIN self.win = Win(Game.WIN_TIME) def lose_start(self): self.status = Game.LOSE self.lose = Lose(Game.LOSE_TIME) def update(self): if self.status == Game.MENU: if self.menu.test(self.mouse[0], self.mouse[1]) == Menu.MENU_PLAY: # menu -> play self.reset() self.robot.level = 2 self.status = Game.PLAY self.sounds.click() elif self.menu.test( self.mouse[0], self.mouse[1]) == Menu.MENU_EXIT: # menu -> exit self.status = Game.EXIT self.sounds.click() # goal -> continue elif self.status == Game.GOAL and self.goal.update() == 0: if self.robot.score >= Game.MAX_SCORE: # goal -> end game self.lose_start() self.sounds.lose() elif self.human.score >= Game.MAX_SCORE: # goal -> end game self.win_start() self.sounds.win() else: self.status = Game.PLAY # goal -> continue play # process win/lose elif self.status == Game.WIN: if self.win.update() == 0: self.status = Game.MENU # win -> menu elif self.status == Game.LOSE: if self.lose.update() == 0: self.status = Game.MENU # lose -> menu elif self.status == Game.PLAY: # calc next self.ball.move() if self._key_up and self.human.top() > SCREEN_HEIGHT / 10: self.human.go_up() elif self._key_down and self.human.bottom( ) < SCREEN_HEIGHT * 9 / 10: self.human.go_down() #self.robot.move() # goal detect if self.ball.left() < 0: self.robot.score += 1 self.ball.reset(SCREEN_WIDTH, SCREEN_HEIGHT) self.goal_start() self.status = Game.GOAL self.sounds.goal() # goal detect if self.ball.right() > SCREEN_WIDTH: self.human.score += 1 self.ball.reset(SCREEN_WIDTH, SCREEN_HEIGHT) self.goal_start() self.status = Game.GOAL self.sounds.goal() # wall collision detect if self.ball.top() < 0 or self.ball.bottom() > SCREEN_HEIGHT: self.ball.toggleY() self.sounds.ball() # player collision detect if pygame.time.get_ticks() - self.last_detect > 500: if self.ball.collision( self.human.rect()) or self.ball.collision( self.robot.rect()): self.last_detect = pygame.time.get_ticks() self.sounds.ball() # robot update if self.robot.level == 0 and self.robot.top( ) < SCREEN_HEIGHT / 10 or self.robot.bottom( ) > SCREEN_HEIGHT * 9 / 10: self.robot.toggle_y() elif self.robot.level >= 1: self.robot.ai(self.ball) self.mouse = (0, 0) def draw_score(self, screen): text = str(self.human.score) + ' : ' + str(self.robot.score) font = pygame.font.Font('freesansbold.ttf', 30) text_surface = font.render(text, True, Game.BLACK) text_rect = text_surface.get_rect() text_rect.center = ((SCREEN_WIDTH / 2), (0.1 * SCREEN_HEIGHT)) screen.blit(text_surface, text_rect) def draw(self, screen): screen.fill(Game.BLACK) screen.blit(self.bg, self.bgrect) self.ball.draw(screen) self.human.draw(screen) self.robot.draw(screen) self.draw_score(screen) self.goal.draw(screen) if self.status == Game.MENU: self.menu.draw(screen) elif self.status == Game.WIN: self.win.draw(screen) elif self.status == Game.LOSE: self.lose.draw(screen) def key_up(self, status): self._key_up = status def key_down(self, status): self._key_down = status
class YeadonGUI(HasTraits): """A GUI for the yeadon module, implemented using the traits package.""" # Input. measurement_file_name = File() # Drawing options. show_mass_center = Bool(False) show_inertia_ellipsoid = Bool(False) # Configuration variables. opts = {'enter_set': True, 'auto_set': True, 'mode': 'slider'} for name, bounds in zip(Human.CFGnames, Human.CFGbounds): # TODO : Find a better way than using locals here, it may not be a good # idea, but I don't know the consequences. locals()[name] = Range(float(rad2deg(bounds[0])), float(rad2deg(bounds[1])), 0.0, **opts) reset_configuration = Button() # Display of Human object properties. Ixx = Property(Float, depends_on=sliders) Ixy = Property(Float, depends_on=sliders) Ixz = Property(Float, depends_on=sliders) Iyx = Property(Float, depends_on=sliders) Iyy = Property(Float, depends_on=sliders) Iyz = Property(Float, depends_on=sliders) Izx = Property(Float, depends_on=sliders) Izy = Property(Float, depends_on=sliders) Izz = Property(Float, depends_on=sliders) x = Property(Float, depends_on=sliders) y = Property(Float, depends_on=sliders) z = Property(Float, depends_on=sliders) scene = Instance(MlabSceneModel, args=()) input_group = Group(Item('measurement_file_name')) vis_group = Group(Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=580, width=430, show_label=False)) config_first_group = Group( Item('somersault'), Item('tilt'), Item('twist'), Item('PTsagittalFlexion', label='PT sagittal flexion'), Item('PTbending', label='PT bending'), Item('TCspinalTorsion', label='TC spinal torsion'), Item('TCsagittalSpinalFlexion', label='TC sagittal spinal flexion'), label='Whole-body, pelvis, torso', dock='tab', ) config_upper_group = Group( Item('CA1extension', label='CA1 extension'), Item('CA1adduction', label='CA1 adduction'), Item('CA1rotation', label='CA1 rotation'), Item('CB1extension', label='CB1 extension'), Item('CB1abduction', label='CB1 abduction'), Item('CB1rotation', label='CB1 rotation'), Item('A1A2extension', label='A1A2 extension'), Item('B1B2extension', label='B1B2 extension'), label='Upper limbs', dock='tab', ) config_lower_group = Group( Item('PJ1extension', label='PJ1 extension'), Item('PJ1adduction', label='PJ1 adduction'), Item('PK1extension', label='PK1 extension'), Item('PK1abduction', label='PK1 abduction'), Item('J1J2flexion', label='J1J2 flexion'), Item('K1K2flexion', label='K1K2 flexion'), label='Lower limbs', dock='tab', ) config_group = VGroup( Label('Configuration'), Group(config_first_group, config_upper_group, config_lower_group, layout='tabbed', ), Item('reset_configuration', show_label=False), Label('P: pelvis (red); T: thorax (orange); C: chest-head (yellow)'), Label('A1/A2: left upper arm/forearm-hand; B1/B2: right arm'), Label('J1/J2: left thigh/shank-foot; K1/K2: right leg'), show_border=True, ) inertia_prop = VGroup( Label('Mass center (from origin of coord. sys.) (m):'), HGroup( Item('x', style='readonly', format_func=format_func), Item('y', style='readonly', format_func=format_func), Item('z', style='readonly', format_func=format_func) ), Label('Inertia tensor (about origin, in basis shown) (kg-m^2):'), HSplit( # HSplit 2 Group( Item('Ixx', style='readonly', format_func=format_func), Item('Iyx', style='readonly', format_func=format_func), Item('Izx', style='readonly', format_func=format_func), ), Group( Item('Ixy', style='readonly', format_func=format_func), Item('Iyy', style='readonly', format_func=format_func), Item('Izy', style='readonly', format_func=format_func), ), Group( Item('Ixz', style='readonly', format_func=format_func), Item('Iyz', style='readonly', format_func=format_func), Item('Izz', style='readonly', format_func=format_func) ), ), # end HSplit 2 Label('X, Y, Z axes drawn as red, green, blue arrows, respectively.'), show_border=True, ) # end VGroup view = View( VSplit( input_group, HSplit(vis_group, VSplit( config_group, Item('show_mass_center'), Item('show_inertia_ellipsoid'), inertia_prop ) ), ), resizable=True, title='Yeadon human inertia model' ) # end View measPreload = { 'Ls5L' : 0.545, 'Lb2p' : 0.278, 'La5p' : 0.24, 'Ls4L' : 0.493, 'La5w' : 0.0975, 'Ls4w' : 0.343, 'La5L' : 0.049, 'Lb2L' : 0.2995, 'Ls4d' : 0.215, 'Lj2p' : 0.581, 'Lb5p' : 0.24, 'Lb5w' : 0.0975, 'Lk8p' : 0.245, 'Lk8w' : 0.1015, 'Lj5L' : 0.878, 'La6w' : 0.0975, 'Lk1L' : 0.062, 'La6p' : 0.2025, 'Lk1p' : 0.617, 'La6L' : 0.0805, 'Ls5p' : 0.375, 'Lj5p' : 0.2475, 'Lk8L' : 0.1535, 'Lb5L' : 0.049, 'La3p' : 0.283, 'Lj9w' : 0.0965, 'La4w' : 0.055, 'Ls6L' : 0.152, 'Lb0p' : 0.337, 'Lj8w' : 0.1015, 'Lk2p' : 0.581, 'Ls6p' : 0.53, 'Lj9L' : 0.218, 'La3L' : 0.35, 'Lj8p' : 0.245, 'Lj3L' : 0.449, 'La4p' : 0.1685, 'Lk3L' : 0.449, 'Lb3p' : 0.283, 'Ls7L' : 0.208, 'Ls7p' : 0.6, 'Lb3L' : 0.35, 'Lk3p' : 0.3915, 'La4L' : 0.564, 'Lj8L' : 0.1535, 'Lj3p' : 0.3915, 'Lk4L' : 0.559, 'La1p' : 0.2915, 'Lb6p' : 0.2025, 'Lj6L' : 0.05, 'Lb6w' : 0.0975, 'Lj6p' : 0.345, 'Lb6L' : 0.0805, 'Ls0p' : 0.97, 'Ls0w' : 0.347, 'Lj6d' : 0.122, 'Ls8L' : 0.308, 'Lk5L' : 0.878, 'La2p' : 0.278, 'Lj9p' : 0.215, 'Ls1L' : 0.176, 'Lj1L' : 0.062, 'Lb1p' : 0.2915, 'Lj1p' : 0.617, 'Ls1p' : 0.865, 'Ls1w' : 0.317, 'Lk4p' : 0.34, 'Lk5p' : 0.2475, 'La2L' : 0.2995, 'Lb4w' : 0.055, 'Lb4p' : 0.1685, 'Lk9p' : 0.215, 'Lk9w' : 0.0965, 'Ls2p' : 0.845, 'Lj4L' : 0.559, 'Ls2w' : 0.285, 'Lk6L' : 0.05, 'La7w' : 0.047, 'La7p' : 0.1205, 'La7L' : 0.1545, 'Lk6p' : 0.345, 'Ls2L' : 0.277, 'Lj4p' : 0.34, 'Lk6d' : 0.122, 'Lk9L' : 0.218, 'Lb4L' : 0.564, 'La0p' : 0.337, 'Ls3w' : 0.296, 'Ls3p' : 0.905, 'Lb7p' : 0.1205, 'Lb7w' : 0.047, 'Lj7p' : 0.252, 'Lb7L' : 0.1545, 'Ls3L' : 0.388, 'Lk7p' : 0.252 } def __init__(self, meas_in=None): HasTraits.__init__(self, trait_value=True) if meas_in: measurement_file_name = meas_in else: measurement_file_name = 'Path to measurement input text file.' self.H = Human(meas_in if meas_in else self.measPreload) self._init_draw_human() def _init_draw_human(self): self.H.draw(self.scene.mlab, True) if self.show_mass_center: self.H._draw_mayavi_mass_center_sphere(self.scene.mlab) if self.show_inertia_ellipsoid: self.H._draw_mayavi_inertia_ellipsoid(self.scene.mlab) @on_trait_change('scene.activated') def set_view(self): """Sets a reasonable camera angle for the intial view.""" self.scene.mlab.view(azimuth=90.0, elevation=-90.0) def _get_Ixx(self): return self.H.inertia[0, 0] def _get_Ixy(self): return self.H.inertia[0, 1] def _get_Ixz(self): return self.H.inertia[0, 2] def _get_Iyx(self): return self.H.inertia[1, 0] def _get_Iyy(self): return self.H.inertia[1, 1] def _get_Iyz(self): return self.H.inertia[1, 2] def _get_Izx(self): return self.H.inertia[2, 0] def _get_Izy(self): return self.H.inertia[2, 1] def _get_Izz(self): return self.H.inertia[2, 2] def _get_x(self): return self.H.center_of_mass[0, 0] def _get_y(self): return self.H.center_of_mass[1, 0] def _get_z(self): return self.H.center_of_mass[2, 0] @on_trait_change('measurement_file_name') def _update_measurement_file_name(self): # Must convert to str (from unicode), because Human parses it # differently depending on its type, and there's no consideration for # it being unicode. self.H = Human(str(self.measurement_file_name)) self.scene.mlab.clf() self._init_draw_human() @on_trait_change('show_inertia_ellipsoid') def _update_show_inertia_ellipsoid(self): if self.show_inertia_ellipsoid: self.H._draw_mayavi_inertia_ellipsoid(self.scene.mlab) else: self.H._ellipsoid_mesh.remove() def _maybe_update_inertia_ellipsoid(self): if self.show_inertia_ellipsoid: self.H._update_mayavi_inertia_ellipsoid() @on_trait_change('show_mass_center') def _update_show_mass_center(self): if self.show_mass_center: self.H._draw_mayavi_mass_center_sphere(self.scene.mlab) else: self.H._mass_center_sphere.remove() def _maybe_update_mass_center(self): if self.show_mass_center: self.H._update_mayavi_mass_center_sphere() @on_trait_change('reset_configuration') def _update_reset_configuration(self): # TODO: This is really slow because it sets every trait one by one. It # would be nice to set them all to zero and only call the redraw once. for cfg in sliders: setattr(self, cfg, self.trait(cfg).default_value()[1]) @on_trait_change('somersault') def _update_somersault(self): self.H.set_CFG('somersault', deg2rad(self.somersault)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('tilt') def _update_tilt(self): self.H.set_CFG('tilt', deg2rad(self.tilt)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('twist') def _update_twist(self): self.H.set_CFG('twist', deg2rad(self.twist)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PTsagittalFlexion') def _update_PTsagittalFlexion(self): self.H.set_CFG('PTsagittalFlexion', deg2rad(self.PTsagittalFlexion)) self._update_mayavi(['T', 'C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PTbending') def _update_PTFrontalFlexion(self): self.H.set_CFG('PTbending', deg2rad(self.PTbending)) self._update_mayavi(['T', 'C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('TCspinalTorsion') def _update_TCSpinalTorsion(self): self.H.set_CFG('TCspinalTorsion', deg2rad(self.TCspinalTorsion)) self._update_mayavi(['C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('TCsagittalSpinalFlexion') def _update_TCLateralSpinalFlexion(self): self.H.set_CFG('TCsagittalSpinalFlexion', deg2rad(self.TCsagittalSpinalFlexion)) self._update_mayavi(['C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1extension') def _update_CA1extension(self): self.H.set_CFG('CA1extension', deg2rad(self.CA1extension)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1adduction') def _update_CA1adduction(self): self.H.set_CFG('CA1adduction', deg2rad(self.CA1adduction)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1rotation') def _update_CA1rotation(self): self.H.set_CFG('CA1rotation', deg2rad(self.CA1rotation)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1extension') def _update_CB1extension(self): self.H.set_CFG('CB1extension', deg2rad(self.CB1extension)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1abduction') def _update_CB1abduction(self): self.H.set_CFG('CB1abduction', deg2rad(self.CB1abduction)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1rotation') def _update_CB1rotation(self): self.H.set_CFG('CB1rotation', deg2rad(self.CB1rotation)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('A1A2extension') def _update_A1A2extension(self): self.H.set_CFG('A1A2extension', deg2rad(self.A1A2extension)) self._update_mayavi(['A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('B1B2extension') def _update_B1B2extension(self): self.H.set_CFG('B1B2extension', deg2rad(self.B1B2extension)) self._update_mayavi(['B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PJ1extension') def _update_PJ1extension(self): self.H.set_CFG('PJ1extension', deg2rad(self.PJ1extension)) self._update_mayavi(['J1', 'J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PJ1adduction') def _update_PJ1adduction(self): self.H.set_CFG('PJ1adduction', deg2rad(self.PJ1adduction)) self._update_mayavi(['J1', 'J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PK1extension') def _update_PK1extension(self): self.H.set_CFG('PK1extension', deg2rad(self.PK1extension)) self._update_mayavi(['K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PK1abduction') def _update_PK1abduction(self): self.H.set_CFG('PK1abduction', deg2rad(self.PK1abduction)) self._update_mayavi(['K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('J1J2flexion') def _update_J1J2flexion(self): self.H.set_CFG('J1J2flexion', deg2rad(self.J1J2flexion)) self._update_mayavi(['J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('K1K2flexion') def _update_K1K2flexion(self): self.H.set_CFG('K1K2flexion', deg2rad(self.K1K2flexion)) self._update_mayavi(['K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() def _update_mayavi(self, segments): """Updates all of the segments and solids.""" for affected in segments: seg = self.H.get_segment_by_name(affected) for solid in seg.solids: solid._mesh.scene.disable_render = True for affected in segments: self.H.get_segment_by_name(affected)._update_mayavi() for affected in segments: seg = self.H.get_segment_by_name(affected) for solid in seg.solids: solid._mesh.scene.disable_render = False