mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 10:37:34 +00:00
new system for synchronizing game objects. fixes #74
This commit is contained in:
parent
3ef3a6abf9
commit
07dad646cf
19 changed files with 194 additions and 162 deletions
|
|
@ -17,15 +17,14 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll, GameObject, Assert) {
|
|||
this.options = options;
|
||||
this.players = {};
|
||||
this.level = null;
|
||||
this.gameObjects = null;
|
||||
this.resetGameObjects();
|
||||
this.worldUpdateObjects = {};
|
||||
|
||||
this.physicsEngine = new PhysicsEngine();
|
||||
this.physicsEngine.setCollisionDetector();
|
||||
|
||||
this.ncTokens = [
|
||||
Nc.on(Nc.ns.core.game.gameObject.add, this.onGameObjectAdd, this),
|
||||
Nc.on(Nc.ns.core.game.gameObject.remove, this.onGameObjectRemove, this)
|
||||
Nc.on(Nc.ns.core.game.worldUpdateObjects.add, this.onWorldUpdateObjectAdd, this),
|
||||
Nc.on(Nc.ns.core.game.worldUpdateObjects.remove, this.onWorldUpdateObjectRemove, this)
|
||||
];
|
||||
|
||||
this.loadLevel(options.levelUid);
|
||||
|
|
@ -37,79 +36,58 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll, GameObject, Assert) {
|
|||
// extend for both sides if necessary
|
||||
};
|
||||
|
||||
GameController.prototype.resetGameObjects = function() {
|
||||
this.gameObjects = {
|
||||
fixed: [],
|
||||
animated: []
|
||||
};
|
||||
GameController.prototype.onWorldUpdateObjectAdd = function(object) {
|
||||
this.worldUpdateObjects[object.uid] = object;
|
||||
};
|
||||
|
||||
GameController.prototype.onGameObjectAdd = function(type, object) {
|
||||
this.gameObjects[type].push(object);
|
||||
};
|
||||
|
||||
GameController.prototype.onGameObjectRemove = function(type, object) {
|
||||
var i = this.gameObjects[type].indexOf(object);
|
||||
if(i>=0) this.gameObjects[type].splice(i, 1);
|
||||
GameController.prototype.onWorldUpdateObjectRemove = function(object) {
|
||||
delete this.worldUpdateObjects[object.uid];
|
||||
};
|
||||
|
||||
GameController.prototype.getPhysicsEngine = function () {
|
||||
return this.physicsEngine;
|
||||
};
|
||||
|
||||
GameController.prototype.getItemByUid = function(uid) {
|
||||
// FIXME : maybe divide this into a dedicated item pool?
|
||||
return this.worldUpdateObjects[uid];
|
||||
};
|
||||
|
||||
GameController.prototype.loadLevel = function (levelUid) {
|
||||
|
||||
if (this.level) {
|
||||
this.level.destroy();
|
||||
this.resetGameObjects();
|
||||
this.worldUpdateObjects = {};
|
||||
}
|
||||
|
||||
this.level = new TiledLevel(levelUid, this.physicsEngine, this.gameObjects);
|
||||
this.level = new TiledLevel(levelUid, this.physicsEngine);
|
||||
};
|
||||
|
||||
/*
|
||||
* This is now in core, because the recorder/player
|
||||
* uses the world update mechanism on the channel side
|
||||
*/
|
||||
GameController.prototype.onWorldUpdate = function (updateData) {
|
||||
|
||||
var body = this.physicsEngine.world.GetBodyList();
|
||||
do {
|
||||
var userData = body.GetUserData();
|
||||
if (userData instanceof GameObject) {
|
||||
var gameObject = userData;
|
||||
if(updateData[gameObject.uid]) {
|
||||
var update = updateData[gameObject.uid];
|
||||
this.onWorldUpdateGameObject(body, gameObject, update);
|
||||
}
|
||||
for (var uid in updateData) {
|
||||
|
||||
var gameObject = this.worldUpdateObjects[uid];
|
||||
|
||||
if (!(gameObject instanceof GameObject)) {
|
||||
console.warn('Cant find object ' + uid + ' in worldUpdateObjects pool');
|
||||
continue;
|
||||
}
|
||||
|
||||
} while (body = body.GetNext());
|
||||
|
||||
};
|
||||
|
||||
GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) {
|
||||
if (gameObject instanceof Doll) {
|
||||
/*
|
||||
if(gameObject === this.me.doll) {
|
||||
this.me.setLastServerPositionState(update);
|
||||
if(!this.me.acceptPositionStateUpdateFromServer()) {
|
||||
return; // this is to ignore own doll updates from world update
|
||||
}
|
||||
}
|
||||
*/
|
||||
gameObject.setActionState(update.as);
|
||||
gameObject.lookAt(update.laxy.x, update.laxy.y);
|
||||
gameObject.setUpdateData(updateData[uid]);
|
||||
}
|
||||
|
||||
Assert.number(update.p.x, update.p.y);
|
||||
Assert.number(update.a);
|
||||
Assert.number(update.lv.x, update.lv.y);
|
||||
Assert.number(update.av);
|
||||
|
||||
body.SetAwake(true);
|
||||
body.SetPosition(update.p);
|
||||
body.SetAngle(update.a);
|
||||
body.SetLinearVelocity(update.lv);
|
||||
body.SetAngularVelocity(update.av);
|
||||
};
|
||||
|
||||
/*
|
||||
GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) {
|
||||
FIXME : call gameObject.setUpdateData(updateData[uid]);
|
||||
};
|
||||
*/
|
||||
|
||||
GameController.prototype.onResetLevel = function() {
|
||||
this.loadLevel(this.level.uid);
|
||||
};
|
||||
|
|
@ -140,39 +118,23 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll, GameObject, Assert) {
|
|||
GameController.prototype.destroy = function () {
|
||||
var i = 0;
|
||||
|
||||
/*
|
||||
for(var player in this.players) {
|
||||
// this.players[player].destroy();
|
||||
|
||||
// FIXME:
|
||||
// commented out for now, because players are in gameObjects array.
|
||||
// try using a real gameobject for the health bar
|
||||
}*/
|
||||
|
||||
|
||||
for (i = 0; i < this.ncTokens.length; i++) {
|
||||
Nc.off(this.ncTokens[i]);
|
||||
this.players[player].destroy();
|
||||
}
|
||||
|
||||
/*
|
||||
* Contents of gameObject: Players, Items, Tiles, RagDolls
|
||||
* No Dolls.
|
||||
*/
|
||||
Nc.trigger(Nc.ns.client.game.events.destroy);
|
||||
|
||||
for (var key in this.gameObjects) {
|
||||
for (i = 0; i < this.gameObjects[key].length; i++) {
|
||||
var gameObject = this.gameObjects[key][i];
|
||||
|
||||
gameObject.destroy();
|
||||
}
|
||||
// Testing after destroy if worldUpdateObjects is empty
|
||||
// events.game.destroy -> gameobjects.destroy() -> Nc.trigger(worldUpdateObjects.remove)
|
||||
if(Object.keys(this.worldUpdateObjects).length > 0) {
|
||||
console.warn('Not all worldUpdateObjects have been removed... ', Object.keys(this.worldUpdateObjects));
|
||||
}
|
||||
|
||||
this.gameObjects = {
|
||||
fixed: [],
|
||||
animated: []
|
||||
};
|
||||
|
||||
this.physicsEngine.destroy();
|
||||
this.worldUpdateObjects = null;
|
||||
|
||||
Nc.off(this.ncTokens);
|
||||
|
||||
};
|
||||
|
||||
return GameController;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc, Asser
|
|||
this.createFixtures();
|
||||
this.body.SetActive(false);
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.worldUpdateObjects.add, this);
|
||||
}
|
||||
|
||||
Doll.prototype = Object.create(Parent.prototype);
|
||||
|
|
@ -471,7 +472,16 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc, Asser
|
|||
}
|
||||
};
|
||||
|
||||
Doll.prototype.setUpdateData = function(update) {
|
||||
|
||||
Parent.prototype.setUpdateData.call(this, update);
|
||||
|
||||
this.setActionState(update.as);
|
||||
this.lookAt(update.laxy.x, update.laxy.y);
|
||||
};
|
||||
|
||||
Doll.prototype.destroy = function() {
|
||||
Nc.trigger(Nc.ns.core.game.worldUpdateObjects.remove, this);
|
||||
Parent.prototype.destroy.call(this);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
define([
|
||||
"Lib/Vendor/Box2D",
|
||||
"Lib/Utilities/Exception"
|
||||
"Lib/Utilities/Exception",
|
||||
"Lib/Utilities/Assert",
|
||||
"Lib/Utilities/NotificationCenter"
|
||||
],
|
||||
|
||||
function (Box2D, Exception) {
|
||||
function (Box2D, Exception, Assert, Nc) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
|
@ -13,6 +15,10 @@ function (Box2D, Exception) {
|
|||
var def = this.getBodyDef();
|
||||
def.userData = this;
|
||||
this.body = physicsEngine.getWorld().CreateBody(def);
|
||||
|
||||
this.ncTokens = (this.ncTokens || []).concat([
|
||||
Nc.on(Nc.ns.client.game.events.destroy, this.destroy, this)
|
||||
]);
|
||||
}
|
||||
|
||||
GameObject.prototype.getBodyDef = function() {
|
||||
|
|
@ -20,11 +26,14 @@ function (Box2D, Exception) {
|
|||
};
|
||||
|
||||
GameObject.prototype.destroy = function() {
|
||||
|
||||
if(this.body instanceof Box2D.Dynamics.b2Body) {
|
||||
this.body.GetWorld().DestroyBody(this.body);
|
||||
} else {
|
||||
throw new Exception("can not destroy body");
|
||||
}
|
||||
|
||||
Nc.off(this.ncTokens);
|
||||
};
|
||||
|
||||
GameObject.prototype.getBody = function() {
|
||||
|
|
@ -34,6 +43,20 @@ function (Box2D, Exception) {
|
|||
GameObject.prototype.getPosition = function() {
|
||||
return this.body.GetPosition().Copy();
|
||||
};
|
||||
|
||||
GameObject.prototype.setUpdateData = function(update) {
|
||||
|
||||
Assert.number(update.p.x, update.p.y);
|
||||
Assert.number(update.a);
|
||||
Assert.number(update.lv.x, update.lv.y);
|
||||
Assert.number(update.av);
|
||||
|
||||
this.body.SetAwake(true);
|
||||
this.body.SetPosition(update.p);
|
||||
this.body.SetAngle(update.a);
|
||||
this.body.SetLinearVelocity(update.lv);
|
||||
this.body.SetAngularVelocity(update.av);
|
||||
};
|
||||
|
||||
return GameObject;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function (Parent, Box2D, Options, Settings, Exception, Nc, Assert) {
|
|||
this.body.SetBullet(true);
|
||||
}
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.add, "animated", this);
|
||||
Nc.trigger(Nc.ns.core.game.worldUpdateObjects.add, this);
|
||||
}
|
||||
|
||||
Item.prototype = Object.create(Parent.prototype);
|
||||
|
|
@ -158,7 +158,7 @@ function (Parent, Box2D, Options, Settings, Exception, Nc, Assert) {
|
|||
};
|
||||
|
||||
Item.prototype.destroy = function() {
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.remove, "animated", this);
|
||||
Nc.trigger(Nc.ns.core.game.worldUpdateObjects.remove, this);
|
||||
Parent.prototype.destroy.call(this);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -378,7 +378,6 @@ function (Parent, Box2D, Settings, Nc, Assert, Options, ItemSettings) {
|
|||
|
||||
RagDoll.prototype.destroy = function() {
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.remove, "animated", this);
|
||||
var world = this.body.GetWorld();
|
||||
|
||||
for (var name in this.limbs) {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ function (Parent, RubeLoader, Box2D, Settings, Assert, Nc, RubeDollJson) {
|
|||
|
||||
RubeDoll.prototype.destroy = function() {
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.remove, "animated", this);
|
||||
var world = this.body.GetWorld();
|
||||
|
||||
for (var name in this.limbs) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ function (Parent, Box2D, Settings, Exception, Nc, Assert) {
|
|||
this.options = options;
|
||||
Parent.call(this, physicsEngine, uid);
|
||||
this.createPhysicTile(this.options);
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.add, "fixed", this);
|
||||
}
|
||||
|
||||
Tile.prototype = Object.create(Parent.prototype);
|
||||
|
|
@ -119,10 +117,6 @@ function (Parent, Box2D, Settings, Exception, Nc, Assert) {
|
|||
Tile.prototype.addVec = function (vs, m1, m2) {
|
||||
return vs.push(new Box2D.Common.Math.b2Vec2(this.mkArg(m1), this.mkArg(m2)));
|
||||
};
|
||||
|
||||
Tile.prototype.destroy = function() {
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.remove, "fixed", this);
|
||||
};
|
||||
|
||||
return Tile;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ function (Doll, Settings, Nc, Exception, ColorConverter, SpectatorDoll, RubeDoll
|
|||
this.spawned = false;
|
||||
this.holdingItem = null;
|
||||
this.spectatorDoll = new SpectatorDoll(this.physicsEngine, "spectatorDoll-" + this.id, this);
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this);
|
||||
}
|
||||
|
||||
Player.prototype.getNickname = function() {
|
||||
|
|
@ -161,7 +159,7 @@ function (Doll, Settings, Nc, Exception, ColorConverter, SpectatorDoll, RubeDoll
|
|||
|
||||
Player.prototype.destroy = function () {
|
||||
|
||||
Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this);
|
||||
// FIXME add destroy nc hook
|
||||
|
||||
if(this.holdingItem) {
|
||||
var options = {
|
||||
|
|
@ -174,8 +172,10 @@ function (Doll, Settings, Nc, Exception, ColorConverter, SpectatorDoll, RubeDoll
|
|||
|
||||
this.spectatorDoll.destroy();
|
||||
|
||||
// doll destoys itself at the end cause its a gameobject
|
||||
// but on userLeft, the player has to destroy it.
|
||||
if(this.doll) {
|
||||
this.doll.destroy();
|
||||
this.doll.destroy();
|
||||
}
|
||||
|
||||
if(this.playerController) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue