I'm currently creating a multiplayer game using the HTML5 framework Phaser.
It's a game where zombies spawn on the map and players have to shoot them to kill them. The zombies target players that are closest to them.
Currently, I'm having my an issue with my design strategy. I'm not sure if this type of game is possible with Phaser due to the movement tracking.
At present, the client is handling all of the player movement, so whenever a player moves, it broadcasts it to the server which sends it to all of the other clients.
However, I would like for the zombies and the bullets to be controlled by the server exclusively. The server then updates each client with the velocity of each zombie and their current position. My reasoning is that anything that isn't player input should be calculated by the server. This will prevent issues such as two clients saying that a zombie died at different times and then trying to communicate with one another, having bullets at different locations at the same time, or zombies spawning at separate times between clients.
Here's an example of a zombie class:
function Zombie(game, data){
this.game = game;
this.id = data.id;
Phaser.Sprite.call(this, this.game, data.x, data.y, 'zombie');
this.anchor.setTo(0.5,0.5);
this.animations.add('right', [0,1,2,3], 7, true);
this.animations.add('left', [4,5,6,7], 7, true);
this.game.physics.arcade.enable(this);
this.body.collideWorldBounds = true;
this.health = data.health;
this.maxHealth = data.maxHealth;
this.speed = data.speed;
this.target = this.game.player;
this.waiting = 100;
this.name = "zombie";
this.healthBary = 20;
this.healthBar = this.game.add.sprite(this.x, this.y + this.healthBary, 'player_health');
this.healthBar.anchor.setTo(0.5, 0.5);
CollisionManager.addObjectToGroup(this, 'baddies');
this.game.add.existing(this);
}
Zombie.prototype = Object.create( Phaser.Sprite.prototype );
Zombie.prototype.constructor = Zombie;
Zombie.prototype.update = function(){
this.updateHealthBar();
this.moveTowards(this.target);
Zombie.prototype.uTarget = function(target) {
this.target = target;
};
Zombie.prototype.moveTowards = function(target){
var x = target.x - this.x;
var y = target.y - this.y;
var mag = Math.sqrt((x * x) + (y * y));
var nx = x / mag;
var ny = y / mag;
this.body.velocity.x = nx * this.speed;
this.body.velocity.y = ny * this.speed;
if(this.body.velocity.x >= 0){
this.animations.play('right');
}
else if(this.body.velocity.x < 0){
this.animations.play('left')
}
}
Zombie.prototype.updateHealthBar = function(){
this.healthBar.x = this.x;
this.healthBar.y = this.y + this.healthBary;
var p = (this.health / this.maxHealth);
p = parseFloat(p.toFixed(1));
this.healthBar.frame = 10 - (p * 10);
}
Zombie.prototype._damage = function(amount){
this.health -= amount;
if(this.health <= 0){
this.kill;
this.die(true);
}
}
Zombie.prototype.die = function(points){
if(this.game){
//this.game.baddie_die_sfx.play();
}
WaveManager.onMap--;
CollisionManager.removeObjectFromGroup(this, "baddies");
if(this.healthBar){
this.healthBar.destroy();
}
socket.emit("kill zombie", {id: this.id});
this.kill();
this.destroy();
}
The problem is that I can't create a Phaser game object on the server (as it's running on a Linux server) because there's no window that can be used. The bullets and zombies need to be Phaser objects for the sake of collision detection, but I can't do that on the server.
I know that I could create a vector of zombies and bullets server-side that would have the information for each bullet/zombie's position at any given time and then update the client, but then I wouldn't be able to use the CollisionManager in Phaser.
Right now, it seems like my only solution is to create my own collision detection system. Are there any alternative ideas?
window
methods by itself, I can imagine no obstruction to using its collision routines server-side. There's also jsdom, which D3 falls back on when run under node instead of a browser. \$\endgroup\$