import random import arcade SPRITE_SCALING = 0.75 WINDOW_WIDTH = 1280 WINDOW_HEIGHT = 720 WINDOW_TITLE = "Camera" # Скорость плавного движения камеры CAMERA_SPEED = 0.1 # Скорость движения игрока PLAYER_MOVEMENT_SPEED = 7 PLAYER_MOVEMENT_DIAGONAL_SPEED = PLAYER_MOVEMENT_SPEED / 2 ** 0.5 class GameView(arcade.View): def __init__(self): super().__init__() # Списки спрайтов self.player_list = None self.wall_list = None # Спрайт игрока self.player_sprite = None # Физический движок (для столкновений со стенами) self.physics_engine = None # Храним информацию о том, какие клавиши нажаты self.left_pressed = False self.right_pressed = False self.up_pressed = False self.down_pressed = False # Две камеры — одна для игрового мира, другая для GUI game user interface self.camera_sprites = arcade.Camera2D() self.camera_gui = arcade.Camera2D() def setup(self): # Создаём списки спрайтов self.player_list = arcade.SpriteList() self.wall_list = arcade.SpriteList() self.background_color = arcade.color.SKY_BLUE # Игрок self.player_sprite = arcade.Sprite( ":resources:images/animated_characters/female_person/femalePerson_idle.png", scale=1, ) self.player_sprite.center_x = 256 self.player_sprite.center_y = 512 self.player_list.append(self.player_sprite) # Стены wall_texture = ":resources:images/tiles/stoneCenter.png" # Создаём много стен столбцами и рядами for _ in range(50): # случайная позиция в пределах уровня x = random.randint(100, 1600) y = random.randint(0, 1500) wall = arcade.Sprite(wall_texture, scale=SPRITE_SCALING) wall.center_x = x wall.center_y = y self.wall_list.append(wall) # Включаем физику игрок + стены self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list) def on_draw(self): self.clear() # Включаем камеру игрового мира self.camera_sprites.use() # Рисуем стены и игрока self.wall_list.draw() self.player_list.draw() # Включаем GUI-камеру (она не скроллится) self.camera_gui.use() # Пишем текст (положение камеры) text = f"Положение камеры: ({self.camera_sprites.position[0]:5.1f}, " \ f"{self.camera_sprites.position[1]:5.1f})" arcade.draw_text(text, 10, 10, arcade.color.WHITE, 20) def on_key_press(self, key, modifiers): if key == arcade.key.UP: self.up_pressed = True elif key == arcade.key.DOWN: self.down_pressed = True elif key == arcade.key.LEFT: self.left_pressed = True elif key == arcade.key.RIGHT: self.right_pressed = True def on_key_release(self, key, modifiers): if key == arcade.key.UP: self.up_pressed = False elif key == arcade.key.DOWN: self.down_pressed = False elif key == arcade.key.LEFT: self.left_pressed = False elif key == arcade.key.RIGHT: self.right_pressed = False def on_update(self, delta_time): # Сбрасываем скорость игрока self.player_sprite.change_x = 0 self.player_sprite.change_y = 0 # Движение вверх/вниз # Определяем направления движения по осям move_x = 0 move_y = 0 if self.up_pressed and not self.down_pressed: move_y = 1 elif self.down_pressed and not self.up_pressed: move_y = -1 if self.left_pressed and not self.right_pressed: move_x = -1 elif self.right_pressed and not self.left_pressed: move_x = 1 # Если движение есть по двум осям сразу (диагональ) — берем скорость диагональную if move_x != 0 and move_y != 0: self.player_sprite.change_x = move_x * PLAYER_MOVEMENT_DIAGONAL_SPEED self.player_sprite.change_y = move_y * PLAYER_MOVEMENT_DIAGONAL_SPEED else: self.player_sprite.change_x = move_x * PLAYER_MOVEMENT_SPEED self.player_sprite.change_y = move_y * PLAYER_MOVEMENT_SPEED # Обновляем физический движок self.physics_engine.update() # Двигаем камеру за игроком self.scroll_to_player() def scroll_to_player(self): """ Плавное движение камеры за игроком """ # Целевая позиция — координаты игрока position = (self.player_sprite.center_x, self.player_sprite.center_y) # Плавное движение: позиция = lerp(текущая, целевая) self.camera_sprites.position = arcade.math.lerp_2d( self.camera_sprites.position, position, CAMERA_SPEED ) def on_resize(self, width: int, height: int): super().on_resize(width, height) self.camera_sprites.match_window() if __name__ == "__main__": window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, resizable=True) game = GameView() game.setup() window.show_view(game) arcade.run()