class BoidLayer(ScrollableLayer): """Where the boids fly. """ is_event_handler = True def __init__(self, how_many): super(BoidLayer, self).__init__() self.how_many = how_many self.manager = ScrollingManager() self.manager.add(self) self.active = None self.blackboard = blackboard.Blackboard() self.boids = None def makeBoids(self): boids = [] for x in xrange(int(self.how_many)): boid = Boid(self.blackboard) boid.position = (random.randint(0, 200), random.randint(0, 200)) boid.rotation = random.randint(1, 360) self.add(boid) boids.append(boid) return boids def on_enter(self): """Code to run when the Layer enters the scene. """ super(BoidLayer, self).on_enter() self.boids = self.makeBoids() self.manager.set_focus(0, 0)
def __init__(self, how_many): super(BoidLayer, self).__init__() self.how_many = how_many self.manager = ScrollingManager() self.manager.add(self) self.active = None self.blackboard = blackboard.Blackboard() self.boids = None
def __init__(self, track, cars): Scene.__init__(self) # This is set to true once countdown is complete. self.started = False self.player_finished = False self.results = [] self.track_layer = ScrollableLayer() self.track_layer.px_width = track.get_size()[0] self.track_layer.px_height = track.get_size()[1] self.track_layer.add(track) self.track = track self.cars = cars self.cars_layer = ScrollableLayer() self.scroller = ScrollingManager() self.scroller.add(self.track_layer, z=-1) self.scroller.add(self.cars_layer) num_player_cars = 0 self.stats = {} # define start grid i = 0 grid = track.get_start() for car in self.cars: # Add the car to the cars layer. self.cars_layer.add(car) # Reset the car's state. car.reset() car.resume_sounds() # Set the car's position. car.position = grid[i][0] car.rotation = grid[i][1] i += 1 # Add the track to the car car.track = track if isinstance(car, PlayerCar): num_player_cars += 1 self.scroller.set_focus(*car.position) self.player_car = car self.stats[car] = Stats(car) assert num_player_cars == 1 self.hud = HUD(self.track.get_laps()) self.add(self.scroller, z=0) self.add(self.hud, z=1) self.menu = None self.add_traffic_lights() self.scroller.is_event_handler = True self.scroller.on_key_press = self.on_key_press
class Race(Scene): def __init__(self, track, cars): Scene.__init__(self) # This is set to true once countdown is complete. self.started = False self.player_finished = False self.results = [] self.track_layer = ScrollableLayer() self.track_layer.px_width = track.get_size()[0] self.track_layer.px_height = track.get_size()[1] self.track_layer.add(track) self.track = track self.cars = cars self.cars_layer = ScrollableLayer() self.scroller = ScrollingManager() self.scroller.add(self.track_layer, z=-1) self.scroller.add(self.cars_layer) num_player_cars = 0 self.stats = {} # define start grid i = 0 grid = track.get_start() for car in self.cars: # Add the car to the cars layer. self.cars_layer.add(car) # Reset the car's state. car.reset() car.resume_sounds() # Set the car's position. car.position = grid[i][0] car.rotation = grid[i][1] i += 1 # Add the track to the car car.track = track if isinstance(car, PlayerCar): num_player_cars += 1 self.scroller.set_focus(*car.position) self.player_car = car self.stats[car] = Stats(car) assert num_player_cars == 1 self.hud = HUD(self.track.get_laps()) self.add(self.scroller, z=0) self.add(self.hud, z=1) self.menu = None self.add_traffic_lights() self.scroller.is_event_handler = True self.scroller.on_key_press = self.on_key_press def on_key_press(self, symbol, modifier): if not self.player_finished and symbol == key.ESCAPE: self.menu = MenuLayer(InGameMenu) self.add(self.menu, z=100) return True def remove_menu(self): if self.menu is not None: self.remove(self.menu) self.menu = None def add_traffic_lights(self): lights = TrafficLights() lights.image_anchor_y = 0 lights.x = director.window.width / 2 origin_y = director.window.height target_y = director.window.height - lights.image.height lights.y = origin_y self.add(lights, name='traffic_lights', z=100) lights.do( AccelDeccel(MoveTo((lights.x, target_y), 2)) + (Delay(1) + CallFunc(lights.shift_overlay)) * TrafficLights.NUM_LIGHTS + CallFunc(self.start) + Delay(1.5) + MoveTo((lights.x, origin_y), 0.3) + CallFunc(self.remove, lights)) def update(self, dt): """Updates all the cars once the race has started.""" for car in self.cars: # update the car car.update(dt) if car is not self.player_car: # Change engine sound accordingly. car.move_sound_relative(self.player_car.position) # Create a short-named reference. stats = self.stats[car] # update checkpoints checkpoint_stage = self.track.get_checkpoint_stage_at(car.position) next_checkpoint_stage = (stats.last_checkpoint_stage + 1) % 3 if checkpoint_stage == next_checkpoint_stage: # Car changed checkpoint stage and is driving in the right # direction. if checkpoint_stage == 2: stats.checkpoints += 1 elif checkpoint_stage <> stats.last_checkpoint_stage and stats.last_checkpoint_stage > -1: # Car changed checkpoint stage and is driving the wrong way. print car, 'WRONG WAY!', stats.last_checkpoint_stage, checkpoint_stage if checkpoint_stage == 1: stats.checkpoints -= 1 stats.last_checkpoint_stage = checkpoint_stage stats.current_lap_time += dt # update laps if stats.checkpoints == self.track.get_checkpoints(): # At finish. stats.checkpoints = 0 # Store the lap time and reset the current lap time. stats.lap_times.append(stats.current_lap_time) stats.current_lap_time = 0 if stats.laps >= self.track.get_laps(): # Stop the car, disabling any controls in the process. print car, 'Finished' car.stop() stats.finished = True self.add_result(stats) else: stats.laps += 1 if isinstance(car, PlayerCar) and not self.player_finished: if stats.finished: # The race is over since the player car finished. self.finish() else: self.hud.update_laps(stats.laps) self.scroller.set_focus(*car.position) # do collision detection # make a copy of cars list to prevent duplicate collision checks cars = self.cars[:] # iterate over all cars for car in self.cars: # remove car from the te list to prevent detecting collision with self cars.remove(car) # iterate over remaining cars for othercar in cars: polygon = car.get_polygon() other_polygon = othercar.get_polygon() if polygon.intersects(other_polygon): self.resolve_collision(car, othercar) def resolve_collision(self, car1, car2): diff_x = abs(car1.x - car2.x) diff_y = abs(car1.y - car2.y) collision = True while collision: if diff_y > diff_x: # resolve collision in y axis if car1.y > car2.y: car1.y += 1 car2.y -= 1 else: car1.y -= 1 car2.y += 1 else: # resolve collision in x axis if car1.x > car2.x: car1.x += 1 car2.x -= 1 else: car1.x -= 1 car2.x += 1 poly1 = car1.get_polygon() poly2 = car2.get_polygon() collision = poly1.intersects(poly2) def add_result(self, stats): """Returns a list with all the Stats instances sorted ascendingly by total lap time.""" assert stats not in self.results self.results.append(stats) print 'RESULTS', self.results def autocomplete_results(self): """Automatically fills in a custom time for all cars that did not finish yet.""" for stats in self.stats.values(): if not stats.finished: assert stats not in self.results stats.total_time = self.results[-1].total_time + 30 stats.finished = True self.results.append(stats) print 'RESULTS', self.results def start(self): self.started = True self.schedule(self.update) def finish(self): """Displays a message explaining the player that he finished. Also automatically progresses to the results screen.""" self.player_finished = True # state.cup.set_results_for_current_track(self.results) player_position = self.results.index(self.stats[self.player_car]) + 1 if player_position == 1: finished_text = 'You won!' elif player_position == len(self.stats): finished_text = 'You finished last' else: finished_text = 'You finished %s' % ( util.ordinal(player_position), ) label = util.Label(text=finished_text, anchor_y='bottom', font_size=40, background=(0, 0, 0, 125)) label.transform_anchor_x = label.width / 2 label.x = director.window.width / 2 - label.width / 2 label.y = director.window.height / 2 self.add(label, z=100) label.scale = 0 label.do( ScaleTo(1, 0.75) + Delay(3) + ScaleTo(0, 0.75) + CallFunc(self.remove, label) + CallFunc(self.show_results)) def show_results(self): self.menu = MenuLayer(ResultsMenu) self.add(self.menu, z=100) self.menu.scale = 0 self.menu.do(ScaleTo(1, 1)) def save_results(self): """Autocompletes this race's results and stores them on the cup object.""" self.autocomplete_results() state.cup.set_results_for_current_track(self.results) def on_exit(self): super(Race, self).on_exit() for car in self.cars: car.pause_sounds() self.track.stop_music()