CrashOverrideX
Sealing v8.1 Subjectively Aware Standard for Hugging Face. Clean Model & Knowledge release.
a3e5f70 | from settings import * | |
| from game_data import * | |
| from pytmx.util_pygame import load_pygame | |
| from os.path import join | |
| from random import randint | |
| from sprites import Sprite, AnimatedSprite, MonsterPatchSprite, BorderSprite, CollidableSprite, TransitionSprite | |
| from entities import Player, Character | |
| from groups import AllSprites | |
| from dialog import DialogTree | |
| from monster_index import MonsterIndex | |
| from battle import Battle | |
| from timer import Timer | |
| from evolution import Evolution | |
| from support import * | |
| from monster import Monster | |
| class Game: | |
| # general | |
| def __init__(self): | |
| pygame.init() | |
| self.display_surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) | |
| pygame.display.set_caption('Monster Hunter') | |
| self.clock = pygame.time.Clock() | |
| self.encounter_timer = Timer(2000, func = self.monster_encounter) | |
| # player monsters | |
| self.player_monsters = { | |
| 0: Monster('Ivieron', 32), | |
| 1: Monster('Atrox', 15), | |
| 2: Monster('Cindrill', 16), | |
| 3: Monster('Atrox', 10), | |
| 4: Monster('Sparchu', 11), | |
| 5: Monster('Gulfin', 9), | |
| 6: Monster('Jacana', 10), | |
| } | |
| for monster in self.player_monsters.values(): | |
| monster.xp += randint(0,monster.level * 100) | |
| self.test_monsters = { | |
| 0: Monster('Finsta', 15), | |
| 1: Monster('Pouch', 13), | |
| 2: Monster('Larvea', 12), | |
| } | |
| # groups | |
| self.all_sprites = AllSprites() | |
| self.collision_sprites = pygame.sprite.Group() | |
| self.character_sprites = pygame.sprite.Group() | |
| self.transition_sprites = pygame.sprite.Group() | |
| self.monster_sprites = pygame.sprite.Group() | |
| # transition / tint | |
| self.transition_target = None | |
| self.tint_surf = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT)) | |
| self.tint_mode = 'untint' | |
| self.tint_progress = 0 | |
| self.tint_direction = -1 | |
| self.tint_speed = 600 | |
| self.import_assets() | |
| self.setup(self.tmx_maps['world'], 'house') | |
| self.audio['overworld'].play(-1) | |
| # overlays | |
| self.dialog_tree = None | |
| self.monster_index = MonsterIndex(self.player_monsters, self.fonts, self.monster_frames) | |
| self.index_open = False | |
| self.battle = None | |
| self.evolution = None | |
| def import_assets(self): | |
| self.tmx_maps = tmx_importer('..', 'data', 'maps') | |
| self.overworld_frames = { | |
| 'water': import_folder('..', 'graphics', 'tilesets', 'water'), | |
| 'coast': coast_importer(24, 12, '..', 'graphics', 'tilesets', 'coast'), | |
| 'characters': all_character_import('..', 'graphics', 'characters') | |
| } | |
| self.monster_frames = { | |
| 'icons': import_folder_dict('..', 'graphics', 'icons'), | |
| 'monsters': monster_importer(4,2,'..', 'graphics', 'monsters'), | |
| 'ui': import_folder_dict('..', 'graphics', 'ui'), | |
| 'attacks': attack_importer('..', 'graphics', 'attacks') | |
| } | |
| self.monster_frames['outlines'] = outline_creator(self.monster_frames['monsters'], 4) | |
| self.fonts = { | |
| 'dialog': pygame.font.Font(join('..', 'graphics', 'fonts', 'PixeloidSans.ttf'), 30), | |
| 'regular': pygame.font.Font(join('..', 'graphics', 'fonts', 'PixeloidSans.ttf'), 18), | |
| 'small': pygame.font.Font(join('..', 'graphics', 'fonts', 'PixeloidSans.ttf'), 14), | |
| 'bold': pygame.font.Font(join('..', 'graphics', 'fonts', 'dogicapixelbold.otf'), 20), | |
| } | |
| self.bg_frames = import_folder_dict('..', 'graphics', 'backgrounds') | |
| self.start_animation_frames = import_folder('..', 'graphics', 'other', 'star animation') | |
| self.audio = audio_importer('..', 'audio') | |
| def setup(self, tmx_map, player_start_pos): | |
| # clear the map | |
| for group in (self.all_sprites, self.collision_sprites, self.transition_sprites, self.character_sprites): | |
| group.empty() | |
| # terrain | |
| for layer in ['Terrain', 'Terrain Top']: | |
| for x, y, surf in tmx_map.get_layer_by_name(layer).tiles(): | |
| Sprite((x * TILE_SIZE, y * TILE_SIZE), surf, self.all_sprites, WORLD_LAYERS['bg']) | |
| # water | |
| for obj in tmx_map.get_layer_by_name('Water'): | |
| for x in range(int(obj.x), int(obj.x + obj.width), TILE_SIZE): | |
| for y in range(int(obj.y), int(obj.y + obj.height), TILE_SIZE): | |
| AnimatedSprite((x,y), self.overworld_frames['water'], self.all_sprites, WORLD_LAYERS['water']) | |
| # coast | |
| for obj in tmx_map.get_layer_by_name('Coast'): | |
| terrain = obj.properties['terrain'] | |
| side = obj.properties['side'] | |
| AnimatedSprite((obj.x, obj.y), self.overworld_frames['coast'][terrain][side], self.all_sprites, WORLD_LAYERS['bg']) | |
| # objects | |
| for obj in tmx_map.get_layer_by_name('Objects'): | |
| if obj.name == 'top': | |
| Sprite((obj.x, obj.y), obj.image, self.all_sprites, WORLD_LAYERS['top']) | |
| else: | |
| CollidableSprite((obj.x, obj.y), obj.image, (self.all_sprites, self.collision_sprites)) | |
| # transition objects | |
| for obj in tmx_map.get_layer_by_name('Transition'): | |
| TransitionSprite((obj.x, obj.y), (obj.width, obj.height), (obj.properties['target'], obj.properties['pos']), self.transition_sprites) | |
| # collision objects | |
| for obj in tmx_map.get_layer_by_name('Collisions'): | |
| BorderSprite((obj.x, obj.y), pygame.Surface((obj.width, obj.height)), self.collision_sprites) | |
| # grass patches | |
| for obj in tmx_map.get_layer_by_name('Monsters'): | |
| MonsterPatchSprite((obj.x, obj.y), obj.image, (self.all_sprites, self.monster_sprites), obj.properties['biome'], obj.properties['monsters'], obj.properties['level']) | |
| # entities | |
| for obj in tmx_map.get_layer_by_name('Entities'): | |
| if obj.name == 'Player': | |
| if obj.properties['pos'] == player_start_pos: | |
| self.player = Player( | |
| pos = (obj.x, obj.y), | |
| frames = self.overworld_frames['characters']['player'], | |
| groups = self.all_sprites, | |
| facing_direction = obj.properties['direction'], | |
| collision_sprites = self.collision_sprites) | |
| else: | |
| Character( | |
| pos = (obj.x, obj.y), | |
| frames = self.overworld_frames['characters'][obj.properties['graphic']], | |
| groups = (self.all_sprites, self.collision_sprites, self.character_sprites), | |
| facing_direction = obj.properties['direction'], | |
| character_data = TRAINER_DATA[obj.properties['character_id']], | |
| player = self.player, | |
| create_dialog = self.create_dialog, | |
| collision_sprites = self.collision_sprites, | |
| radius = obj.properties['radius'], | |
| nurse = obj.properties['character_id'] == 'Nurse', | |
| notice_sound = self.audio['notice']) | |
| # dialog system | |
| def input(self): | |
| if not self.dialog_tree and not self.battle: | |
| keys = pygame.key.get_just_pressed() | |
| if keys[pygame.K_SPACE]: | |
| for character in self.character_sprites: | |
| if check_connections(100, self.player, character): | |
| self.player.block() | |
| character.change_facing_direction(self.player.rect.center) | |
| self.create_dialog(character) | |
| character.can_rotate = False | |
| if keys[pygame.K_RETURN]: | |
| self.index_open = not self.index_open | |
| self.player.blocked = not self.player.blocked | |
| def create_dialog(self, character): | |
| if not self.dialog_tree: | |
| self.dialog_tree = DialogTree(character, self.player, self.all_sprites, self.fonts['dialog'], self.end_dialog) | |
| def end_dialog(self, character): | |
| self.dialog_tree = None | |
| if character.nurse: | |
| for monster in self.player_monsters.values(): | |
| monster.health = monster.get_stat('max_health') | |
| monster.energy = monster.get_stat('max_energy') | |
| self.player.unblock() | |
| elif not character.character_data['defeated']: | |
| self.audio['overworld'].stop() | |
| self.audio['battle'].play(-1) | |
| self.transition_target = Battle( | |
| player_monsters = self.player_monsters, | |
| opponent_monsters = character.monsters, | |
| monster_frames = self.monster_frames, | |
| bg_surf = self.bg_frames[character.character_data['biome']], | |
| fonts = self.fonts, | |
| end_battle = self.end_battle, | |
| character = character, | |
| sounds = self.audio) | |
| self.tint_mode = 'tint' | |
| else: | |
| self.player.unblock() | |
| self.check_evolution() | |
| # transition system | |
| def transition_check(self): | |
| sprites = [sprite for sprite in self.transition_sprites if sprite.rect.colliderect(self.player.hitbox)] | |
| if sprites: | |
| self.player.block() | |
| self.transition_target = sprites[0].target | |
| self.tint_mode = 'tint' | |
| def tint_screen(self, dt): | |
| if self.tint_mode == 'untint': | |
| self.tint_progress -= self.tint_speed * dt | |
| if self.tint_mode == 'tint': | |
| self.tint_progress += self.tint_speed * dt | |
| if self.tint_progress >= 255: | |
| if type(self.transition_target) == Battle: | |
| self.battle = self.transition_target | |
| elif self.transition_target == 'level': | |
| self.battle = None | |
| else: | |
| self.setup(self.tmx_maps[self.transition_target[0]], self.transition_target[1]) | |
| self.tint_mode = 'untint' | |
| self.transition_target = None | |
| self.tint_progress = max(0, min(self.tint_progress, 255)) | |
| self.tint_surf.set_alpha(self.tint_progress) | |
| self.display_surface.blit(self.tint_surf, (0,0)) | |
| def end_battle(self, character): | |
| self.audio['battle'].stop() | |
| self.transition_target = 'level' | |
| self.tint_mode = 'tint' | |
| if character: | |
| character.character_data['defeated'] = True | |
| self.create_dialog(character) | |
| elif not self.evolution: | |
| self.player.unblock() | |
| self.check_evolution() | |
| def check_evolution(self): | |
| for index, monster in self.player_monsters.items(): | |
| if monster.evolution: | |
| if monster.level == monster.evolution[1]: | |
| self.audio['evolution'].play() | |
| self.player.block() | |
| self.evolution = Evolution(self.monster_frames['monsters'], monster.name, monster.evolution[0], self.fonts['bold'], self.end_evolution, self.start_animation_frames) | |
| self.player_monsters[index] = Monster(monster.evolution[0], monster.level) | |
| if not self.evolution: | |
| self.audio['overworld'].play(-1) | |
| def end_evolution(self): | |
| self.evolution = None | |
| self.player.unblock() | |
| self.audio['evolution'].stop() | |
| self.audio['overworld'].play(-1) | |
| # monster encounters | |
| def check_monster(self): | |
| if [sprite for sprite in self.monster_sprites if sprite.rect.colliderect(self.player.hitbox)] and not self.battle and self.player.direction: | |
| if not self.encounter_timer.active: | |
| self.encounter_timer.activate() | |
| def monster_encounter(self): | |
| sprites = [sprite for sprite in self.monster_sprites if sprite.rect.colliderect(self.player.hitbox)] | |
| if sprites and self.player.direction: | |
| self.encounter_timer.duration = randint(800, 2500) | |
| self.player.block() | |
| self.audio['overworld'].stop() | |
| self.audio['battle'].play(-1) | |
| self.transition_target = Battle( | |
| player_monsters = self.player_monsters, | |
| opponent_monsters = {index:Monster(monster, sprites[0].level + randint(-3,3)) for index, monster in enumerate(sprites[0].monsters)}, | |
| monster_frames = self.monster_frames, | |
| bg_surf = self.bg_frames[sprites[0].biome], | |
| fonts = self.fonts, | |
| end_battle = self.end_battle, | |
| character = None, | |
| sounds = self.audio) | |
| self.tint_mode = 'tint' | |
| def run(self): | |
| while True: | |
| dt = self.clock.tick() / 1000 | |
| self.display_surface.fill('black') | |
| # event loop | |
| for event in pygame.event.get(): | |
| if event.type == pygame.QUIT: | |
| pygame.quit() | |
| exit() | |
| # update | |
| self.encounter_timer.update() | |
| self.input() | |
| self.transition_check() | |
| self.all_sprites.update(dt) | |
| self.check_monster() | |
| # drawing | |
| self.all_sprites.draw(self.player) | |
| # overlays | |
| if self.dialog_tree: self.dialog_tree.update() | |
| if self.index_open: self.monster_index.update(dt) | |
| if self.battle: self.battle.update(dt) | |
| if self.evolution: self.evolution.update(dt) | |
| self.tint_screen(dt) | |
| pygame.display.update() | |
| if __name__ == '__main__': | |
| game = Game() | |
| game.run() |