class NPC: def __init__(self, renderer, factory, json_data): self.dialog_timer = Timer(10000) self.close_dialog_timer = Timer(10000) self.db = DataBase() self.renderer = renderer self.factory = factory data = json.loads(json_data) self.name = data["name"] self.start_pos = data["start_pos"] self.npc_data = self.db.get_npc(self.name) self.level = self.npc_data["level"] self.quest = self.npc_data["quest"] self.sprite_size = 128 self.position = [0, 0] self.movement = [0, 0] self.moving = False self.npc_sprites = [ RESOURCES.get_path("{0}_standing.png".format(self.name)), RESOURCES.get_path("{0}_walking.png".format(self.name)) ] self.sprite_sheets = {} self.sprites = [] self.facing = Facing.LEFT_DOWN self.last_facing = self.facing self.motion_type = MotionType.STANDING self.last_motion_type = self.motion_type self.frame_index = 0 self.walk_frames = 60 self.move_rate = 100 self.init_sprite_sheet() self.dialogs = self.db.get_npc_dialog(self.name) self.dialog_box = None self.dialog_sprites = [] self.text = None def init_sprite_sheet(self): for motion_type in range(MotionType.COUNT): self.load_image(self.npc_sprites[motion_type], motion_type) def load_image(self, file_path, motion_type): sprite_sheets = self.sprite_sheets.get(file_path) if not sprite_sheets: sprite_surface = self.factory.from_image(file_path) self.sprite_sheets[motion_type] = sprite_surface def update(self, position, elapsed_time): self.position = position self.sprites.clear() self.frame_index += 1 if self.frame_index == (self.sprite_sheets[self.motion_type].size[0] / self.sprite_size): self.frame_index = 0 if not self.moving: move = dice(self.move_rate) if move[0] == self.move_rate - 1: self.moving = True self.walk_frames = 60 facing = dice(Facing.COUNT - 1) self.facing = facing[0] if self.moving: if self.walk_frames: self.motion_type = MotionType.WALKING if self.facing == 0: self.movement[0] -= 2 self.movement[1] += 1 self.facing = Facing.LEFT_DOWN elif self.facing == 1: self.movement[1] += 1 self.facing = Facing.DOWN elif self.facing == 2: self.movement[0] += 2 self.movement[1] += 1 self.facing = Facing.RIGHT_DOWN elif self.facing == 3: self.movement[0] += 2 self.facing = Facing.RIGHT elif self.facing == 4: self.movement[0] += 2 self.movement[1] -= 1 self.facing = Facing.RIGHT_UP elif self.facing == 5: self.movement[1] -= 1 self.facing = Facing.UP elif self.facing == 6: self.movement[0] -= 2 self.movement[1] -= 1 self.facing = Facing.LEFT_UP elif self.facing == 7: self.movement[0] -= 2 self.facing = Facing.LEFT self.walk_frames -= 1 else: self.moving = False self.motion_type = MotionType.STANDING x = int((int(self.start_pos[0]) + self.position[0] + self.movement[0]) - (self.sprite_size / 2)) y = int((int(self.start_pos[1]) + self.position[1] + self.movement[1]) - (self.sprite_size / 2)) self.position = x, y sprite_sheet = self.sprite_sheets[self.motion_type] sprite_crop = [self.frame_index * self.sprite_size, self.facing * self.sprite_size, self.sprite_size, self.sprite_size] sprite = sprite_sheet.subsprite(sprite_crop) sprite.position = self.position self.sprites.append(sprite) """ renderer = self.renderer src_rect = SDL_Rect() src_rect.x = frame_index * sprite_size src_rect.y = facing * sprite_size src_rect.w = sprite_size src_rect.h = sprite_size dest_rect = SDL_Rect() dest_rect.x = x dest_rect.y = y dest_rect.w = sprite_size dest_rect.h = sprite_size SDL_RenderCopy(renderer, sprite.texture, src_rect, dest_rect) """ def get_sprites(self): return self.sprites def dialog_update(self): self.dialog_timer.update() self.close_dialog_timer.update() if self.dialog_timer.check(): self.dialog_timer.reset() self.close_dialog_timer.activate() self.create_dialog() if self.close_dialog_timer.check(): self.close_dialog_timer.reset() self.dialog_timer.activate() self.dialog_box = None self.dialog_sprites.clear() def create_dialog(self): self.text = dice(len(self.dialogs) - 1) name = self.dialogs[self.text[0]]['npc'] text = self.dialogs[self.text[0]]['text'] message = {0: "{0}:".format(name)} max_chars = 24 i = 1 for j in range(0, len(text), max_chars): message[i] = text[j:j + max_chars] i += 1 self.dialog_box = DialogBox(self.factory, font_size=32, fg_color=Colors.WHITE, bg_color=Colors.BLACK, font_name="04B_20__.TTF", text=message, position=self.position, renderer=self.renderer) sprites = self.dialog_box.get_sprites() for sprite in sprites: self.dialog_sprites.append(sprite)
class Menu: def __init__(self, window, world, renderer, factory): self.window = window self.renderer = renderer self.world = world self.factory = factory self.rsystem = factory.create_sprite_render_system(window) self.menu_bg = RESOURCES.get_path("menu_bg.png") self.menu_cursor = RESOURCES.get_path("menu_cursor.png") self.running = True self.position = 460, 340 self.cursor_start_position = 370, 330 self.cursor_position = 0 self.cursor_sprite_size = 32 self.background_sprite = self.factory.from_image(self.menu_bg) self.cursor_sprite = self.factory.from_image(self.menu_cursor) self.text = {0: "START", 1: "OPTIONS", 2: "EXIT"} self.dialog = DialogBox(self.factory, font_size=32, fg_color=Colors.WHITE, bg_color=Colors.BLACK, font_name="04B_20__.TTF", text=self.text, position=self.position, renderer=self.renderer) self.sprites = [self.background_sprite] sprites = self.dialog.get_sprites() for sprite in sprites: self.sprites.append(sprite) self.sprites.append(self.cursor_sprite) def __del__(self): SDL_Quit() def update(self, elapsed_time): self.cursor_sprite.position = self.cursor_start_position[0], self.cursor_start_position[1] \ + self.cursor_position * self.cursor_sprite_size def run(self): menu_input = Input() last_update_time = SDL_GetTicks() # units.MS while self.running: start_time = SDL_GetTicks() # units.MS menu_input.begin_new_frame() menu_events = get_events() for event in menu_events: if event.type == SDL_KEYDOWN: menu_input.key_down_event(event) elif event.type == SDL_KEYUP: menu_input.key_up_event(event) elif event.type == SDL_QUIT: self.running = False break # Exit if menu_input.was_key_pressed(SDLK_ESCAPE): self.running = False # Move the cursor elif menu_input.was_key_pressed(SDLK_UP): if self.cursor_position != 0: self.cursor_position -= 1 elif menu_input.was_key_pressed(SDLK_DOWN): if self.cursor_position != 2: self.cursor_position += 1 # Select option elif menu_input.was_key_pressed(SDLK_RETURN): self.running = False if self.cursor_position == 0: self.launch_game() current_time = SDL_GetTicks() # units.MS elapsed_time = current_time - last_update_time # units.MS self.update(min(elapsed_time, MAX_FRAME_TIME)) last_update_time = current_time self.renderer.render(self.sprites) # This loop lasts 1/60th of a second, or 1000/60th ms ms_per_frame = 1000 // FPS # units.MS elapsed_time = SDL_GetTicks() - start_time # units.MS if elapsed_time < ms_per_frame: SDL_Delay(ms_per_frame - elapsed_time) def launch_game(self): game = Game(self.world, self.window, self.renderer, self.factory) game.run() self.running = True self.run()