class MyView(arcade.View): def __init__(self, window: arcade.Window): super().__init__() self.window = window self.ui_manager = UIManager(window) def on_draw(self): arcade.start_render() arcade.set_background_color(arcade.color.BLACK) def on_show_view(self): print('on_show_view') self.setup() def setup(self): self.ui_manager.purge_ui_elements() self.ui_manager.add_ui_element( UILabel( text='Username:'******'username') self.ui_manager.add_ui_element(input_box) submit_button = UIFlatButton(text='Login', center_x=650, center_y=self.window.height // 2, width=200, height=40, id='submit_button') self.ui_manager.add_ui_element(submit_button) self.ui_manager.add_ui_element( UILabel(text='', center_x=self.window.width // 2, center_y=self.window.height // 2 - 100, width=600, height=40, id='login_message')) @input_box.event('on_enter') @submit_button.event('on_click') def submit(): username_input = cast(UIInputBox, self.ui_manager.find_by_id('username')) username = username_input.text login_message: UILabel = cast( UILabel, self.ui_manager.find_by_id('login_message')) login_message.text = f'Welcome {username}, you are my first player.'
class MenuView(arcade.View): #меню def __init__(self): super().__init__() self.ui_manager = UIManager() def on_show_view(self): self.setup() arcade.set_background_color(arcade.color.BLACK) def on_draw(self): arcade.start_render() arcade.draw_text("Добро пожаловать", self.window.width / 2, self.window.height / 1.5, arcade.color.WHITE, font_size=30, anchor_x="center") def on_hide_view(self): self.ui_manager.unregister_handlers() def setup(self): self.ui_manager.purge_ui_elements() self.ui_manager.add_ui_element(PlayButton()) self.ui_manager.add_ui_element(SettingButton()) self.ui_manager.add_ui_element(ExitButton()) def on_update(self, delta_time): for i in range(3): button = self.ui_manager.find_by_id(i) button.center_x = self.window.width / 2 button.center_y = (self.window.height / 2) - (35 * i) if button.click and i == 0: button.click = False game_view = GameView() game_view.setup() #загрузка ресурсов window.show_view(game_view) elif button.click and i == 1: button.click = False elif button.click and i == 2: button.click = False window.close()
class MyView(arcade.View): def __init__(self, window: arcade.Window): super().__init__() self.window = window self.ui_manager = UIManager(window) self.ui_manager.push_handlers(self.on_ui_event) def on_draw(self): arcade.start_render() arcade.set_background_color(arcade.color.BLACK) def on_show_view(self): print('on_show_view') self.setup() def setup(self): self.ui_manager.purge_ui_elements() self.ui_manager.add_ui_element( UILabel( text='Username:'******'username')) self.ui_manager.add_ui_element( UIFlatButton(text='Login', center_x=650, center_y=self.window.height // 2, width=200, height=40, id='submit_button')) self.ui_manager.add_ui_element( UILabel(text='', center_x=self.window.width // 2, center_y=self.window.height // 2 - 100, width=600, height=40, id='login_message')) def on_ui_event(self, event: UIEvent): if event.type == UIClickable.CLICKED and event.get( 'ui_element').id == 'submit_button': # Trigger action if 'submit_button' was clicked self.submit() elif event.type == UIInputBox.ENTER and event.get( 'ui_element').id == 'username': # Trigger action if ENTER pressed in 'username'-UIInputBox self.submit() def submit(self): username_input = cast(UIInputBox, self.ui_manager.find_by_id('username')) username = username_input.text login_message: UILabel = cast( UILabel, self.ui_manager.find_by_id('login_message')) login_message.text = f'Welcome {username}, you are my first player.'
class OptionsMenu(arcade.View): def __init__(self, window: arcade.Window): super().__init__() self.window = window self.ui_manager = UIManager(window) self.level_stats = generator_data.GeneratorData() self.music = True self.sounds = True def setup(self): try: file = open(resource_path('data/settings.info'), 'rb') info = pickle.load(file) self.level_stats = info[0] self.music = info[1] self.sounds = info[2] except FileNotFoundError: self.level_stats = generator_data.GeneratorData() arcade.set_background_color(arcade.color.BLACK) if self.level_stats.seed: text = str(self.level_stats.seed) else: text = 'Enter Seed' seed_box = UIInputBox(100, C.SCREEN_HEIGHT - 100, 150, 40, text, 'seed_box') self.ui_manager.add_ui_element(seed_box) @seed_box.event('on_enter') def set_seed(): self.level_stats.seed = self.ui_manager.find_by_id('seed_box').text self.create_input_box_mv( 'mv_chance_box', str(int(self.level_stats.mv_chance * 100)) + '%', 'Value must be between 0 and 100%', [475, C.SCREEN_HEIGHT - 100, 500, 40], self.level_stats) self.create_input_box_mv( 'mv_chance_x', str(int(self.level_stats.mv_chance_x * 100)) + '%', 'Value must be between 0 and 100%', [475, C.SCREEN_HEIGHT - 300, 500, 40], self.level_stats) self.create_input_box_mv( 'mv_chance_y', str(int(self.level_stats.mv_chance_y * 100)) + '%', 'Value must be between 0 and 100%', [475, C.SCREEN_HEIGHT - 500, 500, 40], self.level_stats) if self.level_stats.mv_chance_xy: text = 'True' else: text = 'False' mv_allowed_xy = UIFlatButton(text, 300, C.SCREEN_HEIGHT - 700, width=150, height=50, id='mv_allowed_xy') mv_allowed_xy.set_style_attrs(border_color_hover=arcade.color.WHITE, border_color_press=arcade.color.WHITE) self.ui_manager.add_ui_element(mv_allowed_xy) @mv_allowed_xy.event('on_click') def switch(): button = self.ui_manager.find_by_id('mv_allowed_xy') if button.text == 'True': button.text = 'False' output = False else: button.text = 'True' output = True button.render() self.level_stats.mv_chance_xy = output max_gap = UIInputBox(975, C.SCREEN_HEIGHT - 100, 400, 40, str(self.level_stats.max_gap), 'max_gap') self.ui_manager.add_ui_element(max_gap) @max_gap.event('on_enter') def update_gap(): text_box = self.ui_manager.find_by_id('max_gap') try: gap = int(text_box.text) if not 30 < gap: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be over 30' gap = 160 except ValueError: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be an integer' gap = 160 self.level_stats.max_gap = gap max_height = UIInputBox(975, C.SCREEN_HEIGHT - 300, 400, 40, str(self.level_stats.max_height), 'max_height') self.ui_manager.add_ui_element(max_height) @max_height.event('on_enter') def update_height(): text_box = self.ui_manager.find_by_id('max_height') try: height = int(text_box.text) if not 1500 < height: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be over 1500' height = 2500 except ValueError: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be an integer' height = 2500 self.level_stats.max_height = height max_platforms = UIInputBox(975, C.SCREEN_HEIGHT - 500, 400, 40, str(self.level_stats.pl_num), 'max_platforms') self.ui_manager.add_ui_element(max_platforms) @max_platforms.event('on_enter') def update_platforms(): text_box = self.ui_manager.find_by_id('max_platforms') try: length = int(text_box.text) if not 0 < length: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be over 0' length = 10 except ValueError: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) text_box.text = 'Must be an integer' length = 10 self.level_stats.pl_num = length return_to_menu = UIFlatButton('BACK', 1400, 100, 150, 50, id='return') return_to_menu.set_style_attrs(border_color_hover=arcade.color.WHITE, border_color_press=arcade.color.WHITE) self.ui_manager.add_ui_element(return_to_menu) @return_to_menu.event('on_click') def return_to_menu(): pickle_out = open(resource_path('data/settings.info'), 'wb') pickle.dump((self.level_stats, self.music, self.sounds), pickle_out) pickle_out.close() self.ui_manager.purge_ui_elements() self.window.show_view(MainMenu(self.window)) if self.music: text = 'True' else: text = 'False' music = UIFlatButton(text, 850, 200, width=150, height=50, id='music') music.set_style_attrs(border_color_hover=arcade.color.WHITE, border_color_press=arcade.color.WHITE) self.ui_manager.add_ui_element(music) @music.event('on_click') def switch(): button = self.ui_manager.find_by_id('music') if button.text == 'True': button.text = 'False' output = False else: button.text = 'True' output = True button.render() self.music = output if self.sounds: text = 'True' else: text = 'False' sounds = UIFlatButton(text, 1100, 200, width=150, height=50, id='sounds') sounds.set_style_attrs(border_color_hover=arcade.color.WHITE, border_color_press=arcade.color.WHITE) self.ui_manager.add_ui_element(sounds) @sounds.event('on_click') def switch(): button = self.ui_manager.find_by_id('sounds') if button.text == 'True': button.text = 'False' output = False else: button.text = 'True' output = True button.render() self.sounds = output def create_input_box_mv(self, id, base_text, error_text, position, level_stats): mv_chance_box = UIInputBox(position[0], position[1], position[2], position[3], base_text, id) self.ui_manager.add_ui_element(mv_chance_box) @mv_chance_box.event('on_enter') def get_mv_chance(): mv_chance = self.ui_manager.find_by_id(id).text mv_chance = mv_chance.replace('%', '') try: mv_chance = float(mv_chance) / 100 if not 0 <= mv_chance <= 1: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) self.ui_manager.find_by_id(id).text = error_text mv_chance = 0.2 except ValueError: arcade.play_sound( arcade.load_sound(resource_path('sounds/erro.mp3')), 0.05) self.ui_manager.find_by_id(id).text = error_text mv_chance = 0.2 if id == 'mv_chance_box': self.level_stats.mv_chance = mv_chance elif id == 'mv_chance_x': self.level_stats.mv_chance_x = mv_chance elif id == 'mv_chance_y': self.level_stats.mv_chance_y = mv_chance def on_draw(self): arcade.start_render() arcade.draw_text('Seed:', 25, C.SCREEN_HEIGHT - 50, arcade.color.WHITE, 30) arcade.draw_text('Global moving platform chance:', 225, C.SCREEN_HEIGHT - 50, arcade.color.WHITE, 30) arcade.draw_text('Chance of X-axis movement:', 225, C.SCREEN_HEIGHT - 250, arcade.color.WHITE, 30) arcade.draw_text('Chance of Y-axis movement:', 225, C.SCREEN_HEIGHT - 450, arcade.color.WHITE, 30) arcade.draw_text('Are XY movements allowed:', 225, C.SCREEN_HEIGHT - 650, arcade.color.WHITE, 30) arcade.draw_text('Set the maximum gap between platforms:', 775, C.SCREEN_HEIGHT - 50, arcade.color.WHITE, 30) arcade.draw_text('Set the maximum height of the final platform:', 775, C.SCREEN_HEIGHT - 250, arcade.color.WHITE, 30) arcade.draw_text('Set the maximum length of the platforms:', 775, C.SCREEN_HEIGHT - 450, arcade.color.WHITE, 30) arcade.draw_text( 'Textbox values require ENTER to be pressed to be set.', 25, 25, arcade.color.WHITE, 30) arcade.draw_text('Music:', 775, C.SCREEN_HEIGHT - 650, arcade.color.WHITE, 30) arcade.draw_text('Sounds:', 1025, C.SCREEN_HEIGHT - 650, arcade.color.WHITE, 30) def on_show_view(self): self.setup()
class Game(arcade.Window): # Играют по очереди, сначала делает ход первый игрок, потом второй и т.д. hosts: list = [ ] # список хостов (фракций) игроков (хост - играбельный объект, т.е. страна) hosts_num = 2 active_host: int # номер текущего активного хоста (тот, который играет) game_iteration: int # номер хода host_init_pos = {0: (1, 10), 1: (8, 1)} gamer_host: int state = None select_color = "BLUE" select2_color = "COLUMBIA_BLUE" ui_margin_left = None ui_margin_top = None game_over = False def __init__(self): self.state = GameState() self.map = HexMap(hex_radius=MAP_HEX_RADIUS) self.w, self.h = self.map.get_window_size() super().__init__(self.w + self.w // 4, self.h, "Poliyoy") arcade.set_background_color(arcade.color.BLACK) self.ui_manager = UIManager() self.ui_margin_left = self.w / 15 self.ui_margin_top = self.h / 10 self.game_iteration = 0 self.setup() def __new__(cls): if not hasattr(cls, 'instance'): cls.instance = super(Game, cls).__new__(cls) return cls.instance def init_hosts(self): for (e, frac) in enumerate(FRACTIONS_CONFIG.keys()): self.hosts.append(Fraction(**FRACTIONS_CONFIG[frac])) fraction = self.hosts[-1] self.state.append_fraction(fraction) if not fraction.isBot: self.active_host = e self.gamer_host = e self.map.place_fraction(fraction, self.host_init_pos[fraction.fraction_id]) self.state.set_fraction(self.gamer_host) def setup(self): """ Здесь рендеринг UI и инициализация пользовательской fraction Например, разместить сущности стран на карте :return: """ self.map.create_map() self.init_hosts() self.after_init() # размещение на карте деревьев и т.п. # self.map.after_init(self.hosts) # размещение на карте деревьев и т.п. self.ui_manager.purge_ui_elements() set_ui(self) # back = self.state.last_mouse_tile_pos # back2 = self.state.last_fraction # self.hosts[not self.active_host].money_amount = 9999 # # pos = self.hosts[not self.active_host].fraction_capital_pos # self.state.last_mouse_tile_pos = pos # self.state.last_fraction = self.hosts[not self.active_host] # obj = SpawnEntity(self.map, self.state, 1, UpdateGameState(self)) # obj.execute() # self.state.last_mouse_tile_pos = back # self.state.last_fraction = back2 # sys.exit() def after_init(self): """ Запуск после размещения fractions :return: """ trees = self.map.get_random_positions() from config import TREE_ID fr = self.state.get_last_fraction() for i in trees: self.map.spawn_tree(i, fr) def on_draw(self): """ Рендеринг различных объектов """ # This command has to happen before we start drawing arcade.start_render() self.map.draw() self.ui_manager.on_draw() def on_next_step_key_press(self): # print("before", self.hosts[1].money_amount) for host in self.hosts: for tile in host.tiles: self.map.unuse_entity(tile) self.game_over = self.state.get_last_fraction().make_step() self.update_screen_info() self.game_iteration += 1 self.active_host = not self.active_host self.state.set_fraction(self.active_host) # upd last host self.update_screen_info() fraction = self.state.get_last_fraction() # if fraction.village_cost_prev != fraction.village_cost: self.update_village_btn() def update_screen_info(self): self.ui_manager.find_by_id("money_amount").text = "Gold: " + str( self.state.get_last_fraction().money_amount) self.ui_manager.find_by_id("money_step").text = "Delta: " + str( self.state.get_last_fraction().step_delta) def update_village_btn(self): # Тяжелая операция, поэтому случай обрабатывается отдельно # # Дальше костыль для обновления текста кнопки (в либе такое, почему-то, не предусмотрено) update_ui(self) def on_mouse_press(self, x, y, button, modifiers): """ Обработка пользовательского действия """ col, row = self.map.locate(x, y) host = self.state.get_last_fraction() pos = (col, row) self.map.unselect_tiles() if button == 1: if self.map.is_in_map(col, row): self.map.add_tile_to_state(pos) self.map.select_tile(pos, self.select_color) self.state.set_pos(col, row) if pos in host.units_pos.keys(): self.map.show_move_range(pos, self.select_color, self.select2_color) elif button == 4: unit_pos = self.state.last_mouse_tile_pos if unit_pos in host.units_pos.keys(): self.state.last_mouse_right_tile_pos = pos command = MoveUnit(self.map, self.state, UpdateGameState(self)) command.execute() if pos in host.tiles.keys(): pass # print(self.active_host, self.state.get_last_fraction().fraction_id) def possible_moves(self, pos): return self.map.show_move_range_quiet(pos) def bot_move(self): pass