Назад Вперед

Движение камеры за игроком.

Разберу пример, в котором игрок в виде спрайта двигается по сцене, а камера отслеживает движение игрока. Сцена при этом по размерам больше игрового пространства. Фоном будет служить несколько собранных в одно изображений. Управление игроком с помощью клавиатуры.

Для примера понадобиться 2 изображения: сам игрок и фон. Игрока сделаю из простой фигуры, которую уже делал для проекта Snake. Фоновое изображение скачаю из бесплатного источника с размером 650 на 487 пикселей.

Использовать буду стандартный шаблон проекта, как и во всех примерах. Открываю его. Сразу нужно изменить игровые настройки: добавить использование физического движка 'arcade'.

Новый проект

В функции preload() загружаю изображения.

Файл main.js:


    ...
    this.load.image('bg', 'assets/space.jpg ');
    this.load.image('player', 'assets/snake.png'); 
    ...
 

Прежде, чем перейти к размещению изображений, необходимо установить границы для игрового пространства и для камеры. В моем примере ширина будет равна ширине двух фоновых изображений, высота — высоте двух фоновых изображений. Размер моего фонового изображения 650х487. Соответственно ширина и высота игрового пространства и камеры будет 650*2х487*2. Такие координаты и записываю в методах установки границ.

Файл main.js:


    ...
    this.cameras.main.setBounds(0, 0, 650*2, 487*2);
    this.physics.world.setBounds(0, 0, 650*2, 487*2);  
    ...
 

Следующий шаг — размещение фонового изображения. Записываю 4 метода с нужными координатами и методом setOrigin(). Кроме того, использую методы setFlipX(true) и setFlipY(true) для зеркального отражения изображения по оси X и оси Y.

Файл main.js:


    ...
    this.add.image(0, 0, 'bg').setOrigin(0);
    this.add.image(650, 0, 'bg').setOrigin(0).setFlipX(true);
    this.add.image(0, 487, 'bg').setOrigin(0).setFlipY(true);
    this.add.image(650, 487, 'bg').setOrigin(0).setFlipX(true).setFlipY(true);  
    ...
 

Установка границ игры

Сохранив проект и открыв в браузере, вижу, что на данный момент одно фоновое изображение занимает все видимое игровое пространство. Остальные изображения пока скрыты.

Проверка в браузере

Теперь размещаю игрока на сцене. При этом добавляю ему физические свойства и сохраняю в отдельную переменную. И чтобы игрок не мог выходить за пределы границ игрового пространства записываю для переменной метод, который это запрещает делать (столкновение с границами мира).

Файл main.js:


    ...
    this.player = this.physics.add.image(300, 200, 'player');
    this.player.setCollideWorldBounds(true);
    ...
 

В методе create() осталось записать метод следования камеры за игроком и получения ключей нажатых клавиш стрелок для управления игроком.

Файл main.js:


    ...
    this.cameras.main.startFollow(this.player, true, 0.05, 0.05);
    this.cursors = this.input.keyboard.createCursorKeys();
    ...
 

Размещение игрока

В функции update() записываю код для управления движением персонажа. Но перед эти записываю начальную скорость движения, чтобы игрок не двигался, когда клавиши стрелок не нажаты.

Файл main.js:


    ...
    this.player.setVelocity(0);
    if (this.cursors.left.isDown)
    {
        this.player.setVelocityX(-300);
    }
    else if (this.cursors.right.isDown)
    {
        this.player.setVelocityX(300);
    }
    if (this.cursors.up.isDown)
    {
        this.player.setVelocityY(-300);
    }
    else if (this.cursors.down.isDown)
    {
        this.player.setVelocityY(300);
    }        
    ...
 

Управление игроком

Сохраняю и проверяю в браузере. Игрок двигается при нажатии клавиш стрелок по игровому пространству. Камера следует за ним. И фоновое изображение состоит из 4 одинаковых изображений, которое отражены по разным осям.

Таким образом можно создавать карты локаций, по которым двигается игрок. Камера будет следовать за ним. Выйти за пределы игрового пространства нельзя будет, так как установлены границы и записан метод столкновения игрока и этих границ.

Полный код файла main.js.

Файл main.js:


    var config = {
        type: Phaser.AUTO,
        parent: 'container',
        width: 650,
        height: 487,
        physics: {
            default: 'arcade',
        },
        scene: {
            preload: preload,
            create: create,
            update: update
        }
    };
    
    var game = new Phaser.Game(config); 
    
    function preload () {
        this.load.image('bg', 'assets/2/space.jpg ');
        this.load.image('player', 'assets/2/snake.png');
    }
    
    function create () {
        this.cameras.main.setBounds(0, 0, 650*2, 487*2);    
        this.physics.world.setBounds(0, 0, 650*2, 487*2);
    
        this.add.image(0, 0, 'bg').setOrigin(0);
        this.add.image(650, 0, 'bg').setOrigin(0).setFlipX(true);
        this.add.image(0, 487, 'bg').setOrigin(0).setFlipY(true);
        this.add.image(650, 487, 'bg').setOrigin(0).setFlipX(true).setFlipY(true);
    
        this.player = this.physics.add.image(300, 200, 'player');
        this.player.setCollideWorldBounds(true);
    
        this.cameras.main.startFollow(this.player, true, 0.05, 0.05);
        
        this.cursors = this.input.keyboard.createCursorKeys();
        
    }
    
    function update () {
        
        this.player.setVelocity(0);
        if (this.cursors.left.isDown)
        {
            this.player.setVelocityX(-300);
        }
        else if (this.cursors.right.isDown)
        {
            this.player.setVelocityX(300);
        }
        if (this.cursors.up.isDown)
        {
            this.player.setVelocityY(-300);
        }
        else if (this.cursors.down.isDown)
        {
            this.player.setVelocityY(300);
        }
    }
 

Результат:

Назад Вперед