Связь с администрацией сайта:       

demo

Среди толпы я одинок

PhaserMultiplayer PhaserMultiplayer

Создание многопользовательской игры с помощью Phaser и Eureca.io

Оглавление

Целью данной статьи является показать вам, как создать игру-мультиплеер на HTML5. Я буду использовать движок Phaser  в игре, и использовать Eureca.io  для создания клиент/серверного приложения. Для этого урока вам нужно иметь некоторые знания об играх на HTML5 (Желательно опыт работы с движком Phaser). Надеюсь, что у вас есть некоторые знания о nodejs и то, что вы уже установили его. Код игры я буду использовать с сайта Phaser, игра называется – Танки .
 
 
Давайте начнем.

 

 
Первый шаг: рефакторинг кода
 
Были сделаны некоторые модификации и упрощения, чтобы он стал пригодным для мультиплеера.
Я факторизовал код в классе игрока и вражеские танки под названием Tank (это переименованный класс EnemyTank из примера кода в Phaser), так как в многопользовательском режиме вражеские танки только удаленные игроки, а не боты. 
Поэтому создание и обновление кода был переведен в класс Tank.

 

Tank = function (index, game, player) {this.cursor = {
		left:false,
		right:false,
		up:false,
		fire:false}
 this.input = {
		left:false,
		right:false,
		up:false,
		fire:false}
 
    var x = 0;
    var y = 0;
 
    this.game = game;
    this.health = 30;
    this.player = player;
    this.bullets = game.add.group();
    this.bullets.enableBody = true;
    this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
    this.bullets.createMultiple(20, 'bullet', 0, false);
    this.bullets.setAll('anchor.x', 0.5);
    this.bullets.setAll('anchor.y', 0.5);
    this.bullets.setAll('outOfBoundsKill', true);
    this.bullets.setAll('checkWorldBounds', true);	
 
 
    this.currentSpeed =0;
    this.fireRate = 500;
    this.nextFire = 0;
    this.alive = true;
 
    this.shadow = game.add.sprite(x, y, 'enemy', 'shadow');
    this.tank = game.add.sprite(x, y, 'enemy', 'tank1');
    this.turret = game.add.sprite(x, y, 'enemy', 'turret');
 
    this.shadow.anchor.set(0.5);
    this.tank.anchor.set(0.5);
    this.turret.anchor.set(0.3, 0.5);
 
    this.tank.id = index;
    game.physics.enable(this.tank, Phaser.Physics.ARCADE);
    this.tank.body.immovable = false;
    this.tank.body.collideWorldBounds = true;
    this.tank.body.bounce.setTo(0, 0);
 
    this.tank.angle = 0;
 
    game.physics.arcade.velocityFromRotation(this.tank.rotation, 0, this.tank.body.velocity);
 };
 
Tank.prototype.update = function() {
 
    for (var i in this.input) this.cursor[i] = this.input[i];    
 
 
 
    if (this.cursor.left)
    {
        this.tank.angle -= 1;
    }
    else if (this.cursor.right)
    {
        this.tank.angle += 1;
    }    
    if (this.cursor.up)
    {
        //  Скорость
        this.currentSpeed = 300;
    }
    else
    {
        if (this.currentSpeed > 0)
        {
            this.currentSpeed -= 4;
        }
    }
    if (this.cursor.fire)
    {    
        this.fire({x:this.cursor.tx, y:this.cursor.ty});
    }
 
 
 
    if (this.currentSpeed > 0)
    {
        game.physics.arcade.velocityFromRotation (this.tank.rotation, this.currentSpeed, 

this.tank.body.velocity); } else { game.physics.arcade.velocityFromRotation(this.tank.rotation, 0, this.tank.body.velocity); }       this.shadow.x = this.tank.x; this.shadow.y = this.tank.y; this.shadow.rotation = this.tank.rotation;   this.turret.x = this.tank.x; this.turret.y = this.tank.y;};  

  

Также добавлен метод Tank.kill для удаления танка из игры со сцены и переместил код fire() для Tank.fire

Tank.prototype.fire = function(target) {if (!this.alive) return;
        if (this.game.time.now > this.nextFire && this.bullets.countDead() > 0)
        {
            this.nextFire = this.game.time.now + this.fireRate;
            var bullet = this.bullets.getFirstDead();
            bullet.reset(this.turret.x, this.turret.y); 
	  bullet.rotation = this.game.physics.arcade.moveToObject(bullet, target, 500);
        }}
 
 
Tank.prototype.kill = function() {this.alive = false;this.tank.kill();this.turret.kill();

this.shadow.kill();}  

 

Я также удалил обработку материала и коллизии с другими объектами, для упрощения повреждения, так что стрельба и соприкосновение не даст никакого результата.
Последнее изменение состояло в том, как обрабатывается действие/движение игрока.
Пример кода в phaser.input непосредственно через game.input.keyboard.createCursorKeys () , но в нашем случае, клиент не должен обрабатывать любое действие напрямую, позже я объясню почему.
Поэтому я создал объект Tank.input и Tank.cursor для объекта, они обрабатывают действия/движения игрока.
Этот код  - модифицированная функция update() 
function update () {
 
	player.input.left = cursors.left.isDown;
	player.input.right = cursors.right.isDown;
	player.input.up = cursors.up.isDown;
	player.input.fire = game.input.activePointer.isDown;
	player.input.tx = game.input.x+ game.camera.x;
	player.input.ty = game.input.y+ game.camera.y;
 
 
 
    turret.rotation = game.physics.arcade.angleToPointer(turret);	
    land.tilePosition.x = -game.camera.x;
    land.tilePosition.y = -game.camera.y;
 
 
 
    for (var i in tanksList)
    {if (!tanksList[i]) continue;
var curBullets = tanksList[i].bullets;
var curTank = tanksList[i].tank;
for (var j in tanksList){if (!tanksList[j]) continue;if (j!=i) {  var targetTank = tanksList[j].tank;  game.physics.arcade.overlap(curBullets, targetTank,
bulletHitPlayer, null, this);  }if (tanksList[j].alive){ tanksList[j].update();}} }}  
Вы можете скачать код рефакторинга здесь, чтобы помочь вам дальше идти по обучению в данной статье.
 
 
 

Пред. След. »

Голосуй
(6 Голоса)
1 комментарий
  • Vladimir92

    Спасибо за интересную статью. Давно искал. Сделал по аналогии игру крестики-нолики. Играем с другом теперь по интернету)))

    Жалоба Vladimir92 30.03.2017 08:04 Перейти к комментированию
Оставьте комментарий

Поля, отмеченные звездочкой(*) обязательны для заполнения. HTML теги не приветствуются.

Вход на сайт