class App(Tk): def __init__(self, ftimer): Tk.__init__(self) self.sats = Track() self.sats.load_local("data.txt") # to be changed self.sats.add_satellite(7) # achtung, hardcode menu = UserMenu(parent = self) self.config(menu = menu) self.title('SatKit Ground Tracking') self.timer = ftimer self.timer.callback_function = self.redraw self.time_speed = 1 # normal speed self.var = IntVar() self.scale = Scale(self, variable = self.var, from_ = 1, to = 3600, orient = HORIZONTAL, showvalue=0, sliderlength=15, length=400, command=self.set_time_speed) self.date = Label(self) def redraw(self): self.timer.set_speed(self.time_speed) # bad, should be improven,~event self.sats.update_satellites(self.time_speed * Time.TIMER_INTERVAL) #print self.time_speed # recompute "current" time, later,,, self.date.config(text = str(self.timer.current_time)[0:21]) self.date.grid(row = 0, column = 1) self.scale.grid(row = 0, column = 0) self.sats.anim.grid(row = 1, columnspan = 2) self.sats.draw() def set_time_speed(self, secs): self.time_speed = int(secs)
paused = True while paused: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_p: paused = False clock.tick(constants.FRAME_RATE) # fps # update game status and handle game logic car_list.update(track, frame_counter) particles.update(frame_counter) bayes.update(frame_counter) status_bar.update(frame_counter) # update draw buffer track.draw(screen) sprite_list.draw(screen) if draw_viewfield: for car in car_list: car.driver.draw_viewfield(screen) # draw particles particles.draw(screen) bayes.draw(screen) # update screen clock.tick(constants.FRAME_RATE) # fps frame_counter += 1 pygame.display.flip()
class SpaceRacer(): """Represents the game itself""" def __init__(self): """Creates all game objects needed, loads resources, initializes pygame library and sound mixer, sets display mode, etc.""" self.state = STATE_TITLE pygame.mixer.pre_init(buffer=SOUND_BUFFER) pygame.init() self.clock = Clock() self.scr = pygame.display.set_mode(SCREEN_SIZE, VID_MODE_FLAGS) pygame.display.set_caption(WINDOW_CAPTION) pygame.mouse.set_visible(False) LoadingScreen(self.scr).draw() sound_box.init() self.level = GameLevel() self.stats = GameStats(self.scr) self.view_pt = ViewPoint(self.scr) self.stars = Stars(self.scr, self.view_pt) self.track = Track(self.scr, self.view_pt) self.explosions = Explosions(self.scr, self.view_pt) self.ship = Ship(self.scr, self.view_pt, self.explosions) self.asteroids = Asteroids(self.scr, self.view_pt, self.explosions, self.track) self.title_screen = TitleScreen(self.scr, self.view_pt, self.stars) self.level_start_screen = LevelStartScreen(self.scr) self.level_complete_effect = LevelCompleteEffect(self.scr) self.game_over_effect = GameOverEffect(self.scr) self.pause_screen = PauseScreen(self.scr) self.ending_screen = EndingScreen(self.scr) self._init_title() def run(self): """The only public method just runs the game. It starts infinite loop where game objects are updated, drawn and interacts with each other. Also system events are processed.""" while True: self.clock.tick(FRAMERATE) # print(f"FPS: {round(self.clock.get_fps(), 2)}") self._process_events() self._update_objects() self._interact_objects() self._draw_objects() def _init_title(self): self.state = STATE_TITLE self.stats.reset() self.level.restart() self.title_screen.restart() self.title_screen.play_music() def _init_level_starting(self): self.state = STATE_LEVEL_STARTING self.level_start_screen.set_level_number(self.level.get_level()) self.level_start_screen.set_subtitle_text(self.level.get_description()) self.level_start_screen.restart() def _init_level_playing(self): self.state = STATE_LEVEL_PLAYING self.level.play_music() self.view_pt.reset() self.stars.respawn() self.track.set_tile_map(self.level.get_map()) top_limit = (self.track.get_track_height() - self.scr.get_rect().height / 2) bottom_limit = self.scr.get_rect().height / 2 self.view_pt.set_limits(top=top_limit, bottom=bottom_limit) self.explosions.items.empty() self.asteroids.set_spawn_density(self.level.get_asteroids_density()) self.asteroids.respawn(self.level.get_asteroid_spawns()) self.ship.set_speed(self.level.get_ship_speed()) self.ship.set_acceleration(self.level.get_ship_acceleration()) self.ship.restore((0, 0), reset_control=True) def _init_level_finishing(self): self.state = STATE_LEVEL_FINISHING self.stats.increase_score(LEVEL_COMPLETE_PTS) self.level_complete_effect.restart() self.ship.set_autopilot() pygame.mixer.music.fadeout(MUSIC_FADEOUT) def _init_game_over(self): self.state = STATE_GAME_OVER self.game_over_effect.restart() pygame.mixer.music.fadeout(MUSIC_FADEOUT) def _init_ending(self): self.state = STATE_ENDING self.ending_screen.set_score(self.stats.score) self.ending_screen.restart() self.ending_screen.play_music() def _init_pause(self): self.state = STATE_PAUSE self.pause_screen.refresh_background() pygame.mixer.music.pause() def _ship_control(self, key, control_status): """Returns True if the key was a ship direction control key.""" key_processed = True if key == pygame.K_UP: self.ship.moving_up = control_status elif key == pygame.K_DOWN: self.ship.moving_down = control_status elif key == pygame.K_LEFT: self.ship.moving_left = control_status elif key == pygame.K_RIGHT: self.ship.moving_right = control_status elif key == pygame.K_SPACE: self.ship.shooting = control_status else: key_processed = False return key_processed def _process_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if self.state == STATE_TITLE: if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: sys.exit() elif event.key == pygame.K_RETURN: pygame.mixer.music.fadeout(MUSIC_FADEOUT) self._init_level_starting() elif self.state == STATE_PAUSE: if event.type == pygame.KEYDOWN: if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE): self.state = STATE_LEVEL_PLAYING pygame.mixer.music.unpause() elif event.key == pygame.K_RETURN: sys.exit() elif self.state == STATE_LEVEL_PLAYING: if event.type == pygame.KEYDOWN: if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE): self._init_pause() else: self._ship_control(event.key, control_status=True) elif event.type == pygame.KEYUP: self._ship_control(event.key, control_status=False) if self.state == STATE_ENDING: if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: sys.exit() elif event.key == pygame.K_RETURN: self._init_title() def _update_objects(self): if self.state == STATE_TITLE: self.title_screen.update() if self.state == STATE_LEVEL_STARTING: self.level_start_screen.update() if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING, STATE_GAME_OVER): self.view_pt.update() self.stars.update() self.track.update() self.asteroids.update() self.ship.update() self.explosions.update() if self.state == STATE_LEVEL_FINISHING: self.level_complete_effect.update() if self.state == STATE_GAME_OVER: self.game_over_effect.update() if self.state == STATE_ENDING: self.ending_screen.update() def _crossed_finish_line(self): finish_line_y = (self.track.get_track_height() - self.scr.get_rect().height / 2) return self.ship.y > finish_line_y def _interact_objects(self): if self.state == STATE_LEVEL_STARTING: if self.level_start_screen.finished(): self._init_level_playing() elif self.state == STATE_LEVEL_PLAYING: if self.stats.game_over(): self._init_game_over() elif self._crossed_finish_line(): self._init_level_finishing() elif self.ship.status == SHIP_STATUS_NORMAL: self._check_collisions() elif self.ship.status == SHIP_STATUS_INACTIVE: self._ship_restore() elif self.state == STATE_LEVEL_FINISHING: if self.level_complete_effect.finished(): if self.level.last_level(): self._init_ending() else: self.level.next_level() self._init_level_starting() elif self.state == STATE_GAME_OVER: if self.game_over_effect.finished(): self._init_title() def _draw_objects(self): if self.state == STATE_TITLE: self.title_screen.draw() if self.state == STATE_PAUSE: self.pause_screen.draw() if self.state == STATE_LEVEL_STARTING: self.level_start_screen.draw() if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING, STATE_GAME_OVER): self.scr.blit(self.level.get_background(), (0, 0)) self.stars.draw() self.track.draw() self.asteroids.draw() self.ship.draw() self.explosions.draw() self.stats.draw() if self.state == STATE_LEVEL_FINISHING: self.level_complete_effect.draw() if self.state == STATE_GAME_OVER: self.game_over_effect.draw() if self.state == STATE_ENDING: self.ending_screen.draw() pygame.display.flip() def _ship_explode(self, collide_point=None): """collide_point is a tuple of absolute coordinates: (x, y)""" self.stats.lost_life() self.ship.explode(collide_point) def _ship_restore(self): restore_x, restore_y = self.ship.get_center() borders = self.track.get_track_borders(restore_y) if borders: restore_x = mean(borders) if self.ship.restore((restore_x, restore_y)): self.asteroids.explode_nearest(self.ship.get_center()) def _check_ship_penalty(self): borders = self.track.get_track_borders(self.ship.get_center()[1]) if borders: left = self.ship.x right = left + self.ship.rect.width if right < borders[0] or left > borders[1]: self._ship_explode() return True return False def _check_collisions(self): collide_point = self.track.collidemask(self.ship.mask, self.ship.rect) if collide_point: self._ship_explode(collide_point) return True collide_point = self.asteroids.collidemask(self.ship.mask, self.ship.rect, explode=True) if collide_point: self._ship_explode(collide_point) return True if self.ship.laser.shooting(): if self.asteroids.collidemask(self.ship.laser.mask, self.ship.laser.rect, explode=True): self.stats.increase_score(ASTEROID_HIT_PTS) return self._check_ship_penalty()
class Simulator(pyglet.window.Window): def __init__(self, *args, settings=None, carnum=10, width=960, height=540, vsync=True, **kwargs): config = pyglet.gl.Config(sample_buffers=1, samples=1, depth_size=16, double_buffer=True) super().__init__(width=width, height=height, config=config, resizable=True, vsync=vsync) self.keystate = key.KeyStateHandler() self.push_handlers(self.keystate) self.settings = defaultdict(bool) if type(settings) == dict: self.settings.update(settings) self.init_speed = self.settings['speed'] if type( self.settings['speed']) == int else 25 self.carnum = (carnum + 1) // 2 * 2 # need even number self.carnum = carnum self.cars = [] self.car = Car( sensors=self.settings['sensors'], human=True) # will be deleted later if simulation starts self.carline_colours = tuple() self.track = Track() self.car.put_on_track(self.track) self.generation = 0 self.cars_pos_vbo = VertexBufferObject(self.carnum * 64, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW) self.cars_col_vbo = VertexBufferObject(self.carnum * 96, GL_ARRAY_BUFFER, GL_STATIC_DRAW) self.time = 0 self.fps = pyglet.clock.ClockDisplay() self.times = defaultdict(list) self.counter = 0 self.setup_labels() self.x = 0 self.y = 0 self.scale = 1 pyglet.clock.schedule_interval(self.update, 1.0 / 60) def setup_labels(self): self.main_label = pyglet.text.Label(text="", x=10, y=self.height - 20) self.maintimes_label = pyglet.text.Label(text="", x=10, y=self.height - 40, font_name="Lucida Console", font_size=10) self.cartimes_label = pyglet.text.Label(text="", x=10, y=self.height - 60, font_name="Lucida Console", font_size=10) def start(self, makecars=False): if makecars: self.cars = [ Car(sensors=self.settings['sensors']) for i in range(self.carnum) ] self.carline_colours = sum((car.line_colours for car in self.cars), ()) self.cars_col_vbo.set_data(Vec(*self.carline_colours)) self.car = self.cars[0] for car in self.cars: car.put_on_track(self.track) car.accelerate(self.init_speed) def evolve(self): self.generation += 1 for car in self.cars[1:]: car.driver.learn_from(self.cars[0].driver) car.driver.randomize() return #self.maintimes_label.text = "Generation: %d" % self.generation cars = sorted(self.cars, key=operator.attrgetter('section_idx', 'time'), reverse=True) if cars[1:2] and cars[1].section_idx < 1: #print("Don't have at least two good specimen, randomizing") [car.driver.randomize() for car in self.cars] return pass best = cars[0].driver runnerup = cars[1].driver to_mutate = (self.carnum - 2) // 2 #print("best section: %d, runnerup section: %d" % (best.section_idx, runnerup.section_idx)) # something's wrong here, need to rethink for i, pair in enumerate(zip(self.cars[2::2], self.cars[3::2])): severity = 0.25 * i / to_mutate chance = 1 - i / to_mutate pair[0].driver.learn_from(best, mutate=i, chance=chance, severity=severity) pair[1].driver.learn_from(runnerup, mutate=i, chance=chance, severity=severity) #print("cars[0] == best: %s" % (self.cars[0].driver.network.layers[1].neurons[0].weights == best.driver.network.layers[1].neurons[0].weights)) #print("cars[0] %d, best: %d" % (id(self.cars[0].driver.network.layers[1].neurons[0].weights), id(best.driver.network.layers[1].neurons[0].weights))) #print("copied and mutated!") def set_avg_time(self, cat, time, limit=10): self.times[cat].append(time) if len(self.times[cat]) > limit: self.times[cat].pop(0) def get_avg_time(self, cat): if len(self.times[cat]): return sum(self.times[cat]) / len(self.times[cat]) else: return 0 def set_and_get_avg_time(self, cat, time, limit=10): self.set_avg_time(cat, time, limit) return self.get_avg_time(cat) def update(self, dt): dt = min( dt, 1 / 30 ) # slow down time instead of "dropping" frames and having quick jumps in space #dt = 1/40 self.time += dt self.main_label.text = "Time: %.3f. Generation: %d" % (self.time, self.generation) for key in self.keystate: if self.keystate[key]: self.dispatch_event('on_key_press', key, False) t1 = time.time() if len(self.cars): for car in self.cars: car.update(dt) if all(car.collided for car in self.cars): self.evolve() self.start() return s = [car for car in self.cars if not car.collided] leader = sorted(s, key=operator.attrgetter('section_idx'))[-1] #leader = sorted(self.cars, key=operator.attrgetter('section_idx'))[-1] if self.car.section_idx < leader.section_idx: self.car = leader else: self.car.update(dt) t2 = time.time() if not self.settings['nofollow']: self.x = self.car.x self.y = self.car.y self.draw() t3 = time.time() if self.settings['timings'] or self.settings['manual']: drawtime = 1000 * self.set_and_get_avg_time('draw', t3 - t2) cardraw = 1000 * self.get_avg_time('cardraw') coords = 1000 * self.get_avg_time('lines') drawcall = 1000 * self.get_avg_time('drawcall') updatetime = 1000 * self.set_and_get_avg_time('update', t2 - t1) sensors = 1000 * self.get_avg_time('sensors') extra = 1000 * self.get_avg_time('extra') percar = 1000 * updatetime if not self.settings['manual']: #percar /= sum(not car.collided for car in self.cars) percar /= len(self.cars) cardrawdetail = "(cars=%.2fms:coords:%.2fms,draw=%.2fms)" % ( cardraw, coords, drawcall) else: cardrawdetail = "" self.maintimes_label.text = "dt=%2dms,draw=%2dms%s,upd=%04.1fms(%.2fus/car)" % ( 1000 * dt, drawtime, cardrawdetail, updatetime, percar) def setup2d_init(self): glClear(GL_COLOR_BUFFER_BIT) #glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vec(0,0,0,1)) glColor3ub(255, 255, 255) glViewport(0, 0, self.width, self.height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluOrtho2D(0, self.width, 0, self.height) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def setup2d_camera(self): glMatrixMode(GL_PROJECTION) glLoadIdentity() gluOrtho2D(self.scale * -self.width / 2 + self.x, self.scale * self.width / 2 + self.x, self.scale * -self.height / 2 + self.y, self.scale * self.height / 2 + self.y) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def draw(self): self.clear() self.setup2d_init() self.fps.draw() self.draw_labels() self.setup2d_camera() self.track.draw() t1 = time.time() self.draw_cars() t2 = time.time() self.set_avg_time('cardraw', t2 - t1) def draw_cars(self): glLoadIdentity() t1 = time.time() if len(self.cars): if cmodule: pos = ((car.x, car.y, car.rot) for car in self.cars) self.coords = cmodule.car_lines(pos, self.carnum) else: coords = sum((car.linecoords for car in self.cars), ()) self._coords = np.array( coords, dtype=GLfloat) # must keep the array ref in python self.coords = self._coords.ctypes.data #self.coords = Vec(*coords) t2 = time.time() self.cars_col_vbo.bind() glColorPointer(3, GL_FLOAT, 0, self.cars_col_vbo.ptr) self.cars_pos_vbo.set_data(self.coords) self.cars_pos_vbo.bind() glVertexPointer(2, GL_FLOAT, 0, self.cars_pos_vbo.ptr) glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_COLOR_ARRAY) glDrawArrays(GL_LINES, 0, self.carnum * 16) glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_VERTEX_ARRAY) self.cars_col_vbo.unbind() self.cars_pos_vbo.unbind() else: t2 = time.time() self.car.draw() t3 = time.time() if self.settings['manual']: self.car.draw_section() self.car.draw_points() t4 = time.time() if self.settings['cameras']: self.car.draw_sensors() t5 = time.time() self.set_avg_time('lines', t2 - t1) self.set_avg_time('drawcall', t3 - t2) self.set_avg_time('extra', t4 - t3) self.set_avg_time('sensors', t5 - t4) def draw_labels(self): self.main_label.draw() self.maintimes_label.draw() def on_key_press(self, symbol, modifier): if symbol == key.ESCAPE: self.close() elif symbol == key.LEFT: self.car.steering = -math.pi / 4 elif symbol == key.RIGHT: self.car.steering = math.pi / 4 elif symbol == key.UP: self.car.accelerate(2) elif symbol == key.DOWN: self.car.accelerate(-2) elif symbol == key.SPACE: if self.car.speed >= 0: self.car.speed = max(0, self.car.speed - 8) else: self.car.speed = min(0, self.car.speed + 8) elif symbol == key.W: self.y += 10 elif symbol == key.S: self.y -= 10 elif symbol == key.A: self.x -= 10 elif symbol == key.D: self.x += 10 elif symbol == key.E: if self.scale > 0.2: self.scale -= 0.1 elif symbol == key.Q: if self.scale < 3: self.scale += 0.1 elif symbol == key.C: self.car.check_collision() self.keystate[symbol] = False elif symbol == key.R: if len(self.cars): self.start() return self.car.put_on_track(self.track) elif symbol == key.N: self.car.change_section(self.car.section_idx + 1) self.keystate[symbol] = False elif symbol == key.P: self.car.change_section(self.car.section_idx - 1) self.keystate[symbol] = False def on_key_release(self, symbol, modifier): if symbol in [key.LEFT, key.RIGHT]: self.car.steering = 0
def main(): """ Main function """ # Load pygame.init() path = os.path.abspath('.') + '/' screen = pygame.display.set_mode((800, 600)) font = pygame.font.Font(path + "arial.ttf", 24) quit_game = False key_up = False key_down = False key_left = False key_right = False key_z = False key_q = False key_s = False key_d = False car = Car(60, 300, path + "images/car.png") car2 = Car(500, 300, path + "images/car-alt.png") track = Track() dt = 60 / 1000 clock = pygame.time.Clock() while not quit_game: # Inputs for event in pygame.event.get(): if event.type == pygame.QUIT: quit_game = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: quit_game = True if event.key == pygame.K_UP: key_up = True if event.key == pygame.K_DOWN: key_down = True if event.key == pygame.K_LEFT: key_left = True if event.key == pygame.K_RIGHT: key_right = True if event.key == pygame.K_w: key_z = True if event.key == pygame.K_a: key_q = True if event.key == pygame.K_s: key_s = True if event.key == pygame.K_d: key_d = True if event.type == pygame.KEYUP: if event.key == pygame.K_UP: key_up = False if event.key == pygame.K_DOWN: key_down = False if event.key == pygame.K_LEFT: key_left = False if event.key == pygame.K_RIGHT: key_right = False if event.key == pygame.K_w: key_z = False if event.key == pygame.K_a: key_q = False if event.key == pygame.K_s: key_s = False if event.key == pygame.K_d: key_d = False # Update # - Player 1 if key_up: car.accelerate() if key_left: car.turn_left(dt) if key_right: car.turn_right(dt) car.update(dt) # - Player 2 if key_z: car2.accelerate() if key_q: car2.turn_left(dt) if key_d: car2.turn_right(dt) car2.update(dt) # Draw screen.fill((0, 0, 0)) track.draw(screen) car.draw(screen) car2.draw(screen) pygame.display.update() dt = clock.tick(60) / 1000