class Corsi(): def __init__(self, experiment): self.logger = FileLogger() self.screen = pygame.display.get_surface() self.clock = pygame.time.Clock() self.experiment = experiment self.event_handler = EventHandler() self.keyboard_handler = Event() self.sprites_group = pygame.sprite.LayeredDirty() self.background = {} self.background["pasive"] = pygame.sprite.DirtySprite() # self.background["pasive"].image = pygame.surface.Surface(Properties.SCREEN_RES) self.background["pasive"].image = pygame.surface.Surface( self.screen.get_size()) self.background["pasive"].image.fill([40, 40, 40]) self.background["pasive"].rect = self.background[ "pasive"].image.get_rect() self.sprites_group.add(self.background["pasive"], layer=BACKGR_lyr) # self.background["active"] = pygame.sprite.DirtySprite() # self.background["active"].image = pygame.surface.Surface(Properties.SCREEN_RES) # # self.background["active"].image = pygame.surface.Surface(self.screen.get_size()) # self.background["active"].image.fill([80,80,80]) # self.background["active"].rect = self.background["active"].image.get_rect() # self.sprites_group.add(self.background["active"], layer=BACKGR_lyr) # self.background["active"].visible = False self.feedback_ok = Feedback() self.feedback_no = Feedback(False) self.sprites_group.add(self.feedback_ok, layer=FEED_lyr) self.sprites_group.add(self.feedback_no, layer=FEED_lyr) self.msgs = {} self.boxes = {} self.instruction = Instruction() self.instruction.hide() self.sprites_group.add(self.instruction, layer=INST_lyr) self.msgs["done"] = ImageDone() for v in self.msgs.itervalues(): self.sprites_group.add(v, layer=BTN_lyr) for box_name, position in self.experiment["box_positions"].iteritems(): box = Box(box_name, json.loads(position), self.experiment["properties"]) self.sprites_group.add(box, layer=BOXES_lyr) self.boxes[box_name] = box self.tic_group = [] self.trial = Trial( self.logger, self.experiment["properties"], self.change_to_active_mode, None, { "ok": self.feedback_ok.show, "no": self.feedback_no.show, "off": (lambda: [self.feedback_ok.hide(), self.feedback_no.hide()]) }) self.exp_runner = ExpRunner(self.experiment, self.trial, self.boxes) self.exp_runner.end_test = self.terminar_juego self.exp_runner.instruction = self.instruction self.trial.handle_end = self.exp_runner.next_trial self.trial.set_boxes(self.boxes, self.suscribe_box_on, self.unsuscribe_box) self.boxes_on = [] self.msgs["done"].set_callback(self.trial.next_by_usr) self.change_to_active_mode(False) def change_to_active_mode(self, toActive=True): # self.change_background(toActive) if toActive: self.state = INTERACTIVE self.msgs["done"].show() else: self.state = PASSIVE self.msgs["done"].hide() def change_background(self, toActive=True): if toActive: self.background["active"].visible = True self.background["pasive"].visible = False else: self.background["active"].visible = False self.background["pasive"].visible = True self.background["active"].dirty = True self.background["pasive"].dirty = True def set_events(self): key_suscribe = self.keyboard_handler.suscribe self.event_handler.suscribe( pygame.KEYDOWN, lambda ev: self.keyboard_handler.dispatch(ev.key, ev)) key_suscribe( pygame.K_ESCAPE, (lambda ev: [self.logger.log_message("esc pressed"), self.terminar_juego(ev)])) self.event_handler.suscribe( pygame.QUIT, (lambda ev: [self.logger.log_message("pygame quit"), self.terminar_juego(ev)])) self.event_handler.suscribe(pygame.MOUSEBUTTONDOWN, self.click) # self.event_handler.suscribe(pygame.MOUSEBUTTONUP, self.click) self.event_handler.suscribe(pygame.MOUSEBUTTONUP, self.release_click) # def click(self, res): # (x, y) = pygame.mouse.get_pos() # if self.state == INTERACTIVE: # for i in self.sprites_group.get_sprites_from_layer(BOXES_lyr): # if (i.rect.collidepoint(x, y)): # a = i.tic_off # ev = pygame.USEREVENT + 1 # print "Suscribing event ", ev # self.event_handler.suscribe(ev, a) # i.click(lambda: self.event_handler.unsuscribe(ev, a)) # pygame.time.set_timer(ev, self.experiment["properties"]["tansweron"]) def click(self, res): (x, y) = pygame.mouse.get_pos() if self.state == INTERACTIVE: click_in_box = False for i in self.sprites_group.get_sprites_from_layer(BOXES_lyr): if (i.rect.collidepoint(x, y)): # print "Click box ", i.box_name if not i.is_on: self.suscribe_box_on(i) i.click(self.experiment["properties"]["tansweron"], self.unsuscribe_box) self.trial.usr_answer(i.box_name, (x, y)) click_in_box = True for i in self.sprites_group.get_sprites_from_layer(BTN_lyr): if (i.rect.collidepoint(x, y)): # print "Click button " click_in_box = True i.click() if not click_in_box: self.trial.usr_answer(None, (x, y)) elif self.state == PASSIVE: if self.instruction.visible: self.instruction.hide() def release_click(self, res): (x, y) = pygame.mouse.get_pos() if self.state == INTERACTIVE: for i in self.sprites_group.get_sprites_from_layer(BTN_lyr): if (i.rect.collidepoint(x, y)): # print "Click button " click_in_box = True i.release_click() def suscribe_box_on(self, box): self.boxes_on.append(box) def unsuscribe_box(self, box): # import pdb; pdb.set_trace(); self.boxes_on.remove(box) def terminar_juego(self, ev=None): print "TERMINANDO" self.logger.log_message("end game") self.logger.close() self.running = False def report_answ(self, ev=None): if not self.trial.usr_answer(): self.logger.log_invalid_press() def run(self): #~ import pdb; pdb.set_trace() self.running = True self.set_events() self.exp_runner.next() self.mainLoop() def trial_handle_next(self): pass def mainLoop(self): pygame.display.flip() self.playing = None while self.running: self.clock.tick(60) self.event_handler.handle() self.trial.tic() for box in self.boxes_on: box.tic() self.sprites_group.draw(self.screen) pygame.display.flip()
class TowerOfLondon(): def __init__(self, experiment): self.logger = FileLogger() self.experiment = experiment self.mode = EXPERIMENT_MODE SCREEN_RES = (int(experiment["screen_res"]["x"]), int(experiment["screen_res"]["y"])) self.properties = Properties.Properties(SCREEN_RES) self.screen = pygame.display.get_surface() self.clock = pygame.time.Clock() self.event_handler = EventHandler.EventHandler() self.keyboard_handler = Event.Event() self.sprites_group = pygame.sprite.LayeredDirty() # self.background = pygame.sprite.DirtySprite() self.background = ImageMessage("scale_fondo{}.png".format(BACKGROUND_PROFILE)) self.background.scale(SCREEN_RES[0], SCREEN_RES[1]) self.background.show() # self.background.image = pygame.surface.Surface(Properties.SCREEN_RES) # self.background.image.fill([240,240,240]) # self.background.rect = self.background.image.get_rect() self.sprites_group.add(self.background, layer=BACKGR_lyr) self.floor = pygame.sprite.DirtySprite() self.floor.image = pygame.surface.Surface((self.properties.SCREEN_RES[0], self.properties.floor_height)) self.floor.image.fill([0,200,0]) self.floor.rect = self.floor.image.get_rect() self.floor.rect.bottom = self.properties.SCREEN_RES[1] self.sprites_group.add(self.floor, layer=FLOOR_lyr) self.feedback_ok = Feedback() self.feedback_no = Feedback(False) self.sprites_group.add(self.feedback_ok, layer=FEED_lyr) self.sprites_group.add(self.feedback_no, layer=FEED_lyr) self.state = State.State() st = self.state self.trial = Trial(self.logger, self.show_messages, None, {"ok": self.feedback_ok.show, "no": self.feedback_no.show, "off": (lambda: [self.feedback_ok.hide(), self.feedback_no.hide()])}, self) self.sprites_group.add(StickSprite(st.sticks[1], self.properties), layer=STICK_lyr) self.sprites_group.add(StickSprite(st.sticks[2], self.properties), layer=STICK_lyr) self.sprites_group.add(StickSprite(st.sticks[3], self.properties), layer=STICK_lyr) self.sprites_group.add(DiskSprite(st.get_disk(State.B),st.get_disk_position(State.B), mode=DISKS_PROFILE, prop=self.properties), layer=DISKS_lyr) self.sprites_group.add(DiskSprite(st.get_disk(State.G),st.get_disk_position(State.G), mode=DISKS_PROFILE, prop=self.properties), layer=DISKS_lyr) self.sprites_group.add(DiskSprite(st.get_disk(State.R),st.get_disk_position(State.R), mode=DISKS_PROFILE, prop=self.properties), layer=DISKS_lyr) self.goal = Goal(DISKS_PROFILE, prop=self.properties) self.sprites_group.add(self.goal, layer=GOAL_lyr) self.instruction = Instruction(prop=self.properties) self.instruction.hide() self.sprites_group.add(self.instruction, layer=INST_lyr) self.msgs = {} self.msgs["done"] = ImageDone(prop=self.properties) self.msgs["done"].set_callback(self.trial.check_answer) for v in self.msgs.itervalues(): self.sprites_group.add(v, layer=CTRL_BTN_lyr) self.exp_runner = ExpRunner(self.experiment, self.trial) self.exp_runner.end_test = self.end_game self.exp_runner.instruction = self.instruction self.exp_runner.next() self.clicked_sprite = None if self.mode == FREE_MODE: for i in range(1,8+1): self.sprites_group.add(TextLevel(i,self.set_board_distance), layer=LEVEL_SEL_lyr) self.show_messages(False) def show_messages(self, toActive=True, info_or_feedback=2): # self.change_background(toActive) # print "To PASSIVE MODE" for i in [GOAL_lyr, DISKS_lyr, CTRL_BTN_lyr,FEED_lyr, INST_lyr]: for sp in self.sprites_group.get_sprites_from_layer(i): sp.hide() if toActive: # print "To INTERACTIVE MODE" # self.msgs["done"].show() self.moving_state = INTERACTIVE # self.instruction.hide() # self.goal.visible = True for i in [GOAL_lyr, DISKS_lyr, CTRL_BTN_lyr]: for sp in self.sprites_group.get_sprites_from_layer(i): sp.show() else: if info_or_feedback==2: self.moving_state = PASSIVE self.instruction.show() else: self.moving_state = FEEDBACK if info_or_feedback==1: self.feedback_ok.show() elif info_or_feedback==0: self.feedback_no.show() def set_events(self): suscribir_tecla = self.keyboard_handler.suscribe self.event_handler.suscribe(pygame.QUIT, self.end_game) self.event_handler.suscribe(pygame.MOUSEBUTTONDOWN, self.clicked) self.event_handler.suscribe(pygame.MOUSEMOTION, self.move_mouse) self.event_handler.suscribe(pygame.MOUSEBUTTONUP, self.unclicked) self.event_handler.suscribe(pygame.KEYDOWN, lambda ev: self.keyboard_handler.dispatch(ev.key, ev)) suscribir_tecla(pygame.K_ESCAPE, self.end_game) def set_board_distance(self, distance=None): if distance is None: distance = randrange(8)+1 l1 = randrange(len(inc.distance.dist)) indexes = [i for i, x in enumerate(inc.distance.dist[l1]) if x == distance] l2 = choice(indexes) self.set_board(l1) self.set_goal(l2) def set_board(self, board_num): self.state.set_board_number(board_num) # self.state.show() def set_goal(self, board_num): self.goal_num = board_num self.moves_num = 0 self.sequence_boards = [self.state.get_board_number()] d = inc.distance.dist[board_num][self.state.get_board_number()] # self.goalText.set_message("Sale en %d movidas" %(d,)) self.goal.set(board_num) # self.goalText.rect.center = Properties.goal_pos self.refresh_indicators() self.refresh_all_sprites() def refresh_indicators(self): # self.stepsText.set_message("Movidas: %d" %(self.moves_num,)) # (x,y) = self.goalText.rect.bottomright # self.stepsText.rect.topright = (x,y) # (x,y) = self.stepsText.rect.bottomright # if self.state.get_board_number() == self.goal_num: # self.statusText.set_message("GANASTE") # else: # self.statusText.set_message("") # self.statusText.rect.topright = (x,y) pass def refresh_all_sprites(self): for i in self.sprites_group.get_sprites_from_layer(DISKS_lyr): i.set_stick_pos(self.state.get_disk_position(i.disk.num)) i.dirty = 1 def new_trial(self): self.set_board_distance() def clicked(self, res): if self.moving_state == INTERACTIVE: (x, y) = pygame.mouse.get_pos() for i in self.sprites_group.get_sprites_from_layer(DISKS_lyr): if (i.rect.collidepoint(x, y)): r = i.click() if r: self.clicked_sprite = i self.logger.log_pick_disk(self.exp_runner.trial.trial_name, self.trial.current_trial["source"], self.trial.current_trial["target"], self.state.get_board_number(), self.trial.tol.moves_num, i.disk.num ) # self, trial_id, source, target, current_board, move_num, # picked_disk for i in self.sprites_group.get_sprites_from_layer(CTRL_BTN_lyr): if (i.rect.collidepoint(x, y)): # print "Clicked" i.click() def move_mouse(self, res): if self.clicked_sprite is not None: self.clicked_sprite.set_position(pygame.mouse.get_pos()) def unclicked(self, res): already_placed = False # import pdb; pdb.set_trace() if self.clicked_sprite is not None: qq = self.clicked_sprite for i in self.sprites_group.get_sprites_from_layer(STICK_lyr): if (i.rect.colliderect(self.clicked_sprite)): # print "Left on Stick ", i.stick.num if i.stick.not_full() and i.stick.num!=self.state.get_stick_of_disk(self.clicked_sprite.disk.num).num: # print "There is room enough. Number of moves: ", self.moves_num self.state.moveSP(self.clicked_sprite, i) self.clicked_sprite = None self.moves_num += 1 self.sequence_boards.append(self.state.get_board_number()) self.refresh_indicators() # if self.state.get_board_number() == self.goal_num: # print "GANASTE" already_placed = True self.logger.log_release_disk(self.exp_runner.trial.trial_name, self.trial.current_trial["source"], self.trial.current_trial["target"], self.state.get_board_number(), self.trial.tol.moves_num, qq.disk.num, True ) return # if not already_placed: self.clicked_sprite.set_stick_pos() self.clicked_sprite = None self.logger.log_release_disk(self.exp_runner.trial.trial_name, self.trial.current_trial["source"], self.trial.current_trial["target"], self.state.get_board_number(), self.trial.tol.moves_num, qq.disk.num, False ) if self.moving_state == INTERACTIVE: (x, y) = pygame.mouse.get_pos() for i in self.sprites_group.get_sprites_from_layer(CTRL_BTN_lyr): if (i.rect.collidepoint(x, y)): i.release_click() elif self.moving_state == PASSIVE: self.show_messages() elif self.moving_state == FEEDBACK: self.show_messages(False) def run(self): #~ import pdb; pdb.set_trace() self.running = True self.set_events() self.mainLoop() def end_game(self, ev=None): self.logger.log_message("end game") self.logger.close() self.running = False def mainLoop(self): # print "MainLoop" pygame.display.flip() # pygame.image.save(out,fname+".tga") while self.running: self.event_handler.handle() # dt = self.clock.tick(30) dt = self.clock.tick(60) # self.trial.tic() #self.tweener.update(dt / 1000.0) self.sprites_group.draw(self.screen) pygame.display.flip()