Compare commits

..

No commits in common. "master" and "v0.0.1" have entirely different histories.

1028 changed files with 8268 additions and 64227 deletions

1
.gitignore vendored
View file

@ -4,4 +4,3 @@ node_modules/
lab/audio/ lab/audio/
lab/filter/ lab/filter/
static/items/rube/*-backups static/items/rube/*-backups
build/

View file

@ -3,9 +3,7 @@ chuck.js
Physical JavaScript Action Browser Multiplayer Game - it will be awesome! Physical JavaScript Action Browser Multiplayer Game - it will be awesome!
<a href="http://chuck-game.tumblr.com/about" title="Play the chuck trailer" target="_blank"> [![Foo](http://25.media.tumblr.com/8249dcd3bdb176686421d1914937db1c/tumblr_mzc1ejGxNC1ry8awho1_400.png)](http://chuck-game.tumblr.com/ "Screenshot of chuck.js - click to visit our development blog!")
<img src="https://cloud.githubusercontent.com/assets/692826/8396811/3369df82-1db6-11e5-939f-5ceeba64d802.png">
</a>
Follow the development at http://chuck-game.tumblr.com/ Follow the development at http://chuck-game.tumblr.com/

View file

@ -1,74 +1,92 @@
define([ define([
'express',
'http', 'http',
'path', 'node-static',
'Server/Api', 'Server/Api'
'fs'
], ],
function (express, http, path, Api, fs) { function (http, nodeStatic, Api) {
"use strict";
function HttpServer (options, coordinator) { function HttpServer (options, coordinator) {
options.port = options.port || 1234; options.port = options.port || 1234;
options.caching = typeof options.caching != 'undefined' ? options.caching : 3600;
options.rootDirectory = options.rootDirectory || './'; options.rootDirectory = options.rootDirectory || './';
this.server = null;
this.api = new Api(coordinator); this.api = new Api(coordinator);
this.app = express();
this.server = http.createServer(this.app);
this.init(options); this.init(options);
} }
HttpServer.prototype.init = function (options) { HttpServer.prototype.init = function (options) {
var self = this; var self = this;
var app = this.app;
// Serve static files var fileServer = new nodeStatic.Server(options.rootDirectory, { cache: options.caching });
app.use('/static', express.static(path.join(options.rootDirectory, 'static')));
app.use('/app', express.static(path.join(options.rootDirectory, 'app')));
// Serve index.html at root this.server = http.createServer(
app.get('/', function(req, res) { function (req, res) {
res.sendFile(path.resolve(options.rootDirectory, 'static/html/index.html'));
var fullBody = '';
req.addListener('data', function(chunk) { // doesn't work on Jeenas computer without this
fullBody += chunk.toString();
}); });
// Serve client.js and minified version req.addListener('error', function(err) {
app.get('/client.js', function(req, res) { console.log('');
if (process.env.NODE_ENV === 'production' && fs.existsSync(path.resolve(options.rootDirectory, 'build/client.min.js'))) { });
res.sendFile(path.resolve(options.rootDirectory, 'build/client.min.js'));
} else {
res.sendFile(path.resolve(options.rootDirectory, 'client.js')); req.addListener('end', function () {
switch(true) {
case req.url == '/':
fileServer.serveFile('./static/html/index.html', 200, {}, req, res);
console.checkpoint('HTTP Server serves index');
break;
case req.url == '/game.html':
fileServer.serveFile('./static/html/game.html', 200, {}, req, res);
console.checkpoint('HTTP Server serves game');
break;
case req.url == '/client.js':
fileServer.serveFile('./client.js', 200, {}, req, res);
break;
case req.url == '/require.js':
fileServer.serveFile('./node_modules/requirejs/require.js', 200, {}, req, res);
break;
case req.url == '/screenfull.js':
fileServer.serveFile('./node_modules/screenfull/dist/screenfull.js', 200, {}, req, res);
break;
case req.url == '/api':
self.api.handleCall(fullBody);
var status = self.api.isError ? 400 : 200;
res.writeHead(status, {"Content-Type": self.api.getContentType()});
res.end(self.api.getOutput());
self.api.isError = false;
break;
case new RegExp(/^\/app/).test(req.url):
fileServer.serve(req, res, function () {
self.handleFileError(res)
});
break;
case new RegExp(/^\/static/).test(req.url):
fileServer.serve(req, res, function () {
self.handleFileError(res)
});
break;
default:
self.handleFileError(res);
break;
} }
}); });
app.get('/client.min.js', function(req, res) { }
res.sendFile(path.resolve(options.rootDirectory, 'build/client.min.js')); );
});
// Serve require.js, screenfull.js, chart.js from node_modules
app.get('/require.js', function(req, res) {
res.sendFile(path.resolve(options.rootDirectory, 'node_modules/requirejs/require.js'));
});
app.get('/screenfull.js', function(req, res) {
res.sendFile(path.resolve(options.rootDirectory, 'static/vendor/screenfull.js'));
});
app.get('/chart.js', function(req, res) {
// Chart.js v4 uses 'dist/chart.umd.js'
res.sendFile(path.resolve(options.rootDirectory, 'node_modules/chart.js/dist/chart.umd.js'));
});
// API endpoint
app.post('/api', express.text({type: '*/*'}), function(req, res) {
self.api.handleCall(req.body);
var status = self.api.isError ? 400 : 200;
res.status(status).type(self.api.getContentType()).send(self.api.getOutput());
self.api.isError = false;
});
// 404 handler
app.use(function(req, res) {
res.status(404).send('<h1>404 not ... found</h1>');
});
this.server.once('error', function(err) { this.server.once('error', function(err) {
if(err.code == 'EADDRINUSE') { if(err.code == 'EADDRINUSE') {
@ -79,6 +97,7 @@ function (express, http, path, Api, fs) {
}); });
this.server.listen(options.port); this.server.listen(options.port);
console.checkpoint('start HTTP server'); console.checkpoint('start HTTP server');
} }
@ -86,5 +105,10 @@ function (express, http, path, Api, fs) {
return this.server; return this.server;
} }
HttpServer.prototype.handleFileError = function (res) {
res.writeHead(404, {'Content-Type': 'text/html'});
res.end('<h1>404 not ... found</h1>');
}
return HttpServer; return HttpServer;
}); });

View file

@ -4,23 +4,29 @@ define([
function (io) { function (io) {
"use strict";
function Socket (server, options, coordinator) { function Socket (server, options, coordinator) {
options.logLevel = typeof options.logLevel != 'undefined'
? options.logLevel
: 0;
this.coordinator = coordinator; this.coordinator = coordinator;
this.io = io(server, { this.socket = io.listen(server);
// No more 'log level' or 'transports' in v4
// Add any v4-compatible options here if needed
});
this.init(options); this.init(options);
} }
Socket.prototype.init = function (options) { Socket.prototype.init = function (options) {
var self = this; var self = this;
this.io.on('connection', function (socket) { this.socket.configure('development', function () {
console.checkpoint('socket receiving connection'); this.set('log level', options.logLevel);
self.onConnection(socket);
}); });
this.socket.on('connection', function (user) {
console.checkpoint('socket receiving connection');
self.onConnection(user);
});
console.checkpoint('start Socket Listener'); console.checkpoint('start Socket Listener');
} }

View file

@ -1,783 +0,0 @@
{
"allowSleep" : true,
"autoClearForces" : true,
"body" :
[
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.04692989960312843,
0.04692989960312843,
-0.04693000018596649,
-0.04693000018596649
],
"y" :
[
-0.1895969957113266,
0.1895969957113266,
0.1895969957113266,
-0.1895969957113266
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0004525936674326658,
"massData-center" :
{
"x" : -5.029141902923584e-08,
"y" : 0
},
"massData-mass" : 0.03559110686182976,
"name" : "upperLeftArm",
"position" :
{
"x" : -0.1165359988808632,
"y" : 0.9012569785118103
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture2",
"polygon" :
{
"vertices" :
{
"x" :
[
0.1366278976202011,
0.1366278976202011,
-0.1360991001129150,
-0.1360991001129150
],
"y" :
[
-0.3788780868053436,
0.3830279111862183,
0.3830279111862183,
-0.3788780868053436
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.01134084537625313,
"massData-center" :
{
"x" : 0.0002643987536430359,
"y" : 0.002074912190437317
},
"massData-mass" : 0.2077923566102982,
"name" : "chest",
"position" :
{
"x" : 0.0007875636219978333,
"y" : 0.7995355725288391
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"circle" :
{
"center" :
{
"x" : -0.01561669446527958,
"y" : 0.004700659774243832
},
"radius" : 0.2268356680870056
},
"density" : 0.2204959988594055,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture1"
}
],
"linearVelocity" : 0,
"massData-I" : 0.0009264730615541339,
"massData-center" :
{
"x" : -0.01561669446527958,
"y" : 0.004700659774243832
},
"massData-mass" : 0.03564291819930077,
"name" : "head",
"position" :
{
"x" : 0.02309736609458923,
"y" : 1.497289657592773
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.04693000018596649,
0.04693000018596649,
-0.04693005979061127,
-0.04693005979061127
],
"y" :
[
-0.1159216761589050,
0.1159217953681946,
0.1159217953681946,
-0.1159216761589050
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0001134485355578363,
"massData-center" :
{
"x" : -2.980232238769531e-08,
"y" : 5.960464477539062e-08
},
"massData-mass" : 0.02176084183156490,
"name" : "lowerRightArm",
"position" :
{
"x" : 0.1183081120252609,
"y" : 0.6842151284217834
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.07039500027894974,
0.07039500027894974,
-0.07039500027894974,
-0.07039500027894974
],
"y" :
[
-0.09294360131025314,
0.1277720034122467,
0.1277720034122467,
-0.09294360131025314
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0001869037223514169,
"massData-center" :
{
"x" : 0,
"y" : 0.01741420105099678
},
"massData-mass" : 0.03107454814016819,
"name" : "lowerLeftLeg",
"position" :
{
"x" : -0.03829947486519814,
"y" : 0.09799569845199585
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.04693000763654709,
0.04693000763654709,
-0.04692991077899933,
-0.04692991077899933
],
"y" :
[
-0.1159216761589050,
0.1159217953681946,
0.1159217953681946,
-0.1159216761589050
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0001134483172791079,
"massData-center" :
{
"x" : 4.842877032729120e-08,
"y" : 5.960464477539062e-08
},
"massData-mass" : 0.02176081016659737,
"name" : "lowerLeftArm",
"position" :
{
"x" : -0.1165381968021393,
"y" : 0.6842151284217834
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.04693000018596649,
0.04693000018596649,
-0.04693010076880455,
-0.04693010076880455
],
"y" :
[
-0.1895969957113266,
0.1895969957113266,
0.1895969957113266,
-0.1895969957113266
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0004525947733782232,
"massData-center" :
{
"x" : -5.029141902923584e-08,
"y" : 0
},
"massData-mass" : 0.03559118881821632,
"name" : "upperRightArm",
"position" :
{
"x" : 0.1183080002665520,
"y" : 0.9012569785118103
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.07039496302604675,
0.07039496302604675,
-0.07039486616849899,
-0.07039486616849899
],
"y" :
[
-0.1890522241592407,
0.1890524625778198,
0.1890524625778198,
-0.1890522241592407
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0007221315754577518,
"massData-center" :
{
"x" : 4.842877388000488e-08,
"y" : 1.192092895507812e-07
},
"massData-mass" : 0.05323329567909241,
"name" : "upperRightLeg",
"position" :
{
"x" : 0.03859551250934601,
"y" : 0.3325110077857971
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.07039505988359451,
0.07039505988359451,
-0.07039495557546616,
-0.07039495557546616
],
"y" :
[
-0.1890522241592407,
0.1890524625778198,
0.1890524625778198,
-0.1890522241592407
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.000722132739610970,
"massData-center" :
{
"x" : 5.215406417846680e-08,
"y" : 1.192092824453539e-07
},
"massData-mass" : 0.05323336645960808,
"name" : "upperLeftLeg",
"position" :
{
"x" : -0.03829947486519814,
"y" : 0.3325110077857971
},
"type" : 2
},
{
"angle" : 0,
"angularVelocity" : 0,
"awake" : true,
"fixture" :
[
{
"density" : 1,
"filter-groupIndex" : -55,
"friction" : 0.2,
"name" : "fixture3",
"polygon" :
{
"vertices" :
{
"x" :
[
0.07039500027894974,
0.07039500027894974,
-0.07039490342140198,
-0.07039490342140198
],
"y" :
[
-0.09294389933347702,
0.1276109963655472,
0.1276109963655472,
-0.09294389933347702
]
}
}
}
],
"linearVelocity" : 0,
"massData-I" : 0.0001864968799054623,
"massData-center" :
{
"x" : 4.842877032729120e-08,
"y" : 0.01733354665338993
},
"massData-mass" : 0.03105190023779869,
"name" : "lowerRightLeg",
"position" :
{
"x" : 0.03859551250934601,
"y" : 0.09799569845199585
},
"type" : 2
}
],
"collisionbitplanes" :
{
"names" :
[
"bitplane1",
"bitplane2",
"bitplane3",
"bitplane4",
"bitplane5",
"bitplane6",
"bitplane7",
"bitplane8",
"bitplane9",
"bitplane10",
"bitplane11",
"bitplane12",
"bitplane13",
"bitplane14",
"bitplane15",
"bitplane16",
"bitplane17",
"bitplane18",
"bitplane19",
"bitplane20",
"bitplane21",
"bitplane22",
"bitplane23",
"bitplane24",
"bitplane25",
"bitplane26",
"bitplane27",
"bitplane28",
"bitplane29",
"bitplane30",
"bitplane31",
"bitplane32"
]
},
"continuousPhysics" : true,
"gravity" :
{
"x" : 0,
"y" : -10
},
"joint" :
[
{
"anchorA" :
{
"x" : 0.0003538504242897034,
"y" : 0.07107692956924438
},
"anchorB" :
{
"x" : 0.0003536641597747803,
"y" : -0.1459649801254272
},
"bodyA" : 3,
"bodyB" : 6,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : 0.01745329238474369,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint1",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 1.919862151145935
},
{
"anchorA" :
{
"x" : -0.0007802955806255341,
"y" : -0.1484909951686859
},
"anchorB" :
{
"x" : -0.0007801018655300140,
"y" : 0.08614099025726318
},
"bodyA" : 8,
"bodyB" : 4,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : 0.01745329238474369,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint7",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 2.443460941314697
},
{
"anchorA" :
{
"x" : -0.004979588091373444,
"y" : -0.1506859958171844
},
"anchorB" :
{
"x" : -0.005973689258098602,
"y" : 0.08482310175895691
},
"bodyA" : 7,
"bodyB" : 9,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : 0.01745329238474369,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint8",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 2.443460941314697
},
{
"anchorA" :
{
"x" : -0.06799955666065216,
"y" : -0.3021813035011292
},
"anchorB" :
{
"x" : -0.02891255542635918,
"y" : 0.1648437976837158
},
"bodyA" : 1,
"bodyB" : 8,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -0.7853981852531433,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint6",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 1.570796370506287
},
{
"anchorA" :
{
"x" : 0.06260262429714203,
"y" : -0.3029872477054596
},
"anchorB" :
{
"x" : 0.02294230461120605,
"y" : 0.1640380322933197
},
"bodyA" : 1,
"bodyB" : 7,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -0.7853981852531433,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint5",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 1.570796370506287
},
{
"anchorA" :
{
"x" : 0.1179294362664223,
"y" : 0.2464744448661804
},
"anchorB" :
{
"x" : 0.0004089996218681335,
"y" : 0.1447530388832092
},
"bodyA" : 1,
"bodyB" : 6,
"enableLimit" : false,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -2.268928050994873,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint2",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 3.141592741012573
},
{
"anchorA" :
{
"x" : -0.1188285648822784,
"y" : 0.2521644234657288
},
"anchorB" :
{
"x" : -0.001505002379417419,
"y" : 0.1504430174827576
},
"bodyA" : 1,
"bodyB" : 0,
"enableLimit" : false,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -2.268928050994873,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint3",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 3.141592741012573
},
{
"anchorA" :
{
"x" : 0.0008554458618164062,
"y" : -0.1461489796638489
},
"anchorB" :
{
"x" : 0.0008557140827178955,
"y" : 0.07089227437973022
},
"bodyA" : 0,
"bodyB" : 5,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -1.919862151145935,
"maxMotorTorque" : 1,
"motorSpeed" : 0,
"name" : "joint4",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 0.01745329238474369
},
{
"anchorA" :
{
"x" : 0.02210754156112671,
"y" : 0.4607425332069397
},
"anchorB" :
{
"x" : -0.02544101513922215,
"y" : -0.2591779232025146
},
"bodyA" : 1,
"bodyB" : 2,
"enableLimit" : true,
"enableMotor" : false,
"jointSpeed" : 0,
"lowerLimit" : -0.6981316804885864,
"maxMotorTorque" : 0,
"motorSpeed" : 0,
"name" : "joint9",
"refAngle" : 0,
"type" : "revolute",
"upperLimit" : 1.221730470657349
}
],
"positionIterations" : 3,
"stepsPerSecond" : 60.0,
"subStepping" : false,
"velocityIterations" : 8,
"warmStarting" : true
}

View file

@ -3,13 +3,11 @@
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Game/Channel/User", "Game/Channel/User",
"Lib/Utilities/Protocol/Helper", "Lib/Utilities/Protocol/Helper",
"Lib/Utilities/OptionsHelper", "Lib/Utilities/Options",
"Game/Config/Settings" "Game/Config/Settings"
], ],
function (GameController, nc, User, ProtocolHelper, optionsHelper, Settings) { function (GameController, Nc, User, ProtocolHelper, Options, Settings) {
"use strict";
function Channel (pipeToServer, options) { function Channel (pipeToServer, options) {
@ -19,25 +17,24 @@
this.users = {}; this.users = {};
this.pipeToServer = pipeToServer; this.pipeToServer = pipeToServer;
this.levelListIndex = -1; this.levelListIndex = -1;
this.gameController = null;
this.options = options = optionsHelper.merge(options, { this.options = options = Options.merge(options, {
levelUids: Settings.CHANNEL_DEFAULT_LEVELS levelUids: Settings.CHANNEL_DEFAULT_LEVELS
}); });
// Notification Center // Notification Center
nc.on(nc.ns.channel.events.round.end, this.onEndRound, this); Nc.on(Nc.ns.channel.events.round.end, this.onEndRound, this);
nc.on(nc.ns.channel.events.controlCommand.channel, function (message) { Nc.on(Nc.ns.channel.events.controlCommand.channel, function (message) {
ProtocolHelper.applyCommand(message.data, self); ProtocolHelper.applyCommand(message.data, self);
}); });
nc.on(nc.ns.channel.to.client.gameCommand.broadcast, this.broadcastGameCommand, this); Nc.on(Nc.ns.channel.to.client.gameCommand.broadcast, this.broadcastGameCommand, this);
nc.on(nc.ns.channel.to.client.controlCommand.broadcast, this.broadcastControlCommand, this); Nc.on(Nc.ns.channel.to.client.controlCommand.broadcast, this.broadcastControlCommand, this);
//nc.on(nc.ns.channel.to.client.gameCommand.broadcastExcept, this.broadcastGameCommandExcept, this); //Nc.on(Nc.ns.channel.to.client.gameCommand.broadcastExcept, this.broadcastGameCommandExcept, this);
//nc.on(nc.ns.channel.to.client.controlCommand.broadcastExcept, this.broadcastControlCommandExcept, this); //Nc.on(Nc.ns.channel.to.client.controlCommand.broadcastExcept, this.broadcastControlCommandExcept, this);
this.beginRound(); this.beginRound();
console.checkpoint("channel " + this.name + " created"); console.checkpoint('channel ' + this.name + ' created');
setTimeout(function() { setTimeout(function() {
if(Object.keys(self.users).length < 1) { if(Object.keys(self.users).length < 1) {
@ -56,7 +53,7 @@
if(this.gameController) { if(this.gameController) {
this.gameController.destroy(); this.gameController.destroy();
this.gameController = null; delete this.gameController;
} }
var gameControllerOptions = { var gameControllerOptions = {
@ -82,7 +79,6 @@
Channel.prototype.onEndRound = function() { Channel.prototype.onEndRound = function() {
var self = this; var self = this;
this.gameController.endRound();
this.broadcastControlCommand("endRound", true); this.broadcastControlCommand("endRound", true);
console.checkpoint("End Round (" + this.name + ") - Begin Round in " + Settings.CHANNEL_END_ROUND_TIME + " seconds"); console.checkpoint("End Round (" + this.name + ") - Begin Round in " + Settings.CHANNEL_END_ROUND_TIME + " seconds");
@ -103,23 +99,23 @@
}; };
if(!this.gameController.level || !this.gameController.level.isLoaded) { if(!this.gameController.level || !this.gameController.level.isLoaded) {
var token = nc.on(nc.ns.core.game.events.level.loaded, function() { var token = Nc.on(Nc.ns.core.game.events.level.loaded, function() {
self.sendJoinSuccess(options); self.sendJoinSuccess(options);
self.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions);
nc.off(token); Nc.off(token);
}); });
} else { } else {
this.sendJoinSuccess(options); self.sendJoinSuccess(options);
this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions);
} }
}; }
Channel.prototype.sendJoinSuccess = function(options) { Channel.prototype.sendJoinSuccess = function(options) {
var user = new User(options.id, options); var user = new User(options.id, options);
var joinedUsers = []; var joinedUsers = [];
for(var userId in this.users) { for(var userId in this.users) {
joinedUsers.push(this.users[userId].options); joinedUsers.push(this.users[userId].options)
} }
var levelUid = null; var levelUid = null;
@ -129,22 +125,23 @@
this.users[user.id] = user; this.users[user.id] = user;
options = { var options = {
user: user.options, user: user.options,
joinedUsers: joinedUsers, joinedUsers: joinedUsers,
levelUid: levelUid levelUid: levelUid
}; };
//nc.trigger("user/" + user.id + "/joinSuccess", options); //Nc.trigger('user/' + user.id + "/joinSuccess", options);
user.sendControlCommand("joinSuccess", options); user.sendControlCommand("joinSuccess", options);
nc.trigger(nc.ns.channel.events.user.joined, user); Nc.trigger(Nc.ns.channel.events.user.joined, user);
this.broadcastControlCommandExcept("userJoined", user.options, user); this.broadcastControlCommandExcept("userJoined", user.options, user);
}; };
Channel.prototype.onReleaseUser = function (userId) { Channel.prototype.onReleaseUser = function (userId) {
var self = this; var self = this;
nc.trigger(nc.ns.channel.events.user.left, userId); var user = this.users[userId];
Nc.trigger(Nc.ns.channel.events.user.left, userId);
delete this.users[userId]; delete this.users[userId];
this.broadcastControlCommand("userLeft", userId); this.broadcastControlCommand("userLeft", userId);
@ -161,7 +158,7 @@
} }
}, Settings.CHANNEL_DESTRUCTION_TIME * 1000); }, Settings.CHANNEL_DESTRUCTION_TIME * 1000);
} }
}; }
Channel.prototype.destroy = function() { Channel.prototype.destroy = function() {
console.checkpoint("channel (" + this.name + ") destroyed"); console.checkpoint("channel (" + this.name + ") destroyed");
@ -175,7 +172,7 @@
for(var id in this.users) { for(var id in this.users) {
this.users[id].sendControlCommand(command, options); this.users[id].sendControlCommand(command, options);
} }
}; }
Channel.prototype.broadcastControlCommandExcept = function (command, options, exceptUser) { Channel.prototype.broadcastControlCommandExcept = function (command, options, exceptUser) {
for(var id in this.users) { for(var id in this.users) {
@ -183,13 +180,13 @@
this.users[id].sendControlCommand(command, options); this.users[id].sendControlCommand(command, options);
} }
} }
}; }
Channel.prototype.broadcastGameCommand = function (command, options) { Channel.prototype.broadcastGameCommand = function (command, options) {
for(var id in this.users) { for(var id in this.users) {
this.users[id].sendGameCommand(command, options); this.users[id].sendGameCommand(command, options);
} }
}; }
Channel.prototype.broadcastGameCommandExcept = function (command, options, exceptUser) { Channel.prototype.broadcastGameCommandExcept = function (command, options, exceptUser) {
for(var id in this.users) { for(var id in this.users) {
@ -197,7 +194,7 @@
this.users[id].sendGameCommand(command, options); this.users[id].sendGameCommand(command, options);
} }
} }
}; }
return Channel; return Channel;

View file

@ -4,8 +4,6 @@ define([
function (Parent) { function (Parent) {
"use strict";
function Detector () { function Detector () {
Parent.call(this); Parent.call(this);
} }

View file

@ -5,9 +5,7 @@ define([
"Game/Config/Settings" "Game/Config/Settings"
], ],
function(Parent, nc, Parser, Settings) { function(Parent, Nc, Parser, Settings) {
"use strict";
function PlayerController(player) { function PlayerController(player) {
@ -35,34 +33,31 @@ function(Parent, nc, Parser, Settings) {
}; };
PlayerController.prototype.handActionRequest = function(options) { PlayerController.prototype.handActionRequest = function(options) {
options.x = parseFloat(options.x) || 0.0; if (options) this.player.handActionRequest(options.x, options.y);
options.y = parseFloat(options.y) || 0.0;
options.av = parseFloat(options.av) || 0.0;
if (options) this.player.handActionRequest(options);
}; };
PlayerController.prototype.suicide = function() { PlayerController.prototype.suicide = function() {
this.player.suicide(); this.player.suicide();
}; };
PlayerController.prototype.mePositionStateOverride = function(update) { PlayerController.prototype.mePositionStateUpdate = function(update) {
if(!this.player.isSpawned()) { if(!this.player.doll) {
// if someone still falls but is dead on the server already console.warn('me state update, even though doll does not exist');
return; return;
} }
var difference = { var difference = {
x: Math.abs(update.p.x - this.player.doll.body.GetPosition().x), x: Math.abs(update.p.x - this.player.doll.body.GetPosition().x),
y: Math.abs(update.p.y - this.player.doll.body.GetPosition().y) y: Math.abs(update.p.y - this.player.doll.body.GetPosition().y)
}; }
if(difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS && if(difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS
difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) { && difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) {
this.player.doll.updatePositionState(update); this.player.doll.updatePositionState(update);
} else { } else {
// HARD UPDATE FOR SELF // HARD UPDATE FOR SELF
console.log(this.player.user.options.nickname + " is cheating."); console.log(this.player.user.options.nickname + ' is cheating.')
var body = this.player.doll.body; var body = this.player.doll.body;
@ -71,7 +66,7 @@ function(Parent, nc, Parser, Settings) {
lv: body.GetLinearVelocity() lv: body.GetLinearVelocity()
}; };
nc.trigger(nc.ns.channel.to.client.user.gameCommand.send + this.player.id, "positionStateReset", options); Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, 'positionStateReset', options);
} }
}; };

View file

@ -2,40 +2,39 @@ define([
"Game/Core/GameController", "Game/Core/GameController",
"Game/Channel/Physics/Engine", "Game/Channel/Physics/Engine",
"Game/Config/Settings", "Game/Config/Settings",
"Game/Channel/Control/PlayerController",
"Lib/Utilities/RequestAnimFrame", "Lib/Utilities/RequestAnimFrame",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Game/Channel/Player", "Game/Channel/Player",
"Game/Channel/GameObjects/GameObject", "Game/Channel/GameObjects/GameObject",
"Game/Channel/GameObjects/Doll", "Game/Channel/GameObjects/Doll",
"Game/Channel/GameObjects/Items/RubeDoll" "Game/Channel/GameObjects/Items/RagDoll"
], ],
function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, GameObject, Doll, RubeDoll) { function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, Nc, Box2D, Player, GameObject, Doll, RagDoll) {
"use strict";
function GameController (options) { function GameController (options) {
this.animationTimeout = null; this.animationTimeout = null;
this.worldUpdateTimeout = null; this.worldUpdateTimeout = null;
this.spawnTimeouts = []; this.spawnTimeouts = [];
this.roundHasEnded = false;
Parent.call(this, options); Parent.call(this, options);
this.ncTokens = this.ncTokens.concat([ this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.channel.events.user.joined, this.onUserJoined, this), Nc.on(Nc.ns.channel.events.user.joined, this.onUserJoined, this),
nc.on(nc.ns.channel.events.user.left, this.onUserLeft, this), Nc.on(Nc.ns.channel.events.user.left, this.onUserLeft, this),
nc.on(nc.ns.channel.events.user.level.reset, this.onResetLevel, this), Nc.on(Nc.ns.channel.events.user.level.reset, this.onResetLevel, this),
nc.on(nc.ns.channel.events.user.client.ready, this.onClientReady, this), Nc.on(Nc.ns.channel.events.user.client.ready, this.onClientReady, this),
nc.on(nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this), Nc.on(Nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this),
nc.on(nc.ns.channel.events.game.player.killed, this.onPlayerKilled, this), Nc.on(Nc.ns.channel.events.game.player.killed, this.onPlayerKilled, this),
]); ]);
console.checkpoint('starting game controller for channel (' + options.channelName + ')'); console.checkpoint('starting game controller for channel (' + options.channelName + ')');
} }
GameController.prototype = Object.create(Parent.prototype); GameController.prototype = Object.create(Parent.prototype);
GameController.prototype.update = function () { GameController.prototype.update = function () {
@ -58,28 +57,15 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
this.createPlayer(user); this.createPlayer(user);
} }
GameController.prototype.onUserLeft = function (userId) {
var player = this.players[userId];
this.clearItemsOfPlayerFingerPrints(player);
Parent.prototype.onUserLeft.call(this, userId);
};
GameController.prototype.clearItemsOfPlayerFingerPrints = function(player) {
nc.trigger(nc.ns.channel.events.game.player.clearFingerPrints, player);
};
GameController.prototype.createPlayer = function(user) { GameController.prototype.createPlayer = function(user) {
var player = Parent.prototype.createPlayer.call(this, user);
var revealedGameController = { player.setPlayerController(new PlayerController(player))
isInBetweenRounds: this.isInBetweenRounds.bind(this)
};
var player = Parent.prototype.createPlayer.call(this, user, revealedGameController);
user.setPlayer(player); user.setPlayer(player);
}; };
GameController.prototype.onPlayerKilled = function(player, killedByPlayer) { GameController.prototype.onPlayerKilled = function(player, killedByPlayer) {
if(killedByPlayer.stats.score >= this.options.scoreLimit) { if(killedByPlayer.stats.score >= this.options.scoreLimit) {
nc.trigger(nc.ns.channel.events.round.end); Nc.trigger(Nc.ns.channel.events.round.end);
} else { } else {
this.spawnPlayer(player, Settings.RESPAWN_TIME); this.spawnPlayer(player, Settings.RESPAWN_TIME);
} }
@ -95,6 +81,8 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
var spawnTimeout = setTimeout(function() { var spawnTimeout = setTimeout(function() {
player.spawn(spawnPoint.x, spawnPoint.y); player.spawn(spawnPoint.x, spawnPoint.y);
// put it into
self.gameObjects.animated.push(player);
var options = { var options = {
id: player.id, id: player.id,
@ -102,7 +90,7 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
y: spawnPoint.y y: spawnPoint.y
}; };
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "spawnPlayer", options); Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "spawnPlayer", options);
var i = self.spawnTimeouts.indexOf(spawnTimeout); var i = self.spawnTimeouts.indexOf(spawnTimeout);
self.spawnTimeouts.splice(i, 1); self.spawnTimeouts.splice(i, 1);
@ -117,18 +105,17 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
var update = this.getWorldUpdateObject(false); var update = this.getWorldUpdateObject(false);
if(Object.getOwnPropertyNames(update).length > 0) { if(Object.getOwnPropertyNames(update).length > 0) {
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "worldUpdate", update); Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, 'worldUpdate', update);
} }
this.worldUpdateTimeout = setTimeout(this.updateWorld.bind(this), Settings.NETWORK_UPDATE_INTERVAL); this.worldUpdateTimeout = setTimeout(this.updateWorld.bind(this), Settings.NETWORK_UPDATE_INTERVAL);
}; }
GameController.prototype.getWorldUpdateObject = function(getSleeping) { GameController.prototype.getWorldUpdateObject = function(getSleeping) {
getSleeping = getSleeping || false; getSleeping = getSleeping || false;
var update = {}; var update = {};
/*
var body = this.physicsEngine.world.GetBodyList(); var body = this.physicsEngine.world.GetBodyList();
do { do {
if((getSleeping || body.IsAwake()) && body.GetType() === Box2D.Dynamics.b2Body.b2_dynamicBody) { if((getSleeping || body.IsAwake()) && body.GetType() === Box2D.Dynamics.b2Body.b2_dynamicBody) {
@ -136,33 +123,22 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
if (userData instanceof GameObject) { if (userData instanceof GameObject) {
var gameObject = userData; var gameObject = userData;
var updateData = gameObject.getUpdateData();
if (updateData) { update[gameObject.uid] = {
update[gameObject.uid] = updateData; p: body.GetPosition(),
a: body.GetAngle(),
lv: body.GetLinearVelocity(),
av: body.GetAngularVelocity()
};
if(gameObject instanceof Doll) {
update[gameObject.uid].as = gameObject.getActionState();
update[gameObject.uid].laxy = gameObject.lookAtXY;
} }
} }
} }
} while (body = body.GetNext()); } while (body = body.GetNext());
*/
for (var uid in this.worldUpdateObjects) {
var gameObject = this.worldUpdateObjects[uid];
if (!(gameObject instanceof GameObject)) {
console.warn('Cant find object ' + uid + ' in worldUpdateObjects pool (channel side), here is the object:');
console.log(gameObject);
continue;
}
var updateData = gameObject.getUpdateData(getSleeping);
if (updateData) {
update[gameObject.uid] = updateData;
}
}
return update; return update;
}; };
@ -171,7 +147,7 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
var spawnedPlayers = []; var spawnedPlayers = [];
for(var id in this.players) { for(var id in this.players) {
var player = this.players[id]; var player = this.players[id];
if(player.isSpawned()) { if(player.isSpawned) {
var options = { var options = {
id: id, id: id,
@ -190,36 +166,23 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
return spawnedPlayers; return spawnedPlayers;
}; };
GameController.prototype._getRuntimeItems = function() { GameController.prototype.getRuntimeItems = function() {
var objects = []
var runtimeItems = []; for (var i = 0; i < this.gameObjects.animated.length; i++) {
for (var uid in this.worldUpdateObjects) { if(this.gameObjects.animated[i] instanceof RagDoll) {
if(this.worldUpdateObjects[uid] instanceof RubeDoll) { var object = this.gameObjects.animated[i];
var object = this.worldUpdateObjects[uid];
runtimeItems.push(object);
}
}
return runtimeItems;
};
GameController.prototype.gatherRuntimeItemsForWorldUpdate = function() {
var infos = [];
var runtimeItems = this._getRuntimeItems();
// On the other side this is using the level.createItem mechanism to
// create the RubeDoll from its ItemSettings
for (var i = 0; i < runtimeItems.length; i++) {
var object = runtimeItems[i];
var options = object.options; var options = object.options;
options.x = object.getPosition().x; options.x = object.getPosition().x;
options.y = object.getPosition().y; options.y = object.getPosition().y;
infos.push({ objects.push({
uid: object.uid, uid: object.uid,
options: object.options options: object.options
}); });
} }
};
return infos; return objects;
}; };
GameController.prototype.onClientReady = function(userId) { GameController.prototype.onClientReady = function(userId) {
@ -228,34 +191,21 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
var options = { var options = {
spawnedPlayers: this.getSpawnedPlayersAndTheirPositions(), spawnedPlayers: this.getSpawnedPlayersAndTheirPositions(),
worldUpdate: this.getWorldUpdateObject(true), worldUpdate: this.getWorldUpdateObject(true),
runtimeItems: this.gatherRuntimeItemsForWorldUpdate(), runtimeItems: this.getRuntimeItems(),
userId: userId userId: userId
}; }
nc.trigger(nc.ns.channel.to.client.user.gameCommand.send + userId, "clientReadyResponse", options); Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + userId, "clientReadyResponse", options);
this.spawnPlayer(player, 0); this.spawnPlayer(player, 0);
}; };
GameController.prototype.endRound = function() {
this.roundHasEnded = true;
for(var id in this.players) {
this.players[id].setInBetweenRounds(true);
}
};
GameController.prototype.isInBetweenRounds = function() {
return this.roundHasEnded;
};
// FIXME: remove this method
GameController.prototype.onResetLevel = function(userId) { GameController.prototype.onResetLevel = function(userId) {
console.log('OH NO!!! ON RESET LEVEL IS CALLED AND RESPAWNES PLAYERS'); console.log('OH NO!!! ON RESET LEVEL IS CALLED AND RESPAWNES PLAYERS');
Parent.prototype.onResetLevel.call(this); Parent.prototype.onResetLevel.call(this);
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "resetLevel", true); Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "resetLevel", true);
for (var key in this.players) { for (var key in this.players) {
this.spawnPlayer(this.players[key]); this.spawnPlayer(this.players[key]);
} }
@ -269,11 +219,6 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player,
clearTimeout(this.spawnTimeouts[i]); clearTimeout(this.spawnTimeouts[i]);
}; };
var runtimeItems = this._getRuntimeItems();
for (var i = 0; i < runtimeItems.length; i++) {
runtimeItems[i].destroy();
}
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };

View file

@ -2,13 +2,10 @@ define([
"Game/Core/GameObjects/Doll", "Game/Core/GameObjects/Doll",
"Game/Channel/GameObjects/Item", "Game/Channel/GameObjects/Item",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Lib/Utilities/Assert"
], ],
function (Parent, Item, Box2D, nc, Assert) { function (Parent, Item, Box2D, Nc) {
"use strict";
function Doll(physicsEngine, uid, player) { function Doll(physicsEngine, uid, player) {
Parent.call(this, physicsEngine, uid, player); Parent.call(this, physicsEngine, uid, player);
@ -16,14 +13,12 @@ function (Parent, Item, Box2D, nc, Assert) {
Doll.prototype = Object.create(Parent.prototype); Doll.prototype = Object.create(Parent.prototype);
Doll.prototype.findCloseItem = function(x) { Doll.prototype.findCloseItem = function(x, y) {
var self = this;
function findItem(array) { function findItem(array) {
for (var i = 0; i < array.length; i++) { for (var i = 0; i < array.length; i++) {
var item = array[i]; var item = array[i];
if(item.isGrabbingAllowed(self.player)) { if(item.isGrabbingAllowed(this.player)) {
return item; return item;
} }
} }
@ -34,7 +29,7 @@ function (Parent, Item, Box2D, nc, Assert) {
} else { } else {
return findItem(this.reachableItems.right); return findItem(this.reachableItems.right);
} }
}; }
Doll.prototype.onImpact = function(isColliding, fixture) { Doll.prototype.onImpact = function(isColliding, fixture) {
var self = this; var self = this;
@ -47,74 +42,48 @@ function (Parent, Item, Box2D, nc, Assert) {
var item = otherBody.GetUserData(); var item = otherBody.GetUserData();
if(item instanceof Item) { if(item instanceof Item) {
var itemVelocity = item.body.GetLinearVelocity(); var itemVelocity = item.body.GetLinearVelocity();
//var itemMass = item.body.GetMass(); var itemMass = item.body.GetMass();
var ownVelocity = this.body.GetLinearVelocity(); var ownVelocity = this.body.GetLinearVelocity();
var b2Math = Box2D.Common.Math.b2Math; var b2Math = Box2D.Common.Math.b2Math;
var absItemVelocity = b2Math.AbsV(itemVelocity);
var min = 1;
var damage = 0;
if(absItemVelocity.x > min || absItemVelocity.y > min) { var absItemVelocity = b2Math.AbsV(itemVelocity)
var max = 1;
if(absItemVelocity.x > max || absItemVelocity.y > max) {
if(item.lastMoved && item.lastMoved.player != this.player) { if(item.lastMoved && item.lastMoved.player != this.player) {
var damageVector = b2Math.SubtractVV(itemVelocity, ownVelocity);
damageVector.Abs();
damageVector.Multiply(0.7);
damageVector.Multiply(itemMass * 1.3);
var damage = damageVector.Length();
damage *= item.options.danger ? item.options.danger : 1;
var collision = b2Math.SubtractVV(itemVelocity, ownVelocity); var player = item.lastMoved.player;
// Tested max velocity banana: 50
var velocityDamage = collision.Length() / 50;
// Max weight of piano: 15
var weightDamage = item.options.weight / 15;
// Max danger of knife: 3
var dangerDamage = item.options.danger / 3;
// + 0.5 and / 2: offsetting for lower velocity impact
// * 300: tested imperically by throwing piano from deadly height
// * 80: tested imperically by throwing knife fast
damage = (velocityDamage + 0.5) * (weightDamage * 300 + dangerDamage * 80) / 2;
var lastMovedPlayer = item.lastMoved.player;
var callback = function() { var callback = function() {
self.player.addDamage(damage, lastMovedPlayer, item); self.player.addDamage(damage, player);
}; }
nc.trigger(nc.ns.channel.engine.worldQueue.add, callback); Nc.trigger(Nc.ns.channel.engine.worldQueue.add, callback)
} }
} }
// only set lastMovedBy if player wasn't hurt by collision
if (damage === 0) {
item.setLastMovedBy(this.player); item.setLastMovedBy(this.player);
} }
} }
} }
} }
};
Doll.prototype.updatePositionState = function(update) { Doll.prototype.updatePositionState = function(update) {
if(!this.isAnotherPlayerNearby()) { if(!this.isAnotherPlayerNearby()) {
Assert.number(update.p.x, update.p.y);
Assert.number(update.lv.x, update.lv.y);
this.body.SetAwake(true); this.body.SetAwake(true);
this.body.SetPosition(update.p); this.body.SetPosition(update.p);
this.body.SetLinearVelocity(update.lv); this.body.SetLinearVelocity(update.lv);
} }
}; };
Doll.prototype.getUpdateData = function(getSleeping) {
var updateData = Parent.prototype.getUpdateData.call(this, getSleeping);
if(updateData) {
updateData.as = this.getActionState();
updateData.laxy = this.lookAtXY;
}
return updateData;
};
return Doll; return Doll;
}); });

View file

@ -1,39 +1,9 @@
define([ define([
"Game/Core/GameObjects/GameObject", "Game/Core/GameObjects/GameObject"
"Lib/Vendor/Box2D"
], ],
function (Parent, Box2D) { function(Parent) {
"use strict"; return Parent;
function GameObject(physicsEngine, uid) {
Parent.call(this, physicsEngine, uid);
}
GameObject.prototype = Object.create(Parent.prototype);
GameObject.prototype.getUpdateData = function(getSleeping) {
if (!this.body) {
return null;
}
if (this.body.GetType() === Box2D.Dynamics.b2Body.b2_staticBody) {
return null;
}
if (!getSleeping && !this.body.IsAwake()) {
return null;
}
return {
p: this.body.GetPosition(),
a: this.body.GetAngle(),
lv: this.body.GetLinearVelocity(),
av: this.body.GetAngularVelocity()
};
}
return GameObject;
}); });

View file

@ -1,27 +1,17 @@
define([ define([
"Game/Core/GameObjects/Item", "Game/Core/GameObjects/Item"
"Lib/Utilities/NotificationCenter",
], ],
function (Parent, nc) { function (Parent) {
"use strict";
function Item(physicsEngine, uid, options) { function Item(physicsEngine, uid, options) {
Parent.call(this, physicsEngine, uid, options); Parent.call(this, physicsEngine, uid, options);
this.heldByPlayers = []; this.heldByPlayers = [];
this.lastMoved = null; this.lastMoved = null;
this.ncTokens = (this.ncTokens || []).concat([
nc.on(nc.ns.channel.events.game.player.clearFingerPrints, this.clearOfPlayerFingerPrints, this)
]);
} }
Item.prototype = Object.create(Parent.prototype); Item.prototype = Object.create(Parent.prototype);
Item.prototype.getLastMovedBy = function() {
return this.lastMoved;
}
Item.prototype.setLastMovedBy = function(player) { Item.prototype.setLastMovedBy = function(player) {
@ -29,14 +19,14 @@ function (Parent, nc) {
this.lastMoved = { this.lastMoved = {
player: player, player: player,
timestamp: new Date() timestamp: new Date()
}; }
} else { } else {
this.lastMoved = null; this.lastMoved = null;
} }
}; };
Item.prototype.isGrabbingAllowed = function(player) { // jshint unused:false Item.prototype.isGrabbingAllowed = function(player) {
return this.heldByPlayers.length === 0; return this.heldByPlayers.length == 0;
}; };
Item.prototype.beingGrabbed = function(player) { Item.prototype.beingGrabbed = function(player) {
@ -48,7 +38,7 @@ function (Parent, nc) {
} }
}; };
Item.prototype.isReleasingAllowed = function(player) { // jshint unused:false Item.prototype.isReleasingAllowed = function(player) {
return true; return true;
}; };
@ -64,13 +54,6 @@ function (Parent, nc) {
} }
}; };
Item.prototype.clearOfPlayerFingerPrints = function(player) {
if (this.getLastMovedBy() && this.getLastMovedBy().player === player) {
console.checkpoint('Removing fingerprints from ' + this.options.image);
this.setLastMovedBy(null);
}
};
Item.prototype.onCollisionChange = function(isColliding, fixture) { Item.prototype.onCollisionChange = function(isColliding, fixture) {
if(isColliding) { if(isColliding) {
@ -96,7 +79,8 @@ function (Parent, nc) {
} }
} }
} }
}; }
return Item; return Item;

View file

@ -4,9 +4,7 @@ define([
"Lib/Utilities/NotificationCenter" "Lib/Utilities/NotificationCenter"
], ],
function (Parent, Settings, nc) { function (Parent, Settings, Nc) {
"use strict";
function RagDoll(physicsEngine, uid, options) { function RagDoll(physicsEngine, uid, options) {
this.scheduledForDestruction = false; this.scheduledForDestruction = false;
@ -35,7 +33,7 @@ function (Parent, Settings, nc) {
var self = this; var self = this;
this.scheduledForDestruction = true; this.scheduledForDestruction = true;
this.destructionTimeout = setTimeout(function() { this.destructionTimeout = setTimeout(function() {
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', { Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', {
type: 'animated', type: 'animated',
uid: self.uid uid: self.uid
}); });

View file

@ -0,0 +1,9 @@
define([
"Game/Core/GameObjects/Items/Rube"
],
function (Parent) {
return Parent;
});

View file

@ -1,79 +0,0 @@
define([
"Game/Core/GameObjects/Items/RubeDoll",
"Game/Config/Settings",
"Lib/Utilities/NotificationCenter"
],
function (Parent, Settings, nc) {
"use strict";
function RubeDoll(physicsEngine, uid, options) {
this.scheduledForDestruction = false;
this.destructionTimeout = null;
Parent.call(this, physicsEngine, uid, options);
}
RubeDoll.prototype = Object.create(Parent.prototype);
RubeDoll.prototype.beingGrabbed = function(player) {
Parent.prototype.beingGrabbed.call(this, player);
if(this.scheduledForDestruction) {
clearTimeout(this.destructionTimeout);
}
};
RubeDoll.prototype.beingReleased = function(player) {
Parent.prototype.beingReleased.call(this, player);
if(this.scheduledForDestruction) {
this.delayedDestroy();
}
};
RubeDoll.prototype.delayedDestroy = function() {
var self = this;
this.scheduledForDestruction = true;
this.destructionTimeout = setTimeout(function() {
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', {
type: 'animated',
uid: self.uid
});
self.destroy();
}, Settings.RAGDOLL_DESTRUCTION_TIME * 1000);
};
RubeDoll.prototype.getUpdateData = function(getSleeping) {
var updateData = Parent.prototype.getUpdateData.call(this, getSleeping);
// if parent is asleep it sends null, to do no update
if(!updateData) {
return updateData;
}
// adding limb update data
var limbUpdateData = {};
for(var name in this.limbs) {
limbUpdateData[name] = {
p: this.limbs[name].GetPosition(),
a: this.limbs[name].GetAngle(),
lv: this.limbs[name].GetLinearVelocity(),
av: this.limbs[name].GetAngularVelocity()
};
}
updateData['limbs'] = limbUpdateData;
return updateData;
}
RubeDoll.prototype.destroy = function() {
if(this.scheduledForDestruction) {
clearTimeout(this.destructionTimeout);
}
Parent.prototype.destroy.call(this);
};
return RubeDoll;
});

View file

@ -4,8 +4,6 @@ define([
function (Parent) { function (Parent) {
"use strict";
return Parent; return Parent;
}); });

View file

@ -4,12 +4,10 @@ define([
"fs" "fs"
], ],
function (Parent, Settings, FileSystem) { function (Parent, Settings, fs) {
"use strict"; function Level (uid, engine, gameObjects) {
Parent.call(this, uid, engine, gameObjects);
function Level (uid, engine) {
Parent.call(this, uid, engine);
} }
Level.prototype = Object.create(Parent.prototype); Level.prototype = Object.create(Parent.prototype);
@ -17,7 +15,7 @@ function (Parent, Settings, FileSystem) {
Level.prototype.loadLevelDataFromPath = function (path, callback) { Level.prototype.loadLevelDataFromPath = function (path, callback) {
// overwriting parent // overwriting parent
FileSystem.readFile(path, "utf8", function (err, data) { fs.readFile(path, "utf8", function (err, data) {
if (err) throw err; if (err) throw err;
callback(JSON.parse(data)); callback(JSON.parse(data));
}); });

View file

@ -4,8 +4,6 @@ define([
function (Parent) { function (Parent) {
"use strict";
return Parent; return Parent;
}); });

View file

@ -1,147 +1,55 @@
define([ define([
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Game/Channel/Channel", "Game/Channel/Channel"
"Game/Config/Settings",
"fs"
], ],
function (nc, Channel, Settings, fs) { function (Nc, Channel) {
"use strict";
function PipeToServer (process) { function PipeToServer (process) {
var self = this;
this.channel = null; this.channel = null;
this.process = process; this.process = process;
this.recordingFileName = null;
nc.on(nc.ns.channel.to.server.controlCommand.send, this.send, this); Nc.on(Nc.ns.channel.to.server.controlCommand.send, this.send, this);
process.on("message", this.onProcessMessage.bind(this)); process.on('message', function (message, handle) {
}
PipeToServer.prototype.onProcessMessage = function (message, handle) { // jshint unused:false if(message.data.hasOwnProperty('CREATE')) {
self.channel = new Channel(self, message.data.options);
if(message.data.hasOwnProperty("CREATE")) { } else if (message.data.hasOwnProperty('KILL')) {
this.channel = new Channel(this, message.data.options); self.channel.destroy();
message.data.options.playingFileName = Settings.CHANNEL_PLAY_RECORDING;
if(message.data.options.playingFileName) {
var self = this;
setTimeout(function() {
console.log(message.data.options.playingFileName);
self.play(message.data.options.playingFileName);
}, 2000); // giving channel time to set everything up
}
if(Settings.CHANNEL_RECORD_SESSION) {
this.recordingFileName = Settings.CHANNEL_RECORDING_PATH +
this.channel.name +
"-" +
(new Date()).toISOString() +
"-" +
message.data.options.levelUids.join("_") +
".log";
if(!fs.existsSync(Settings.CHANNEL_RECORDING_PATH)) {
fs.mkdirSync(Settings.CHANNEL_RECORDING_PATH);
}
setInterval(this.recordWorldUpdate.bind(this), 1000);
console.checkpoint("Started recording to: " + this.recordingFileName);
}
} else if (message.data.hasOwnProperty("KILL")) {
this.channel.destroy();
} else { } else {
this.onMessage(message); self.onMessage(message);
}
if(Settings.CHANNEL_RECORD_SESSION && this.channel && this.channel.name) {
var m = JSON.stringify(message);
var timestamp = Date.now();
var line = "m" + timestamp + m + "\n";
fs.appendFile(this.recordingFileName, line, function (err) {
if (err) throw err;
}); });
} }
}
};
PipeToServer.prototype.send = function (recipient, data) { PipeToServer.prototype.send = function (recipient, data) {
var message = { var message = {
recipient: recipient, recipient: recipient,
data: data data: data
}; }
this.process.send(message); this.process.send(message);
}; };
PipeToServer.prototype.onMessage = function (message) { PipeToServer.prototype.onMessage = function (message) {
switch(message.recipient) { switch(message.recipient) {
case "channel": case 'channel':
nc.trigger(nc.ns.channel.events.controlCommand.channel, message); Nc.trigger(Nc.ns.channel.events.controlCommand.channel, message);
break; break;
default: default:
nc.trigger(nc.ns.channel.events.controlCommand.user + message.recipient, message); Nc.trigger(Nc.ns.channel.events.controlCommand.user + message.recipient, message);
break; break;
} }
};
PipeToServer.prototype.play = function(playingFileName) {
var self = this;
var data = fs.readFileSync(Settings.CHANNEL_RECORDING_PATH + playingFileName);
var lines = data.toString().split("\n");
var start = 0;
for (var i = 0; i < lines.length; i++) {
// bind message variable
(function() {
var line = lines[i];
if(line.length > 0) {
var type = line.substring(0, 1);
var time = parseInt(line.substring(1, Date.now().toString().length + 1), 10);
if(i === 0) {
start = time;
} }
time -= start;
var jsonString = line.substring(Date.now().toString().length + 1);
var message = JSON.parse(jsonString);
setTimeout(function() {
console.log(line);
if(type == "m") {
self.onProcessMessage(message, null);
} else if(type == "w") {
if(self.channel.gameController) {
self.channel.gameController.onWorldUpdate(message);
}
}
}, time);
}
})();
}
};
PipeToServer.prototype.recordWorldUpdate = function() {
if(this.channel.gameController) {
var update = this.channel.gameController.getWorldUpdateObject(true);
var worldUpdate = JSON.stringify(update);
var timestamp = Date.now();
var line = "w" + timestamp + worldUpdate + "\n";
fs.appendFile(this.recordingFileName, line, function (err) {
if (err) throw err;
});
}
};
PipeToServer.prototype.destroy = function() { PipeToServer.prototype.destroy = function() {
this.send("coordinator", {destroy:this.channel.name}); this.send('coordinator', {destroy:this.channel.name});
this.process.exit(0); this.process.exit(0);
}; };

View file

@ -1,22 +1,17 @@
define([ define([
"Game/Core/Player", "Game/Core/Player",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Game/Channel/Control/PlayerController"
], ],
function (Parent, nc, PlayerController) { function (Parent, Nc) {
"use strict"; function Player(id, physicsEngine, user) {
Parent.call(this, id, physicsEngine, user);
function Player(id, physicsEngine, user, revealedGameController) {
Parent.call(this, id, physicsEngine, user, revealedGameController);
this.playerController = new PlayerController(this);
} }
Player.prototype = Object.create(Parent.prototype); Player.prototype = Object.create(Parent.prototype);
Player.prototype.handActionRequest = function(options) { Player.prototype.handActionRequest = function(x, y) {
if(!this.doll) return false; if(!this.doll) return false;
var item = null; var item = null;
@ -25,26 +20,30 @@ function (Parent, nc, PlayerController) {
if (isHolding) { if (isHolding) {
item = this.holdingItem; item = this.holdingItem;
} else { } else {
item = this.doll.findCloseItem(options.x); item = this.doll.findCloseItem(x, y);
} }
if(item) { if(item) {
this.handAction(options, isHolding, item); this.handAction(x, y, isHolding, item);
}
} }
};
Player.prototype.handAction = function(options, isHolding, item) { Player.prototype.handAction = function(x, y, isHolding, item) {
options.playerId = this.id; var options = {
options.itemUid = item.uid; playerId: this.id,
itemUid: item.uid
}
if (isHolding) { if (isHolding) {
// throw // throw
if(item.isReleasingAllowed()) { if(item.isReleasingAllowed()) {
this.throw(options, item); this.throw(x, y, item);
options.action = "throw"; options.action = "throw";
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); options.x = x;
options.y = y;
Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options);
} }
} else { } else {
// grab // grab
@ -52,34 +51,26 @@ function (Parent, nc, PlayerController) {
this.grab(item); this.grab(item);
options.action = "grab"; options.action = "grab";
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options);
} }
} }
}; };
Player.prototype.suicide = function() { Player.prototype.suicide = function() {
if(this.isSpawned()) { this.addDamage(100, this);
this.addDamage(100, this, null);
}
}; };
Player.prototype.addDamage = function(damage, enemy, byItem) { Player.prototype.addDamage = function(damage, enemy) {
// Prevent stats change (kills) after round has ended
if (this.revealedGameController.isInBetweenRounds()) {
return;
}
this.stats.health -= damage; this.stats.health -= damage;
if(this.stats.health < 0) this.stats.health = 0; if(this.stats.health < 0) this.stats.health = 0;
if(this.stats.health <= 0) { if(this.stats.health <= 0) {
if(enemy != this) enemy.score(); if(enemy != this) enemy.score();
this.kill(enemy, byItem); this.kill(enemy);
} else {
this.broadcastStats();
} }
this.broadcastStats(enemy);
}; };
Player.prototype.spawn = function(x, y) { Player.prototype.spawn = function(x, y) {
@ -88,19 +79,19 @@ function (Parent, nc, PlayerController) {
this.broadcastStats(); this.broadcastStats();
}; };
Player.prototype.kill = function(killedByPlayer, byItem) { Player.prototype.kill = function(killedByPlayer) {
this.stats.deaths++; this.stats.deaths++;
var ragDollId = this.stats.deaths; var ragDollId = this.stats.deaths;
Parent.prototype.kill.call(this, killedByPlayer, ragDollId); Parent.prototype.kill.call(this, killedByPlayer, ragDollId);
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "playerKill", { this.broadcastStats();
Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "playerKill", {
playerId: this.id, playerId: this.id,
killedByPlayerId: killedByPlayer.id, killedByPlayerId: killedByPlayer.id,
ragDollId: ragDollId, ragDollId: ragDollId
item: byItem ? byItem.options.name : "Suicide"
}); });
nc.trigger(nc.ns.channel.events.game.player.killed, this, killedByPlayer); // sends endround Nc.trigger(Nc.ns.channel.events.game.player.killed, this, killedByPlayer); // sends endround
if(this.ragDoll) { if(this.ragDoll) {
this.ragDoll.delayedDestroy(); this.ragDoll.delayedDestroy();
@ -109,22 +100,18 @@ function (Parent, nc, PlayerController) {
Player.prototype.score = function() { Player.prototype.score = function() {
this.stats.score++; this.stats.score++;
this.broadcastStats();
}; };
Player.prototype.broadcastStats = function(enemy) { Player.prototype.broadcastStats = function() {
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", { Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", {
playerId: this.id, playerId: this.id,
stats: this.stats stats: this.stats
}); });
if(enemy && enemy != this) {
nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", {
playerId: enemy.id,
stats: enemy.stats
});
}
}; };
return Player; return Player;
}); });

View file

@ -5,7 +5,7 @@ define([
"Lib/Utilities/Protocol/Parser", "Lib/Utilities/Protocol/Parser",
], ],
function(Parent, nc, ProtocolHelper, ProtocolParser) { function(Parent, Nc, ProtocolHelper, ProtocolParser) {
function User(id, options) { function User(id, options) {
Parent.call(this, id, options); Parent.call(this, id, options);
@ -14,15 +14,15 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) {
this.isReady = false; this.isReady = false;
var self = this; var self = this;
nc.on(nc.ns.channel.to.client.user.controlCommand.joinSuccess + this.id, function(options) { Nc.on(Nc.ns.channel.to.client.user.controlCommand.joinSuccess + this.id, function(options) {
self.sendControlCommand("joinSuccess", options); self.sendControlCommand("joinSuccess", options);
}); });
nc.on(nc.ns.channel.events.controlCommand.user + this.id, function(message) { Nc.on(Nc.ns.channel.events.controlCommand.user + this.id, function(message) {
ProtocolHelper.applyCommand(message.data, self); ProtocolHelper.applyCommand(message.data, self);
}); });
nc.on(nc.ns.channel.to.client.user.gameCommand.send + this.id, function(command, options) { Nc.on(Nc.ns.channel.to.client.user.gameCommand.send + this.id, function(command, options) {
self.sendGameCommand(command, options); self.sendGameCommand(command, options);
}); });
@ -44,10 +44,10 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) {
} // FIXME: move this to Protocol helper as a function } // FIXME: move this to Protocol helper as a function
if(command.hasOwnProperty("resetLevel")) { if(command.hasOwnProperty("resetLevel")) {
nc.trigger(nc.ns.channel.events.user.level.reset, this.id); Nc.trigger(Nc.ns.channel.events.user.level.reset, this.id);
} else if(command.hasOwnProperty("clientReady")) { } else if(command.hasOwnProperty("clientReady")) {
this.isReady = true; this.isReady = true;
nc.trigger(nc.ns.channel.events.user.client.ready, this.id); Nc.trigger(Nc.ns.channel.events.user.client.ready, this.id);
} else { } else {
this.player.playerController.applyCommand(command); this.player.playerController.applyCommand(command);
} }
@ -61,17 +61,7 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) {
var recipient = this.id; var recipient = this.id;
var data = ProtocolHelper.encodeCommand(command, options); var data = ProtocolHelper.encodeCommand(command, options);
/** Nc.trigger(Nc.ns.channel.to.server.controlCommand.send, recipient, data);
* Listen for beginRound control command
* to set client to be unready again
* so it can load its new level without getting
* any gameCommands like worldUpdate
*/
if(command == "beginRound") {
this.isReady = false;
}
nc.trigger(nc.ns.channel.to.server.controlCommand.send, recipient, data);
}; };
User.prototype.sendGameCommand = function(command, options) { User.prototype.sendGameCommand = function(command, options) {

View file

@ -1,38 +0,0 @@
define([
],
function () {
"use strict";
function AudioPlayer(path) {
this.audio = new Audio(path);
this.audio.loop = true;
this.audio.volume = 0.1;
this.audio.addEventListener('timeupdate', function(){
var buffer = 1
if(this.currentTime > this.duration - buffer) {
this.currentTime = 1
this.play()
}
}, false);
}
AudioPlayer.prototype.play = function() {
//this.audio.play();
//this.doPlay = true;
}
AudioPlayer.prototype.stop = function() {
//this.audio.stop();
//this.doPlay = false;
};
AudioPlayer.prototype.destroy = function() {
this.stop();
};
return AudioPlayer;
});

View file

@ -4,8 +4,6 @@ define([
function (Parent) { function (Parent) {
"use strict";
function Detector () { function Detector () {
Parent.call(this); Parent.call(this);
} }

View file

@ -1,21 +0,0 @@
define([
"Lib/Utilities/NotificationCenter"
],
function (nc) {
function Input(playerController) {
this.playerController = playerController;
this.x = null;
this.y = null
}
Input.prototype.onXyChange = function(x, y) {
this.x = x;
this.y = y;
this.playerController.setXY(this.x, this.y);
}
return Input;
});

View file

@ -1,11 +1,10 @@
define([ define([
"Game/Client/Control/Input", "Game/Client/Control/Input/XyInput",
"Game/Config/Settings" "Game/Config/Settings",
"Lib/Utilities/NotificationCenter"
], ],
function (Parent, Settings) { function (Parent, Settings, Nc) {
"use strict";
function GamepadInput(playerController) { function GamepadInput(playerController) {
this.playerController = playerController; this.playerController = playerController;
@ -37,7 +36,7 @@ function (Parent, Settings) {
var y = -this.gamepad.axes[3]; var y = -this.gamepad.axes[3];
// Looking direction // Looking direction
this.onXyChange(x, y); this.playerController.xyInput.onXyChange(x, y);
// Pointer finger holding item // Pointer finger holding item
var holdingPressure = this.gamepad.axes[5]; var holdingPressure = this.gamepad.axes[5];

View file

@ -0,0 +1,47 @@
define([
"Game/Client/Control/Input/XyInput",
"Game/Client/View/DomController",
"Game/Config/Settings",
"Lib/Utilities/NotificationCenter"
],
function (Parent, DomController, Settings, Nc) {
function MouseInput() {
Parent.call(this);
this.init();
}
MouseInput.prototype = Object.create(Parent.prototype);
MouseInput.prototype.init = function() {
var canvas = null;
var self = this;
canvas = DomController.getCanvas();
canvas.onmousemove = function(e){
// -1 +1 +1 +1 xy scaling should
// -1 -1 +1 -1 be like this
var x = (((e.clientX - this.offsetLeft) / Settings.STAGE_WIDTH) * 2) - 1;
var y = (((Settings.STAGE_HEIGHT - (e.clientY - this.offsetTop)) / Settings.STAGE_HEIGHT) * 2) -1;
self.onXyChange(x, y);
}
canvas.onmousedown = function(e) {
var x = (((e.clientX - this.offsetLeft) / Settings.STAGE_WIDTH) * 2) - 1;
var y = (((Settings.STAGE_HEIGHT - (e.clientY - this.offsetTop)) / Settings.STAGE_HEIGHT) * 2) -1;
Nc.trigger(Nc.ns.client.input.handAction.request, x, y);
}
};
return MouseInput;
});

View file

@ -0,0 +1,20 @@
define([
"Lib/Utilities/NotificationCenter"
],
function (Nc) {
function XyInput() {
this.x = null;
this.y = null
}
XyInput.prototype.onXyChange = function(x, y) {
this.x = x;
this.y = y;
Nc.trigger(Nc.ns.client.input.xy.change, x, y);
}
return XyInput;
});

View file

@ -1,231 +0,0 @@
define([
"Game/Client/Control/Input",
"Game/Client/Control/KeyboardInput",
"Game/Client/View/DomController",
"Game/Config/Settings",
"Game/Client/Control/Swiper"
],
function (Parent, KeyboardInput, domController, Settings, Swiper) {
"use strict";
function KeyboardAndMouse(playerController) {
Parent.call(this);
this.x = 0;
this.y = 0;
this.mousePosition = {x:0,y:0};
this.modifier = false;
this.swiper = null;
this.lastLookDirection = 1;
this.keys = {
w:87,
a:65,
s:83,
d:68,
f:70,
g:71,
k:75,
up: 38,
left: 37,
down: 40,
right: 39,
space: 32,
tab: 9,
shift: 16,
plus: 187,
plusfx: 171,
minus: 189,
minusfx: 173,
zero: 48
};
this.playerController = playerController;
this.keyboardInit();
this.mouseInit();
}
KeyboardAndMouse.prototype = Object.create(Parent.prototype);
KeyboardAndMouse.prototype.keyboardInit = function() {
this.keyboardInput = new KeyboardInput();
var self = this;
function bind2Pc(methodName) {
return self.playerController[methodName].bind(self.playerController);
}
this.keyboardInput.registerKey(this.keys.a, this.moveLeft.bind(this), this.stop.bind(this));
this.keyboardInput.registerKey(this.keys.left, this.moveLeft.bind(this), this.stop.bind(this));
this.keyboardInput.registerKey(this.keys.d, this.moveRight.bind(this), this.stop.bind(this));
this.keyboardInput.registerKey(this.keys.right, this.moveRight.bind(this), this.stop.bind(this));
this.keyboardInput.registerKey(this.keys.w, bind2Pc('jump'), bind2Pc('jumpStop'));
this.keyboardInput.registerKey(this.keys.up, bind2Pc('jump'), bind2Pc('jumpStop'));
this.keyboardInput.registerKey(this.keys.space, bind2Pc('jump'), bind2Pc('jumpStop'));
this.keyboardInput.registerKey(this.keys.plus, bind2Pc('zoomIn'));
this.keyboardInput.registerKey(this.keys.plusfx, bind2Pc('zoomIn'));
this.keyboardInput.registerKey(this.keys.minus, bind2Pc('zoomOut'));
this.keyboardInput.registerKey(this.keys.minusfx, bind2Pc('zoomOut'));
this.keyboardInput.registerKey(this.keys.zero, bind2Pc('zoomReset'));
this.keyboardInput.registerKey(this.keys.tab, bind2Pc('showInfo'), bind2Pc('hideInfo'));
this.keyboardInput.registerKey(this.keys.k, bind2Pc('suicide'));
this.keyboardInput.registerKey(
this.keys.shift,
this.activateModifier.bind(this),
this.deactivateModifier.bind(this)
);
};
KeyboardAndMouse.prototype.moveLeft = function() {
if (!this.modifier) {
this.lastLookDirection = -1;
this.onXyChange(this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD, 0);
}
this.playerController.moveLeft();
};
KeyboardAndMouse.prototype.moveRight = function() {
if (!this.modifier) {
this.lastLookDirection = 1;
this.onXyChange(this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD, 0);
}
this.playerController.moveRight();
};
KeyboardAndMouse.prototype.stop = function(e) {
var isMovingLeft = this.keyboardInput.getKeyByKeyCode(this.keys.a).getActive()
|| this.keyboardInput.getKeyByKeyCode(this.keys.left).getActive();
var isMovingRight = this.keyboardInput.getKeyByKeyCode(this.keys.d).getActive()
|| this.keyboardInput.getKeyByKeyCode(this.keys.right).getActive();
if (isMovingLeft) {
this.moveLeft();
return;
}
if (isMovingRight) {
this.moveRight();
return;
}
this.playerController.stop();
};
KeyboardAndMouse.prototype.mouseInit = function() {
var canvas = domController.getCanvas();
var self = this;
canvas.onmousedown = function(e) {
self.mousePosition = {x:0,y:0};
if(!self.playerController.player.isHoldingSomething()) {
var options = {
x: self.x,
y: self.y,
av: 0
};
self.playerController.handActionRequest(options);
} else {
self.swiper = new Swiper();
self.draw({
movementX: 0,
movementY: 0
});
}
}
canvas.onmousemove = function(e) {
if (self.swiper) {
self.draw(e);
} else if(self.modifier) {
self.updateViewport(e);
}
}
canvas.onmouseup = function(e) {
if(self.swiper) {
var options = self.swiper.swipeEnd(e.x, e.y);
self.playerController.handActionRequest(options);
self.swiper = null;
}
}
};
KeyboardAndMouse.prototype.updateViewport = function(e) {
// -1 +1 +1 +1 xy scaling should
// -1 -1 +1 -1 be like this
var movementX = e.movementX ||
e.mozMovementX ||
e.webkitMovementX ||
0;
var movementY = e.movementY ||
e.mozMovementY ||
e.webkitMovementY ||
0;
this.x += movementX / Settings.VIEWPORT_SPEED_FACTOR;
if(this.x > 1) {
this.x = 1;
}
if(this.x < -1) {
this.x = -1;
};
this.y -= movementY / Settings.VIEWPORT_SPEED_FACTOR;
if(this.y > 1) {
this.y = 1;
}
if(this.y < -1) {
this.y = -1;
}
this.lastLookDirection = this.x >= 0 ? 1 : -1;
this.onXyChange(this.x, this.y);
};
KeyboardAndMouse.prototype.draw = function(e) {
var movementX = e.movementX ||
e.mozMovementX ||
e.webkitMovementX ||
0;
var movementY = e.movementY ||
e.mozMovementY ||
e.webkitMovementY ||
0;
this.mousePosition.x += movementX;
this.mousePosition.y += movementY;
this.swiper.swipe(this.mousePosition.x, -this.mousePosition.y);
};
KeyboardAndMouse.prototype.activateModifier = function() {
this.modifier = true;
this.playerController.activateModifier();
};
KeyboardAndMouse.prototype.deactivateModifier = function() {
this.modifier = false;
this.x = this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD;
this.y = 0;
this.onXyChange(this.x, this.y);
this.playerController.deactivateModifier();
};
return KeyboardAndMouse;
});

View file

@ -1,9 +1,4 @@
define([ define(function () {
],
function () {
"use strict";
function Key () { function Key () {
this._active = false; this._active = false;

View file

@ -4,47 +4,50 @@ define([
function (Key) { function (Key) {
function KeyboardInput () { function KeyboardInput (playerController) {
this.registry = {};
this._registry = {};
this._playerController = playerController;
this.init(); this.init();
} }
KeyboardInput.prototype.init = function () { KeyboardInput.prototype.init = function () {
// Using window is ok here because it only runs in the browser // Using window is ok here because it only runs in the browser
window.onkeydown = this.onKeyDown.bind(this); window.onkeydown = this._onKeyDown.bind(this);
window.onkeyup = this.onKeyUp.bind(this); window.onkeyup = this._onKeyUp.bind(this);
} }
KeyboardInput.prototype.registerKey = function (keyCode, onKeyDown, onKeyUp) { KeyboardInput.prototype.registerKey = function (keyCode, onKeyDown, onKeyUp) {
var key = new Key(); var key = new Key();
if(onKeyDown) key.setKeyDownFunction(onKeyDown); if(onKeyDown) key.setKeyDownFunction(onKeyDown);
if(onKeyUp) key.setKeyUpFunction(onKeyUp); if(onKeyUp) key.setKeyUpFunction(onKeyUp);
this.registry[keyCode] = key; this._registry[keyCode] = key;
} }
KeyboardInput.prototype.getKeyByKeyCode = function (keyCode) { KeyboardInput.prototype._getKeyByKeyCode = function (keyCode) {
return this.registry[keyCode]; return this._registry[keyCode];
} }
KeyboardInput.prototype.onKeyDown = function (e) { KeyboardInput.prototype._onKeyDown = function (e) {
var key = this.getKeyByKeyCode(e.keyCode); var key = this._getKeyByKeyCode(e.keyCode);
if (key && !key.getActive()) { if (key && !key.getActive()) {
var callback = key.getKeyDownFunction(); var callback = key.getKeyDownFunction();
if(callback) this._playerController[callback]();
key.setActive(true); key.setActive(true);
if(callback) callback();
} }
// Prevent tab from changing focus // Prevent tab from changing focus
if(e.keyCode == 9) return false; if(e.keyCode == 9) return false;
} }
KeyboardInput.prototype.onKeyUp = function (e) { KeyboardInput.prototype._onKeyUp = function (e) {
var key = this.getKeyByKeyCode(e.keyCode); var key = this._getKeyByKeyCode(e.keyCode);
if (key && key.getActive()) { if (key && key.getActive()) {
var callback = key.getKeyUpFunction(); var callback = key.getKeyUpFunction();
if(callback) this._playerController[callback]();
key.setActive(false); key.setActive(false);
if(callback) callback();
} }
// Prevent tab from changing focus // Prevent tab from changing focus

View file

@ -1,122 +1,135 @@
define([ define([
"Game/Core/Control/PlayerController", "Game/Core/Control/PlayerController",
"Game/Client/Control/KeyboardInput",
"Game/Client/Control/Input/MouseInput",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Game/Client/Control/Inputs/KeyboardAndMouse", "Game/Client/Control/Input/GamepadInput",
"Game/Client/Control/Inputs/Gamepad",
"Game/Client/PointerLockManager"
], ],
function (Parent, nc, KeyboardAndMouse, Gamepad, pointerLockManager) { function (Parent, KeyboardInput, MouseInput, Nc, GamepadInput) {
"use strict";
function PlayerController (me) { function PlayerController (me) {
Parent.call(this, me); Parent.call(this, me);
this.keyboardAndMouse = new KeyboardAndMouse(this); this.keyboardInput = new KeyboardInput(this);
this.gamepad = new Gamepad(this); this.xyInput = new MouseInput(this);
this.gamepadInput = new GamepadInput(this);
this.ncTokens = [
Nc.on(Nc.ns.client.input.xy.change, this.setXY, this),
Nc.on(Nc.ns.client.input.handAction.request, this.handActionRequest, this)
];
var keys = {
w:87,
a:65,
s:83,
d:68,
f:70,
g:71,
k:75,
up: 38,
left: 37,
down: 40,
right: 39,
space: 32,
tab: 9
}
this.init(keys);
} }
PlayerController.prototype = Object.create(Parent.prototype); PlayerController.prototype = Object.create(Parent.prototype);
PlayerController.prototype.update = function() { PlayerController.prototype.update = function() {
Parent.prototype.update.call(this); Parent.prototype.update.call(this);
this.gamepad.update(); this.gamepadInput.update();
}; };
PlayerController.prototype.init = function (keys) {
this.keyboardInput.registerKey(keys.a, 'moveLeft', 'stop');
this.keyboardInput.registerKey(keys.left, 'moveLeft', 'stop');
this.keyboardInput.registerKey(keys.d, 'moveRight', 'stop');
this.keyboardInput.registerKey(keys.right, 'moveRight', 'stop');
this.keyboardInput.registerKey(keys.w, 'jump', 'jumpStop');
this.keyboardInput.registerKey(keys.up, 'jump', 'jumpStop');
this.keyboardInput.registerKey(keys.space, 'jump', 'jumpStop');
this.keyboardInput.registerKey(keys.tab, 'showInfo', 'hideInfo');
this.keyboardInput.registerKey(keys.f, 'handActionLeft');
this.keyboardInput.registerKey(keys.g, 'handActionRight');
this.keyboardInput.registerKey(keys.k, 'suicide');
}
PlayerController.prototype.moveLeft = function () { PlayerController.prototype.moveLeft = function () {
if (!this.isPlayerInputAllowed()) return;
Parent.prototype.moveLeft.call(this); Parent.prototype.moveLeft.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveLeft'); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveLeft');
} }
PlayerController.prototype.moveRight = function () { PlayerController.prototype.moveRight = function () {
if (!this.isPlayerInputAllowed()) return;
Parent.prototype.moveRight.call(this); Parent.prototype.moveRight.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveRight'); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveRight');
} }
// always allow to stop, to prevent endless running
PlayerController.prototype.stop = function () { PlayerController.prototype.stop = function () {
Parent.prototype.stop.call(this); Parent.prototype.stop.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'stop'); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'stop');
} }
PlayerController.prototype.jump = function () { PlayerController.prototype.jump = function () {
if (!this.isPlayerInputAllowed()) return;
Parent.prototype.jump.call(this); Parent.prototype.jump.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jump'); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jump');
} }
// always allow to stop.
PlayerController.prototype.jumpStop = function () { PlayerController.prototype.jumpStop = function () {
Parent.prototype.jumpStop.call(this); Parent.prototype.jumpStop.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jumpStop'); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jumpStop');
} }
PlayerController.prototype.setXY = function(x, y) { PlayerController.prototype.setXY = function(x, y) {
if (!this.isPlayerInputAllowed()) return;
var options = {x:x, y:y}; var options = {x:x, y:y};
Parent.prototype.lookAt.call(this, options); Parent.prototype.lookAt.call(this, options);
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'lookAt', options); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'lookAt', options);
};
PlayerController.prototype.handActionLeft = function() {
this.handActionRequest(-0.5, 0.5);
};
PlayerController.prototype.handActionRight = function() {
this.handActionRequest(0.5, 0.5);
}; };
PlayerController.prototype.suicide = function() { PlayerController.prototype.suicide = function() {
if (!this.isPlayerInputAllowed()) return; Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "suicide");
nc.trigger(nc.ns.client.to.server.gameCommand.send, "suicide");
}; };
PlayerController.prototype.handActionRequest = function(options) { PlayerController.prototype.handActionRequest = function(x, y) {
if (!this.isPlayerInputAllowed()) return; var options = {x:x, y:y};
nc.trigger(nc.ns.client.to.server.gameCommand.send, "handActionRequest", options); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "handActionRequest", options);
}; };
PlayerController.prototype.showInfo = function() { PlayerController.prototype.showInfo = function() {
if (!this.isPlayerInputAllowed()) return; Nc.trigger(Nc.ns.client.game.gameInfo.toggle, true);
nc.trigger(nc.ns.client.game.gameStats.toggle, true);
}; };
PlayerController.prototype.hideInfo = function() { PlayerController.prototype.hideInfo = function() {
if (!this.isPlayerInputAllowed()) return; Nc.trigger(Nc.ns.client.game.gameInfo.toggle, false);
nc.trigger(nc.ns.client.game.gameStats.toggle, false);
}; };
PlayerController.prototype.zoomIn = function() { PlayerController.prototype.destroy = function() {
if (!this.isPlayerInputAllowed()) return; Nc.offAll(this.ncTokens);
nc.trigger(nc.ns.client.game.zoomIn, true); Parent.prototype.destroy.call(this);
};
PlayerController.prototype.zoomOut = function() {
if (!this.isPlayerInputAllowed()) return;
nc.trigger(nc.ns.client.game.zoomOut, false);
};
PlayerController.prototype.zoomReset = function() {
if (!this.isPlayerInputAllowed()) return;
nc.trigger(nc.ns.client.game.zoomReset, false);
};
PlayerController.prototype.activateModifier = function() {
if (!this.isPlayerInputAllowed()) return;
Parent.prototype.activateModifier.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, "activateModifier");
};
PlayerController.prototype.deactivateModifier = function() {
if (!this.isPlayerInputAllowed()) return;
Parent.prototype.deactivateModifier.call(this);
nc.trigger(nc.ns.client.to.server.gameCommand.send, "deactivateModifier");
};
/*
* Client overwrite - allow player input if PointerLock is locked to canvas
* and is not in between games
*/
PlayerController.prototype.isPlayerInputAllowed = function() {
return pointerLockManager.isLocked()
&& Parent.prototype.isPlayerInputAllowed.call(this);
}; };

View file

@ -1,175 +0,0 @@
define([
"Lib/Utilities/NotificationCenter",
],
function (nc) {
var MAX_LENGTH = 200;
var MIN_LENGTH = 5;
function Swiper() {
this.points = [];
this.angleSum = 0;
this.lengthSum = 0;
this.finished = false;
}
Swiper.prototype.swipe = function(x, y) {
if(this.finished) return;
var points = this.points;
// Check if swipe is long enough to count
if(points.length >= 1) {
var lastPoint = points[points.length-1];
var a = Math.abs(x) - Math.abs(lastPoint.x);
var b = Math.abs(y) - Math.abs(lastPoint.y);
var currentLength = Math.sqrt(a * a + b * b); // Pythagoras -> hypotenuse
if(currentLength < MIN_LENGTH) return;
}
points.push({x:x, y:y});
if(points.length >= 2) {
this.updateLengthSum(currentLength);
if(this.points.length >= 3) {
this.updateAngleSum(currentLength);
}
}
var i = points.length - 1;
nc.trigger(nc.ns.client.view.swiper.swipe, points[i].x, points[i].y);
}
Swiper.prototype.updateLengthSum = function(currentLength) {
var points = this.points;
var i = points.length - 1;
var lengthSum = this.lengthSum + Math.abs(currentLength);
if(lengthSum > MAX_LENGTH) {
var diff = lengthSum - MAX_LENGTH;
var ratio = (currentLength - diff) / currentLength;
// Offset triangle to origin
var x0 = points[i].x - points[i-1].x;
var y0 = points[i].y - points[i-1].y;
// Multiply with ratio and offset back
var clippedX = x0 * ratio + points[i-1].x;
var clippedY = y0 * ratio + points[i-1].y;
points[i].x = clippedX;
points[i].y = clippedY;
this.finished = true;
lengthSum = MAX_LENGTH;
}
this.lengthSum = lengthSum;
};
Swiper.prototype.updateAngleSum = function(currentLength) {
var points = this.points;
var i = points.length - 1;
// last two lines
var vectors = [
{
x: points[i].x - points[i-1].x,
y: points[i].y - points[i-1].y
},
{
x: points[i-2].x - points[i-1].x,
y: points[i-2].y - points[i-1].y
}
];
var yx = vectors[0].y * vectors[1].x;
var xy = vectors[0].x * vectors[1].y;
var direction = 0;
if(yx > xy) {
direction = -1;
} else if (yx < xy) {
direction = 1;
}
var dotProduct = vectors[0].x
* vectors[1].x
+ vectors[0].y
* vectors[1].y;
var lastLength = Math.sqrt(
Math.pow(vectors[1].x, 2)
+ Math.pow(vectors[1].y, 2)
);
var angle = 180 - (Math.acos((dotProduct / (currentLength * lastLength)) % 1) * 180 / Math.PI);
angle *= direction;
if(!isNaN(parseFloat(angle)) && direction != 0) {
this.angleSum += angle;
}
};
Swiper.prototype.swipeEnd = function(x, y) {
var angularVelocity = this.angleSum;
var length = this.lengthSum;
if (this.points.length < 1) {
return {
x: 0,
y: 0,
av: 0
}
}
var p0x = this.points[0].x;
var p0y = this.points[0].y;
var sumx = 0;
var sumy = 0;
nc.trigger(nc.ns.client.view.swiper.end);
for(var i=0, count = this.points.length; i < count; i++) {
var p = this.points[i];
sumx += p.x - p0x;
sumy += p.y - p0y;
}
var direction = {
x: sumx / count,
y: sumy / count
};
var larger = Math.abs(direction.x) > Math.abs(direction.y) ? direction.x : direction.y;
direction.x /= Math.abs(larger);
direction.y /= Math.abs(larger);
this.angleSum = 0;
this.lengthSum = 0;
this.points = [];
this.finished = false;
return {
x: direction.x * length / 100,
y: direction.y * length / 100,
av: angularVelocity / 100
}
}
Swiper.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
nc.off(this.ncTokens[i]);
};
};
return Swiper;
});

View file

@ -11,16 +11,16 @@ define([
"Game/Client/GameObjects/Doll", "Game/Client/GameObjects/Doll",
"Game/Client/View/DomController", "Game/Client/View/DomController",
"Lib/Utilities/Protocol/Helper", "Lib/Utilities/Protocol/Helper",
"Game/Client/Me", "Game/Client/Me"
"Game/Client/AudioPlayer",
"Game/Client/PointerLockManager",
"Lib/Utilities/Assert",
"Lib/Utilities/Exception"
], ],
function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, requestAnimFrame, Settings, GameObject, Doll, domController, ProtocolHelper, Me, AudioPlayer, pointerLockManager, Assert, Exception) { function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me) {
"use strict"; if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
function GameController (options) { function GameController (options) {
@ -28,12 +28,11 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
this.view = ViewManager.createView(); this.view = ViewManager.createView();
this.me = null; this.me = null;
this.animationRequestId = null; this.animationRequestId = null;
this.audioPlayer = null;
Parent.call(this, options); Parent.call(this, options);
this.ncTokens = this.ncTokens.concat([ this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.game.gameStats.toggle, this.toggleGameStats, this) Nc.on(Nc.ns.client.game.gameInfo.toggle, this.toggleInfo, this)
]); ]);
} }
@ -41,52 +40,60 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
GameController.prototype.getMe = function () { GameController.prototype.getMe = function () {
return this.me; return this.me;
}; }
GameController.prototype.update = function () { GameController.prototype.update = function () {
Parent.prototype.update.call(this); Parent.prototype.update.call(this);
DomController.statsBegin();
this.animationRequestId = requestAnimFrame(this.update.bind(this)); this.animationRequestId = requestAnimFrame(this.update.bind(this));
this.physicsEngine.update(); this.physicsEngine.update();
if(this.me) { if(this.me) {
this.me.update(); this.me.update();
this.mePositionStateOverride(); this.mePositionStateUpdate();
} }
nc.trigger(nc.ns.client.game.events.render); for (var i = 0; i < this.gameObjects.animated.length; i++) {
this.gameObjects.animated[i].render();
}
this.view.render(); this.view.render();
domController.fpsStep();
};
GameController.prototype.mePositionStateOverride = function() { DomController.statsEnd();
if(this.me.isPositionStateOverrideNeeded()) { }
nc.trigger(
nc.ns.client.to.server.gameCommand.send, GameController.prototype.mePositionStateUpdate = function() {
"mePositionStateOverride", if(this.me.isPositionStateUpdateNeeded()) {
this.me.getPositionStateOverride() Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "mePositionStateUpdate", this.me.getPositionStateUpdate());
);
} }
}; };
GameController.prototype.onClientReadyResponse = function(options) { GameController.prototype.onClientReadyResponse = function(options) {
var i;
if (options.worldUpdate) {
this.onWorldUpdate(options.worldUpdate);
}
if (options.runtimeItems) { if (options.runtimeItems) {
for (i = 0; i < options.runtimeItems.length; i++) { for (var i = 0; i < options.runtimeItems.length; i++) {
var itemDef = options.runtimeItems[i]; var itemDef = options.runtimeItems[i];
if(!this.getItemByUid(itemDef.uid)) { var alreadyExists = false;
// When creating from synchronization we need to bring it into level format (px) for (var i = 0; i < this.gameObjects.animated.length; i++) {
itemDef.options.x *= Settings.RATIO; if(this.gameObjects.animated[i].uid == itemDef.uid) {
itemDef.options.y *= Settings.RATIO; alreadyExists = true;
this.level.createItem(itemDef.uid, itemDef.options); break;
console.log("Creating runtime Item: ", itemDef.options.name, itemDef.uid)
} }
};
if(!alreadyExists) {
var item = this.level.createItem(itemDef.uid, itemDef.options);
} }
};
} }
this.setMe(); this.setMe();
@ -94,51 +101,43 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
this.clientIsReady = true; // needs to stay before onSpawnPlayer this.clientIsReady = true; // needs to stay before onSpawnPlayer
if (options.spawnedPlayers) { if (options.spawnedPlayers) {
for(i = 0; i < options.spawnedPlayers.length; i++) { for(var i = 0; i < options.spawnedPlayers.length; i++) {
this.onSpawnPlayer(options.spawnedPlayers[i]); this.onSpawnPlayer(options.spawnedPlayers[i]);
} }
} }
if (options.worldUpdate) { // needs to stay after onSpawnPlayer otherwise others doll will not be there
this.onWorldUpdate(options.worldUpdate);
}
//this.audioPlayer = new AudioPlayer(Settings.AUDIO_PATH + "city.mp3");
//this.audioPlayer.play();
}; };
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];
TODO : if (gameObject instanceof Doll) {
- remove this
- overwrite setUpdateData inside client / Me with an empty function
GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) {
if(gameObject === this.me.doll) { if(gameObject === this.me.doll) {
this.me.setLastServerPositionState(update); this.me.setLastServerPositionState(update);
if(!this.me.acceptPositionStateUpdateFromServer()) { if(!this.me.acceptPositionStateUpdateFromServer()) {
return; // this is to ignore own doll updates from world update continue; // this is to ignore own doll updates from world update
}
}
gameObject.setActionState(update.as);
gameObject.lookAt(update.laxy.x, update.laxy.y);
}
body.SetAwake(true);
body.SetPosition(update.p);
body.SetAngle(update.a);
body.SetLinearVelocity(update.lv);
body.SetAngularVelocity(update.av);
} }
} }
Parent.prototype.onWorldUpdateGameObject.call(this, body, gameObject, update); } while (body = body.GetNext());
};
*/
GameController.prototype.onRemoveGameObject = function(options) {
};
GameController.prototype.updateGameObject = function (gameObject, gameObjectUpdate) {
if(gameObject === this.me.doll) {
this.me.setLastServerPositionState(gameObjectUpdate);
if(!this.me.acceptPositionStateUpdateFromServer()) {
return; // this is to ignore own doll updates from world update
}
}
Parent.prototype.updateGameObject.call(this, gameObject, gameObjectUpdate);
} }
GameController.prototype.createMe = function(user) { GameController.prototype.createMe = function(user) {
@ -147,8 +146,9 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
}; };
GameController.prototype.setMe = function() { GameController.prototype.setMe = function() {
this.me.setPlayerController(new PlayerController(this.me));
this.view.setMe(this.me); this.view.setMe(this.me);
}; }
GameController.prototype.onGameCommand = function(message) { GameController.prototype.onGameCommand = function(message) {
ProtocolHelper.applyCommand(message, this); ProtocolHelper.applyCommand(message, this);
@ -174,35 +174,78 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
playerId: playerId playerId: playerId
}); });
} }
}; }
GameController.prototype.onHandActionResponse = function(options) { GameController.prototype.onHandActionResponse = function(options) {
var player = this.players[options.playerId]; var player = this.players[options.playerId];
var item = this.getItemByUid(options.itemUid);
var item = null;
for (var i = 0; i < this.gameObjects.animated.length; i++) {
var currentItem = this.gameObjects.animated[i];
if(currentItem.uid == options.itemUid) {
item = currentItem;
break;
}
};
if(item) { if(item) {
if(options.action == "throw") { if(options.action == "throw") {
player.throw(options, item); player.throw(options.x, options.y, item);
} else if(options.action == "grab") { } else if(options.action == "grab") {
player.grab(item); player.grab(item);
} }
} else { } else {
console.warn("Item for joint can not be found locally. " + options.itemUid); console.warn("Item for joint can not be found locally. " + options.itemUid)
} }
}; };
GameController.prototype.onUpdateStats = function(options) { GameController.prototype.onUpdateStats = function(options) {
var player = this.players[options.playerId]; var player = this.players[options.playerId];
if(!player) {
throw new Exception("No player with id: " + options.playerId);
}
player.setStats(options.stats); player.setStats(options.stats);
// FIXME: move to canvas later
if(player == this.me) {
DomController.setHealth(player.stats.health);
}
};
GameController.prototype.onPlayerKill = function(options) {
var player = this.players[options.playerId];
var killedByPlayer = this.players[options.killedByPlayerId];
player.kill(killedByPlayer, options.ragDollId);
};
GameController.prototype.onPositionStateReset = function(options) {
this.me.resetPositionState(options);
};
GameController.prototype.onRemoveGameObject = function(options) {
var object = null;
for (var i = 0; i < this.gameObjects[options.type].length; i++) {
if(this.gameObjects[options.type][i].uid == options.uid) {
object = this.gameObjects[options.type][i];
break;
}
}
if(object) {
//this.onGameObjectRemove(options.type, object);
object.destroy();
} else {
console.warn("GameObject for removal can not be found locally. " + options.uid);
}
};
GameController.prototype.loadLevel = function (path) {
Parent.prototype.loadLevel.call(this, path);
}
GameController.prototype.toggleInfo = function(show) {
var playersArray = []; var playersArray = [];
for (var key in this.players) { for (var key in this.players) {
playersArray.push(this.players[key]); playersArray.push(this.players[key]);
} };
var sortedPlayers = playersArray.sort(function(a,b) { var sortedPlayers = playersArray.sort(function(a,b) {
if(a.stats.score > b.stats.score) return -1; if(a.stats.score > b.stats.score) return -1;
@ -214,66 +257,48 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
return 0; return 0;
}); });
nc.trigger(nc.ns.client.view.gameStats.update, sortedPlayers); function pad(string, max, alignLeft) {
}; string = string.substring(0, max - 1);
GameController.prototype.onPlayerKill = function(options) { var spaces = new Array( max - string.length + 1 ).join(" ");
var player = this.players[options.playerId]; if(alignLeft) {
var killedByPlayer = this.players[options.killedByPlayerId]; return string + spaces;
player.kill(killedByPlayer, options.ragDollId); } else {
return spaces + string;
}
}
nc.trigger(nc.ns.client.view.gameStats.kill, { var string = "" +
victim: { pad("#", 2, false) + " " +
name: player.user.options.nickname, pad("Name", 12, true) +
isMe: player === this.me pad("Score", 6, false) +
}, pad("Deaths", 7, false) +
killer: { pad("Health", 7, false) +
name: killedByPlayer.user.options.nickname, "\n-----------------------------------\n";
isMe: killedByPlayer === this.me
},
item: options.item
});
};
GameController.prototype.onPositionStateReset = function(options) { var lines = [];
this.me.resetPositionState(options); sortedPlayers.forEach(function(player, i) {
}; var name = player.getNickname();
lines.push(
pad("" + (i + 1) + ".", 2, false) + " " +
pad(name, 12, true) +
pad("" + player.stats.score, 6, false) +
pad("" + player.stats.deaths, 7, false) +
pad("" + parseInt(player.stats.health, 10), 7, false)
);
}, this);
GameController.prototype.loadLevel = function (path) { string += lines.join("\n");
Parent.prototype.loadLevel.call(this, path);
};
GameController.prototype.onLevelLoaded = function () { this.view.toggleInfo(show, string);
pointerLockManager.update(null, {start:true});
};
GameController.prototype.toggleGameStats = function(show) {
nc.trigger(nc.ns.client.view.gameStats.toggle, show);
};
GameController.prototype.beginRound = function() {
this.me.setInBetweenRounds(false);
};
GameController.prototype.endRound = function() {
this.me.setInBetweenRounds(true);
this.toggleGameStats(true);
}; };
GameController.prototype.destroy = function() { GameController.prototype.destroy = function() {
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
cancelAnimationFrame(this.animationRequestId); cancelAnimationFrame(this.animationRequestId);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
//this.audioPlayer.destroy();
this.view.destroy(); this.view.destroy();
}; };

View file

@ -2,17 +2,12 @@ define([
"Game/Core/GameObjects/Doll", "Game/Core/GameObjects/Doll",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Lib/Utilities/Exception", "Lib/Utilities/Exception"
"Lib/Utilities/ColorConverter",
"Game/Client/View/Abstract/Layer",
], ],
function (Parent, Settings, nc, Exception, ColorConverter, Layer) { function (Parent, Settings, Nc, Exception) {
"use strict";
function Doll(physicsEngine, uid, player) { function Doll(physicsEngine, uid, player) {
this.layerId = Layer.ID.SPAWN;
this.animationDef = { this.animationDef = {
"stand": [1,1], "stand": [1,1],
"walk": [2,28], "walk": [2,28],
@ -25,71 +20,31 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) {
"run": [104,126] "run": [104,126]
} }
this.lastStep = Date.now(); this.animatedMeshes = {};
this.animatedMeshesContainer = {
withArms: {},
withoutArms: {}
};
this.animatedMeshes = this.animatedMeshesContainer.withArms;
this.headMesh = null; this.headMesh = null;
this.holdingArmMesh = null;
var converter = new ColorConverter();
this.primaryColor = converter.getColorByName(player.getNickname());
Parent.call(this, physicsEngine, uid, player); Parent.call(this, physicsEngine, uid, player);
} }
Doll.prototype = Object.create(Parent.prototype); Doll.prototype = Object.create(Parent.prototype);
Doll.prototype.setActionState = function(state, force) { Doll.prototype.setActionState = function(state) {
if(!force && this.actionState == state) return; if(this.actionState == state) return;
if(!state) throw new Exception("action state is undefined"); if(!state) throw new Exception("action state is undefined");
if(this.animatedMeshes[this.actionState]) { if(this.animatedMeshes[this.actionState]) {
nc.trigger( Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[this.actionState], { visible: false });
nc.ns.client.view.mesh.update,
this.layerId,
this.animatedMeshesContainer.withArms[this.actionState],
{ visible: false }
);
nc.trigger(
nc.ns.client.view.mesh.update,
this.layerId,
this.animatedMeshesContainer.withoutArms[this.actionState],
{ visible: false }
);
} }
Parent.prototype.setActionState.call(this, state); Parent.prototype.setActionState.call(this, state);
nc.trigger( Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[this.actionState], { visible: true });
nc.ns.client.view.mesh.update,
this.layerId,
this.animatedMeshes[this.actionState],
{
visible: true,
xScale: this.lookDirection
}
);
} }
Doll.prototype.createMesh = function() { Doll.prototype.createMesh = function() {
var self = this;
var setShirtColor = function (mesh) {
nc.trigger(nc.ns.client.view.mesh.addFilter, self.layerId, mesh, 'colorRangeReplace', {
minColor: 0x3b4a31,
maxColor: 0x657f54,
newColor: self.primaryColor,
brightnessOffset: 0.56
});
}
// Body // Body
var padF = function(n) { var padF = function(n) {
@ -100,101 +55,53 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) {
var self = this; var self = this;
var arms = ["withArms", "withoutArms"];
for (var j = 0; j < arms.length; j++) {
var arm = arms[j];
for (var key in this.animationDef) { for (var key in this.animationDef) {
var start = this.animationDef[key][0]; var start = this.animationDef[key][0];
var end = this.animationDef[key][1]; var end = this.animationDef[key][1];
var texturePaths = []; var texturePaths = [];
for (var i = start; i <= end; i++) { for (var i = start; i <= end; i++) {
/*
// Multiple File Animations
texturePaths.push( texturePaths.push(
Settings.GRAPHICS_PATH Settings.GRAPHICS_PATH
+ Settings.GRAPHICS_SUBPATH_CHARACTERS + Settings.GRAPHICS_SUBPATH_CHARACTERS
+ this.characterName + this.characterName
+ "/Animation/" + arm.toUpperCaseFirstChar() + "/ChuckAnimations0" //+ "/Animation/WithoutArms/ChuckAnimationsWithoutArms0"
+ "/Animation/WithArms/ChuckAnimations0"
+ padF(i) + padF(i)
+ ".png" + ".png"
); );
*/
// Single File Animations (animation names from chuck_sheet.json, use option fromFrame=true)
texturePaths.push(
"Chuck" + arm.toUpperCaseFirstChar() + "0" + padF(i) + ".png"
);
} }
var callback = function(mesh) { var callback = function(mesh) {
self.animatedMeshesContainer[arm][key] = mesh; self.animatedMeshes[key] = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.add, mesh);
setShirtColor(mesh);
}; };
nc.trigger(nc.ns.client.view.animatedMesh.create, this.layerId, texturePaths, callback, { Nc.trigger(Nc.ns.client.view.animatedMesh.create, texturePaths, callback, {
visible: false, visible: false,
pivot: { pivot: {
x: 0, x: 35/2 * 4,
y: 40 * 4 y: 40 * 4
}, },
xScale: 0.25, width: 35,
yScale: 0.25, height: 40
anchor: {
x: 0.5,
y: 0
},
fromFrame: true
}); });
} }
};
// Head // Head
var texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/head.png"; var texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/head.png";
var callback = function (mesh) { var callback = function (mesh) {
self.headMesh = mesh; self.headMesh = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.add, mesh);
} }
nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, { Nc.trigger(Nc.ns.client.view.mesh.create, texturePath, callback, {
pivot: { pivot: {
x: 5, x: 5,
y: 12 y: 12
}, },
width: 10, width: 10,
height: 12, height: 12
anchor: {
x: 0,
y: 0
}
});
// Holding arm
texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/holdingArm.png";
var callback = function (mesh) {
self.holdingArmMesh = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh);
setShirtColor(mesh);
}
nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, {
visible: false,
pivot: {
//x: 35/2 * 4,
x: 0,
y: 40 * 4
},
width: 35,
height: 40,
anchor: {
x: 0.5,
y: 0
}
}); });
} }
@ -206,28 +113,18 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) {
if(oldLookDirection != this.lookDirection) { if(oldLookDirection != this.lookDirection) {
for(var key in this.animatedMeshes) { for(var key in this.animatedMeshes) {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.animatedMeshes[key], this.animatedMeshes[key],
{ {
xScale: this.lookDirection xScale: this.lookDirection
} }
); );
} }
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.holdingArmMesh,
{
xScale: this.lookDirection
}
);
} }
var angle = Math.atan2(this.lookAtXY.x, this.lookAtXY.y) / 2 - 0.7855 * this.lookDirection; // 0.7855 = 45° var angle = Math.atan2(this.lookAtXY.x, this.lookAtXY.y) / 2 - 0.7855 * this.lookDirection; // 0.7855 = 45°
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.headMesh, this.headMesh,
{ {
xScale: this.lookDirection, xScale: this.lookDirection,
@ -236,70 +133,35 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) {
); );
} }
Doll.prototype.grab = function(item) {
Parent.prototype.grab.call(this, item);
this.animatedMeshes = this.animatedMeshesContainer.withoutArms;
this.setActionState(this.actionState, true);
nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: true });
};
Doll.prototype.throw = function(item, options) {
Parent.prototype.throw.call(this, item, options);
this.animatedMeshes = this.animatedMeshesContainer.withArms;
this.setActionState(this.actionState, true);
nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: false });
};
Doll.prototype.destroy = function () { Doll.prototype.destroy = function () {
for (var key in this.animatedMeshes) { for (var key in this.animatedMeshes) {
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.animatedMeshes[key]); Nc.trigger(Nc.ns.client.view.mesh.remove, this.animatedMeshes[key]);
} }
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.headMesh); Nc.trigger(Nc.ns.client.view.mesh.remove, this.headMesh);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
} }
Doll.prototype.render = function() { Doll.prototype.render = function() {
if(this.actionState) { if(this.actionState) {
Nc.trigger(Nc.ns.client.view.mesh.update,
var stepLength = (Date.now() - this.lastStep);
this.lastStep = Date.now();
// compare current framerate to wanted and get factor
// (stepLength / 60) * 2
// * 2 to scale to flash fps
var factor = stepLength / 30;
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.animatedMeshes[this.actionState], this.animatedMeshes[this.actionState],
{ {
x: this.body.GetPosition().x * Settings.RATIO, x: this.body.GetPosition().x * Settings.RATIO,
y: this.body.GetPosition().y * Settings.RATIO, y: this.body.GetPosition().y * Settings.RATIO,
animationSpeed: factor rotation: this.body.GetAngle()
//rotation: this.body.GetAngle()
} }
); );
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.headMesh, this.headMesh,
{ {
x: this.body.GetPosition().x * Settings.RATIO, x: this.body.GetPosition().x * Settings.RATIO,
y: this.body.GetPosition().y * Settings.RATIO - this.height + this.headHeight y: this.body.GetPosition().y * Settings.RATIO - this.height + this.headHeight
} }
) )
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.holdingArmMesh,
{
x: this.body.GetPosition().x * Settings.RATIO,
y: this.body.GetPosition().y * Settings.RATIO
}
)
} }
} }

View file

@ -4,9 +4,7 @@ define([
"Lib/Utilities/NotificationCenter" "Lib/Utilities/NotificationCenter"
], ],
function (Parent, Exception, nc) { function (Parent, Exception, Nc) {
"use strict";
function GameObject(physicsEngine, uid) { function GameObject(physicsEngine, uid) {
Parent.call(this, physicsEngine, uid); Parent.call(this, physicsEngine, uid);

View file

@ -1,21 +1,13 @@
define([ define([
"Game/Core/GameObjects/Item", "Game/Core/GameObjects/Item",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Game/Client/View/Abstract/Layer"
], ],
function (Parent, Settings, nc, Layer) { function (Parent, Settings, Nc) {
"use strict";
function Item(physicsEngine, uid, options) { function Item(physicsEngine, uid, options) {
this.layerId = Layer.ID.ITEM;
Parent.call(this, physicsEngine, uid, options); Parent.call(this, physicsEngine, uid, options);
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.game.events.render, this.render, this)
]);
} }
Item.prototype = Object.create(Parent.prototype); Item.prototype = Object.create(Parent.prototype);
@ -30,11 +22,10 @@ function (Parent, Settings, nc, Layer) {
var callback = function(mesh) { var callback = function(mesh) {
self.mesh = mesh; self.mesh = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.add, mesh);
} }
nc.trigger(nc.ns.client.view.mesh.create, Nc.trigger(Nc.ns.client.view.mesh.create,
this.layerId,
texturePath, texturePath,
callback, callback,
{ {
@ -49,14 +40,13 @@ function (Parent, Settings, nc, Layer) {
}; };
Item.prototype.destroy = function() { Item.prototype.destroy = function() {
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.mesh); Nc.trigger(Nc.ns.client.view.mesh.remove, this.mesh);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };
Item.prototype.render = function() { Item.prototype.render = function() {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.mesh, this.mesh,
{ {
x: this.body.GetPosition().x * Settings.RATIO, x: this.body.GetPosition().x * Settings.RATIO,
@ -72,8 +62,7 @@ function (Parent, Settings, nc, Layer) {
Parent.prototype.flip.call(this, direction); Parent.prototype.flip.call(this, direction);
if(oldFlipDirection != direction) { if(oldFlipDirection != direction) {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.mesh, this.mesh,
{ {
xScale: direction xScale: direction

View file

@ -2,16 +2,12 @@ define([
"Game/Core/GameObjects/Items/RagDoll", "Game/Core/GameObjects/Items/RagDoll",
"Game/Core/GameObjects/Item", "Game/Core/GameObjects/Item",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Game/Client/View/Abstract/Layer"
], ],
function (Parent, CoreItem, Settings, nc, Layer) { function (Parent, CoreItem, Settings, Nc) {
"use strict";
function RagDoll(physicsEngine, uid, options) { function RagDoll(physicsEngine, uid, options) {
this.layerId = Layer.ID.SPAWN;
this.limbMeshes = {}; this.limbMeshes = {};
this.baseMeshName = "chest"; this.baseMeshName = "chest";
this.characterName = "Chuck"; this.characterName = "Chuck";
@ -40,11 +36,10 @@ function (Parent, CoreItem, Settings, nc, Layer) {
self.limbMeshes[name] = mesh; self.limbMeshes[name] = mesh;
} }
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.add, mesh);
} }
nc.trigger(nc.ns.client.view.mesh.create, Nc.trigger(Nc.ns.client.view.mesh.create,
this.layerId,
texturePath + name + ".png", texturePath + name + ".png",
callback, callback,
{ {
@ -64,8 +59,7 @@ function (Parent, CoreItem, Settings, nc, Layer) {
if(this.limbs) { if(this.limbs) {
for(var name in this.limbMeshes) { for(var name in this.limbMeshes) {
if(this.limbs[name]) { if(this.limbs[name]) {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.limbMeshes[name], this.limbMeshes[name],
{ {
x: this.limbs[name].GetPosition().x * Settings.RATIO, x: this.limbs[name].GetPosition().x * Settings.RATIO,
@ -85,8 +79,7 @@ function (Parent, CoreItem, Settings, nc, Layer) {
CoreItem.prototype.flip.call(this, direction); CoreItem.prototype.flip.call(this, direction);
if(oldFlipDirection != direction) { if(oldFlipDirection != direction) {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.mesh, this.mesh,
{ {
xScale: direction xScale: direction
@ -94,8 +87,7 @@ function (Parent, CoreItem, Settings, nc, Layer) {
); );
for (var name in this.limbMeshes) { for (var name in this.limbMeshes) {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.limbMeshes[name], this.limbMeshes[name],
{ {
xScale: direction xScale: direction
@ -108,7 +100,7 @@ function (Parent, CoreItem, Settings, nc, Layer) {
RagDoll.prototype.destroy = function() { RagDoll.prototype.destroy = function() {
for (var name in this.limbMeshes) { for (var name in this.limbMeshes) {
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.limbMeshes[name]); Nc.trigger(Nc.ns.client.view.mesh.remove, this.limbMeshes[name]);
}; };
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);

View file

@ -0,0 +1,26 @@
define([
"Game/Core/GameObjects/Items/Rube"
],
function (Parent) {
function Rube(physicsEngine, uid, options) {
Parent.call(this, physicsEngine, uid, options);
}
Rube.prototype = Object.create(Parent.prototype);
Rube.prototype.createMesh = function() {
};
Rube.prototype.destroy = function() {
};
Rube.prototype.render = function() {
}
Rube.prototype.flip = function(direction) {
};
return Rube;
});

View file

@ -1,254 +0,0 @@
define([
"Game/Core/GameObjects/Items/RubeDoll",
"Game/Client/View/Abstract/Layer",
"Game/Config/Settings",
"Lib/Utilities/NotificationCenter",
],
function (Parent, Layer, Settings, nc) {
"use strict";
function RubeDoll(physicsEngine, uid, options) {
this.primaryColor = options.primaryColor;
var limbOptions = {};
limbOptions.chest = {
width: 6,
height: 18,
x: 0,
y: 0
};
limbOptions.head = {
width: 10,
height: 12,
x: 0,
y: - limbOptions.chest.height / 2 - 7
};
limbOptions.upperLeftLeg = {
width: 5,
height: 8,
x: -2,
y: limbOptions.chest.height / 2
};
limbOptions.upperRightLeg = {
width: 5,
height: 8,
x: 2,
y: limbOptions.chest.height / 2
};
limbOptions.lowerLeftLeg = {
width: 5,
height: 4,
x: -2,
y: limbOptions.chest.height / 2 + limbOptions.upperLeftLeg.height
};
limbOptions.lowerRightLeg = {
width: 5,
height: 4,
x: 2,
y: limbOptions.chest.height / 2 + limbOptions.upperRightLeg.height
};
limbOptions.upperLeftArm = {
width: 4,
height: 8,
x: -2,
y: -limbOptions.chest.height / 2
};
limbOptions.upperRightArm = {
width: 4,
height: 8,
x: 2,
y: -limbOptions.chest.height / 2
};
limbOptions.lowerLeftArm = {
width: 4,
height: 5,
x: -2,
y: -limbOptions.chest.height / 2 + limbOptions.upperLeftArm.height
};
limbOptions.lowerRightArm = {
width: 4,
height: 5,
x: 2,
y: -limbOptions.chest.height / 2 + limbOptions.upperRightArm.height
};
this.limbOptions = limbOptions;
this.layerId = Layer.ID.SPAWN;
this.limbMeshes = {};
this.baseMeshName = "chest";
this.characterName = "Chuck";
this.lastFlipDirection = -options.direction || 1;
Parent.call(this, physicsEngine, uid, options);
}
RubeDoll.prototype = Object.create(Parent.prototype);
RubeDoll.prototype.createMesh = function() {
this.createLimbMesh("lowerRightLeg");
this.createLimbMesh("upperRightLeg");
this.createLimbMesh("lowerRightArm");
this.createLimbMesh("upperRightArm");
this.createLimbMesh("chest");
this.createLimbMesh("head");
this.createLimbMesh("lowerLeftLeg");
this.createLimbMesh("upperLeftLeg");
this.createLimbMesh("lowerLeftArm");
this.createLimbMesh("upperLeftArm");
};
RubeDoll.prototype.createLimbMesh = function(name) {
var self = this;
var texturePath = Settings.GRAPHICS_PATH
+ Settings.GRAPHICS_SUBPATH_CHARACTERS + ""
+ this.characterName + '/';
var callback = function(mesh) {
if(name == self.baseMeshName) {
self.mesh = mesh;
}
self.limbMeshes[name] = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh);
// setting shirt color
nc.trigger(nc.ns.client.view.mesh.addFilter, self.layerId, mesh, "colorRangeReplace", {
minColor: 0x3b4a31,
maxColor: 0x6d855d,
newColor: self.primaryColor,
brightnessOffset: 0.56
});
};
nc.trigger(nc.ns.client.view.mesh.create,
this.layerId,
texturePath + name + ".png",
callback,
{
width: this.limbOptions[name].width,
height: this.limbOptions[name].height,
pivot: {
x: this.limbOptions[name].width / 2,
y: this.limbOptions[name].height / 2
}
}
);
};
RubeDoll.prototype.destroy = function() {
for (var name in this.limbMeshes) {
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.limbMeshes[name]);
};
Parent.prototype.destroy.call(this);
};
RubeDoll.prototype.render = function() {
//Parent.prototype.render.call(this);
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.mesh,
{
x: this.body.GetPosition().x * Settings.RATIO,
y: this.body.GetPosition().y * Settings.RATIO,
rotation: this.body.GetAngle()
}
);
if(this.limbs) {
for(var name in this.limbMeshes) {
if(this.limbs[name]) {
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.limbMeshes[name],
{
x: this.limbs[name].GetPosition().x * Settings.RATIO,
y: this.limbs[name].GetPosition().y * Settings.RATIO,
rotation: this.limbs[name].GetAngle()
}
);
}
}
}
};
RubeDoll.prototype.flip = function(direction) {
Parent.prototype.flip.call(this, direction);
// flipping depth of right body side arm/leg images with left
if (this.lastFlipDirection != direction) { // FIXME : this is a bit broken.
this.lastFlipDirection = direction;
nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes,
this.layerId,
this.limbMeshes["lowerRightLeg"],
this.limbMeshes["lowerLeftLeg"]
);
nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes,
this.layerId,
this.limbMeshes["upperRightLeg"],
this.limbMeshes["upperLeftLeg"]
);
nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes,
this.layerId,
this.limbMeshes["lowerRightArm"],
this.limbMeshes["lowerLeftArm"]
);
nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes,
this.layerId,
this.limbMeshes["upperRightArm"],
this.limbMeshes["upperLeftArm"]
);
// swap short images
nc.trigger(nc.ns.client.view.mesh.swapMeshes,
this.layerId,
this.limbMeshes["upperRightLeg"],
this.limbMeshes["upperLeftLeg"]
);
}
// x flipping has to happen after (see swapMeshes)
if(this.limbs) {
for(var name in this.limbMeshes) {
if(this.limbs[name]) {
nc.trigger(nc.ns.client.view.mesh.update,
this.layerId,
this.limbMeshes[name],
{
xScale: direction,
}
);
}
}
}
};
return RubeDoll;
});

View file

@ -4,8 +4,6 @@ define([
function (Parent) { function (Parent) {
"use strict";
function SpectatorDoll(physicsEngine, uid) { function SpectatorDoll(physicsEngine, uid) {
Parent.call(this, physicsEngine, uid); Parent.call(this, physicsEngine, uid);
} }

View file

@ -1,16 +1,12 @@
define([ define([
"Game/Core/GameObjects/Tile", "Game/Core/GameObjects/Tile",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Game/Client/View/Abstract/Layer"
], ],
function (Parent, Settings, nc, Layer) { function (Parent, Settings, Nc) {
"use strict";
function Tile(physicsEngine, uid, options) { function Tile(physicsEngine, uid, options) {
this.layerId = Layer.ID.TILE;
Parent.call(this, physicsEngine, uid, options); Parent.call(this, physicsEngine, uid, options);
} }
@ -31,11 +27,10 @@ function (Parent, Settings, nc, Layer) {
var callback = function(mesh) { var callback = function(mesh) {
self.mesh = mesh; self.mesh = mesh;
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.add, mesh);
} }
nc.trigger(nc.ns.client.view.mesh.create, Nc.trigger(Nc.ns.client.view.mesh.create,
this.layerId,
texturePath, texturePath,
callback, callback,
{ {
@ -50,14 +45,13 @@ function (Parent, Settings, nc, Layer) {
}; };
Tile.prototype.destroy = function() { Tile.prototype.destroy = function() {
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.mesh); Nc.trigger(Nc.ns.client.view.mesh.remove, this.mesh);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };
Tile.prototype.render = function() { Tile.prototype.render = function() {
nc.trigger(nc.ns.client.view.mesh.update, Nc.trigger(Nc.ns.client.view.mesh.update,
this.layerId,
this.mesh, this.mesh,
{ {
x: this.body.GetPosition().x * Settings.RATIO, x: this.body.GetPosition().x * Settings.RATIO,

View file

@ -2,20 +2,13 @@ define([
"Game/Core/Loader/Level", "Game/Core/Loader/Level",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Lib/Vendor/Pixi", "Lib/Vendor/Pixi"
"Game/Client/View/Abstract/Layer"
], ],
function (Parent, Settings, nc, PIXI, AbstractLayer) { function (Parent, Settings, Nc, PIXI) {
"use strict";
function Level (uid, engine, gameObjects) { function Level (uid, engine, gameObjects) {
Parent.call(this, uid, engine, gameObjects); Parent.call(this, uid, engine, gameObjects);
this.levelSize = {
width: 0,
height: 0
}
} }
Level.prototype = Object.create(Parent.prototype); Level.prototype = Object.create(Parent.prototype);
@ -46,7 +39,7 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) {
loader.onComplete = function() { callback(levelData); }; loader.onComplete = function() { callback(levelData); };
loader.onProgress = function() { loader.onProgress = function() {
var progress = parseInt(100 / numPaths * ++count, 10) + 1; var progress = parseInt(100 / numPaths * ++count, 10) + 1;
nc.trigger(nc.ns.client.view.preloadBar.update, progress); Nc.trigger(Nc.ns.client.view.preloadBar.update, progress);
} }
loader.load(); loader.load();
}; };
@ -62,42 +55,28 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) {
return n; return n;
} }
/* var characterNames = ["Chuck"];
// Single File Animations Preloading var animationSets = ["WithArms"];//, "WithArms"];
var animationSets = ["WithArms", "WithoutArms"];
var addition = ""; var addition = "";
for (var i = 0; i < characterNames.length; i++) { for (var i = 0; i < characterNames.length; i++) {
var characterName = characterNames[i]; var characterName = characterNames[i];
for (var j = 1; j <= 126; j++) { for (var j = 1; j <= 126; j++) {
for (var k = 0; k < animationSets.length; k++) { for (var k = 0; k < animationSets.length; k++) {
var animationSet = animationSets[k]; var animationSet = animationSets[k];
addition = animationSet == "WithoutArms" ? "WithoutArms" : "";
paths.push( paths.push(
Settings.GRAPHICS_PATH Settings.GRAPHICS_PATH
+ Settings.GRAPHICS_SUBPATH_CHARACTERS + Settings.GRAPHICS_SUBPATH_CHARACTERS
+ characterName + characterName
+ "/Animation/" + "/Animation/"
+ animationSet + animationSet
+ "/ChuckAnimations0" + "/ChuckAnimations" + addition + "0"
+ padF(j) + padF(j)
+ ".png" + ".png"
); );
}; };
}; };
}; };
*/
var characterNames = ["Chuck"];
var characterName = characterNames[0];
paths.push(
Settings.GRAPHICS_PATH
+ Settings.GRAPHICS_SUBPATH_CHARACTERS
+ characterName
+ "/Animation/"
+ "/TexturePacker"
+ "/chuck_sheet.json"
);
paths.push( paths.push(
Settings.GRAPHICS_PATH Settings.GRAPHICS_PATH
@ -109,24 +88,5 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) {
return paths; return paths;
}; };
Level.prototype.setupLayer = function(options, behind, referenceId) {
Parent.prototype.setupLayer.call(this, options, behind, referenceId);
var parallaxSpeed = 0.0; // default parallax
if (options.properties && options.properties.parallaxSpeed) {
parallaxSpeed = parseFloat(options.properties.parallaxSpeed);
}
nc.trigger(
nc.ns.client.view.layer.createAndInsert,
options.layerId,
{
parallaxSpeed: parallaxSpeed,
levelSize: this.levelSize
},
behind,
referenceId
);
};
return Level; return Level;
}); });

View file

@ -1,32 +1,16 @@
define([ define([
"Game/Core/Loader/TiledLevel", "Game/Core/Loader/TiledLevel",
"Game/Config/Settings", "Game/Config/Settings"
"Lib/Utilities/NotificationCenter",
], ],
function (Parent, Settings, nc) { function (Parent, Settings) {
"use strict"; function TiledLevel(uid, engine, gameObjects) {
Parent.call(this, uid, engine, gameObjects);
function TiledLevel(uid, engine) {
this.layerId = "background";
Parent.call(this, uid, engine);
} }
TiledLevel.prototype = Object.create(Parent.prototype); TiledLevel.prototype = Object.create(Parent.prototype);
TiledLevel.prototype.setup = function(levelData) {
var tilesLayerData = this.getLayer(levelData, "tiles");
this.levelSize = {
width: tilesLayerData.width * Settings.TILE_SIZE,
height: tilesLayerData.height * Settings.TILE_SIZE
};
nc.trigger(nc.ns.client.view.layer.levelSizeUpdate, this.levelSize);
Parent.prototype.setup.call(this, levelData);
};
TiledLevel.prototype.getAssetPaths = function(levelData) { TiledLevel.prototype.getAssetPaths = function(levelData) {
var paths = Parent.prototype.getAssetPaths.call(this, levelData); var paths = Parent.prototype.getAssetPaths.call(this, levelData);
@ -56,100 +40,12 @@ function (Parent, Settings, nc) {
paths.push(texturePath); paths.push(texturePath);
}; };
for (var i = 0; i < levelData.layers.length; i++) { // FIXME: Get background image
var layer = levelData.layers[i];
if (layer.type == "imagelayer") {
paths.push(Settings.MAPS_PATH + layer.image);
}
};
return paths; return paths;
} }
TiledLevel.prototype.setupLayer = function(options, behind, referenceId) {
var self = this;
Parent.prototype.setupLayer.call(this, options, behind, referenceId);
// So far only one image per layer is possible because of Tiled editor
if (options.type == "imagelayer") {
var texturePath = Settings.MAPS_PATH + options.image;
var callback = function(mesh) {
nc.trigger(nc.ns.client.view.mesh.add, options.layerId, mesh);
nc.trigger(nc.ns.client.view.mesh.update, options.layerId, mesh, {
x: 0,//self.levelData.width * Settings.TILE_SIZE / 2,
y: 0,//self.levelData.height * Settings.TILE_SIZE / 2,
pivot: {
x: mesh.texture.width / 2,
y: mesh.texture.height / 2
},
xScale: 1,
yScale: 1
});
}
nc.trigger(nc.ns.client.view.mesh.create,
options.layerId,
texturePath,
callback,
{
alpha: options.opacity
}
);
}
// Adding tiles without collision
else if (options.type == "tilelayer" && options.name != "tiles") {
this.createNonCollidingTiles(options);
}
};
TiledLevel.prototype.createNonCollidingTiles = function(options) {
var data = options.data;
var tilesOptions = [];
for (var i = 0; i < data.length; i++) {
var gid = data[i];
if(gid === 0) continue;
var imagePath = this.getTileImagePath(gid);
var parts = imagePath.split("/");
var tileType = parts[parts.length - 1].split(".")[0].split("")
var callback = function(mesh) {
nc.trigger(nc.ns.client.view.mesh.add, options.layerId, mesh);
}
nc.trigger(nc.ns.client.view.mesh.create,
options.layerId,
Settings.MAPS_PATH + imagePath,
callback,
{
width: Settings.TILE_SIZE,
height: Settings.TILE_SIZE,
x: (i % options.width) * Settings.TILE_SIZE,
y: parseInt(i / options.width , 10) * Settings.TILE_SIZE,
}
);
}
}
TiledLevel.prototype.getLayer = function(levelData, name) {
for (var i = 0; i < levelData.layers.length; i++) {
if(levelData.layers[i].name === name) {
return levelData.layers[i];
}
}
throw "Layer '" + name + "' not found.";
};
return TiledLevel; return TiledLevel;
}); });

View file

@ -1,60 +1,28 @@
define([ define([
"Game/Client/Player", "Game/Client/Player",
"Game/Config/Settings", "Game/Config/Settings"
"Lib/Utilities/NotificationCenter",
"Lib/Utilities/Assert",
"Game/Client/Control/PlayerController",
], ],
function (Parent, Settings, nc, Assert, PlayerController) { function (Parent, Settings) {
"use strict";
function Me(id, physicsEngine, user) { function Me(id, physicsEngine, user) {
Parent.call(this, id, physicsEngine, user); Parent.call(this, id, physicsEngine, user);
// View uses this to calculate center position
this.lookAtXY = {
x: Settings.VIEWPORT_LOOK_AHEAD,
y: 0
};
this.lastServerPositionState = { this.lastServerPositionState = {
p: { p: {
x: 0, x: 0,
y: 0 y: 0
} }
}; };
this.arrowMesh = null;
this.createAndAddArrow();
this.playerController = new PlayerController(this);
} }
Me.prototype = Object.create(Parent.prototype); Me.prototype = Object.create(Parent.prototype);
Me.prototype.lookAt = function(x, y) {
this.lookAtXY = {
x: x,
y: y
};
Parent.prototype.lookAt.call(this, x, y);
};
Me.prototype.getLookAt = function() {
return {
x: this.lookAtXY.x,
y: this.lookAtXY.y
};
};
Me.prototype.setLastServerPositionState = function(update) { Me.prototype.setLastServerPositionState = function(update) {
this.lastServerPositionState = update; this.lastServerPositionState = update;
}; };
// Checks if client should send out its position to server Me.prototype.isPositionStateUpdateNeeded = function() {
Me.prototype.isPositionStateOverrideNeeded = function() {
if(!this.doll) { if(!this.doll) {
return false; return false;
@ -67,20 +35,20 @@ function (Parent, Settings, nc, Assert, PlayerController) {
var difference = { var difference = {
x: Math.abs(this.lastServerPositionState.p.x - this.doll.body.GetPosition().x), x: Math.abs(this.lastServerPositionState.p.x - this.doll.body.GetPosition().x),
y: Math.abs(this.lastServerPositionState.p.y - this.doll.body.GetPosition().y) y: Math.abs(this.lastServerPositionState.p.y - this.doll.body.GetPosition().y)
}; }
if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS || if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS
difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) { || difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) {
return true; return true;
} }
return false; return false;
}; };
Me.prototype.getPositionStateOverride = function() { Me.prototype.getPositionStateUpdate = function() {
return { return {
p: this.doll.body.GetPosition().Copy(), p: this.doll.body.GetPosition().Copy(),
lv: this.doll.body.GetLinearVelocity().Copy() lv: this.doll.body.GetLinearVelocity().Copy()
}; }
}; };
Me.prototype.acceptPositionStateUpdateFromServer = function() { Me.prototype.acceptPositionStateUpdateFromServer = function() {
@ -89,39 +57,10 @@ function (Parent, Settings, nc, Assert, PlayerController) {
}; };
Me.prototype.resetPositionState = function(options) { Me.prototype.resetPositionState = function(options) {
Assert.number(options.p.x, options.p.y);
Assert.number(options.lv.x, options.lv.y);
this.doll.body.SetPosition(options.p); this.doll.body.SetPosition(options.p);
this.doll.body.SetLinearVelocity(options.lv); this.doll.body.SetLinearVelocity(options.lv);
}; };
Me.prototype.createAndAddArrow = function() {
var self = this;
var position = this.getPosition();
var options = {
x: position.x * Settings.RATIO,
y: position.y * Settings.RATIO,
};
var callback = function(arrowMesh) {
self.arrowMesh = arrowMesh;
};
nc.trigger(nc.ns.client.view.playerArrow.createAndAdd, callback, options);
};
Me.prototype.render = function() {
Parent.prototype.render.call(this);
var position = this.getPosition();
var options = {
x: position.x * Settings.RATIO,
y: position.y * Settings.RATIO,
};
nc.trigger(nc.ns.client.view.playerArrow.update, this.arrowMesh, options);
};
return Me; return Me;
}); });

View file

@ -7,14 +7,9 @@ define([
"Game/Client/View/DomController" "Game/Client/View/DomController"
], ],
function (ProtocolHelper, GameController, User, nc, Settings, domController) { function (ProtocolHelper, GameController, User, Nc, Settings, DomController) {
"use strict"; function Networker (socketLink) {
function Networker (socketLink, channelName, nickname) {
this.channelName = channelName;
this.nickname = nickname;
this.socketLink = socketLink; this.socketLink = socketLink;
this.gameController = null; this.gameController = null;
this.users = {}; this.users = {};
@ -25,47 +20,33 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
var self = this; var self = this;
this.socketLink.on('message', function (message) { this.socketLink.on('message', function (message) {
var m = JSON.parse(message) var m = JSON.parse(message)
if(Settings.NETWORK_LOG_INCOMING) { if(Settings.NETWORK_LOG_INCOMING) {
var shouldBeFiltered = false;
var keyword;
for (var i = 0; i < Settings.NETWORK_LOG_FILTER.length; i++) { if (message.indexOf('worldUpdate') == -1 && message.indexOf('pong') == -1) {
keyword = Settings.NETWORK_LOG_FILTER[i];
if(message.search(keyword) != -1) {
shouldBeFiltered = true;
break;
}
};
if(!shouldBeFiltered) {
console.log('INCOMING', message); console.log('INCOMING', message);
} }
} }
ProtocolHelper.applyCommand(message, self); ProtocolHelper.applyCommand(message, self);
}); });
nc.on(nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this); Nc.on(Nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this);
nc.on(nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this); Nc.on(Nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this);
domController.setNick(nickname);
} }
// Socket callbacks // Socket callbacks
Networker.prototype.onConnect = function () { Networker.prototype.onConnect = function () {
console.log('connected.') console.log('connected.')
if(this.channelName) { var channel = JSON.parse(localStorage["channel"]);
var player = JSON.parse(localStorage["player"]);
if(channel.name) {
var options = { var options = {
channelName: this.channelName, channelName: channel.name,
nickname: this.nickname nickname: player.nickname
} }
this.sendCommand('join', options); this.sendCommand('join', options);
domController.setConnected(true);
} else { } else {
alert("Error: no channel name");
window.location.href = "/"; window.location.href = "/";
} }
} }
@ -74,7 +55,7 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
//if(this.gameController) this.gameController.destruct(); //if(this.gameController) this.gameController.destruct();
//this.gameController = null; //this.gameController = null;
console.log('disconnected. game destroyed. no auto-reconnect'); console.log('disconnected. game destroyed. no auto-reconnect');
domController.setConnected(false); document.body.style.backgroundColor = '#aaaaaa';
} }
Networker.prototype.onJoinSuccess = function (options) { Networker.prototype.onJoinSuccess = function (options) {
@ -93,21 +74,18 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
} }
Networker.prototype.onJoinError = function(options) { Networker.prototype.onJoinError = function(options) {
alert(options.message); // alert(options.message);
window.location.href = "/"; window.location.href = "/";
}; };
Networker.prototype.onLevelLoaded = function() { Networker.prototype.onLevelLoaded = function() {
/*
this.gameController.createMe(this.users[this.meUserId]); this.gameController.createMe(this.users[this.meUserId]);
for (var userId in this.users) { for (var userId in this.users) {
if(this.meUserId != userId) { if(this.meUserId != userId) {
this.gameController.createPlayer(this.users[userId]); this.gameController.createPlayer(this.users[userId]);
} }
}*/ }
this.gameController.onLevelLoaded();
this.sendGameCommand("clientReady"); this.sendGameCommand("clientReady");
}; };
@ -129,6 +107,8 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
this.socketLink.send(message); this.socketLink.send(message);
if(Settings.NETWORK_LOG_OUTGOING) { if(Settings.NETWORK_LOG_OUTGOING) {
if(Settings.NETWORK_LOG_FILTER.length > 0) {
var shouldBeFiltered = false; var shouldBeFiltered = false;
var keyword; var keyword;
@ -143,6 +123,9 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
if(!shouldBeFiltered) { if(!shouldBeFiltered) {
console.log('OUTGOING', message); console.log('OUTGOING', message);
} }
} else {
console.log('OUTGOING', message);
}
} }
} }
@ -174,16 +157,12 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
} }
Networker.prototype.onGameCommand = function(message) { Networker.prototype.onGameCommand = function(message) {
if (this.gameController) {
this.gameController.onGameCommand(message); this.gameController.onGameCommand(message);
} else {
console.warn("Networker.onGameCommand: this.gameController is undefined", message);
}
} }
Networker.prototype.onPong = function(timestamp) { Networker.prototype.onPong = function(timestamp) {
var ping = (Date.now() - parseInt(timestamp, 10)); var ping = (Date.now() - parseInt(timestamp, 10));
domController.setPing(ping); DomController.setPing(ping);
setTimeout(this.ping.bind(this), 1000); setTimeout(this.ping.bind(this), 1000);
}; };
@ -191,23 +170,14 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) {
if(this.gameController) { if(this.gameController) {
this.gameController.destroy(); this.gameController.destroy();
delete this.gameController;
} }
this.gameController = new GameController(options); this.gameController = new GameController(options);
this.gameController.createMe(this.users[this.meUserId]);
for (var userId in this.users) {
if(this.meUserId != userId) {
this.gameController.createPlayer(this.users[userId]);
}
}
this.gameController.beginRound();
}; };
Networker.prototype.onEndRound = function() { Networker.prototype.onEndRound = function() {
this.gameController.endRound(); this.gameController.toggleInfo(true);
}; };
return Networker; return Networker;

View file

@ -3,21 +3,17 @@ define([
"Game/Config/Settings", "Game/Config/Settings",
"Game/Client/View/DomController", "Game/Client/View/DomController",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Game/Client/View/Pixi/DebugDraw",
"Game/Client/View/Pixi/Layers/Debug"
], ],
function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) { function (Parent, Settings, DomController, Box2D, Nc) {
"use strict";
function Engine () { function Engine () {
Parent.call(this); Parent.call(this);
this.debugMode = false; this.debugMode = false;
nc.on(nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this); Nc.on(Nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this);
} }
Engine.prototype = Object.create(Parent.prototype); Engine.prototype = Object.create(Parent.prototype);
@ -25,19 +21,19 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) {
Engine.prototype.onToggleDebugMode = function(debugMode) { Engine.prototype.onToggleDebugMode = function(debugMode) {
this.debugMode = debugMode; this.debugMode = debugMode;
if(!this.debugDraw) { if(this.debugMode && !this.debugDraw) {
this.setupDebugDraw(); this.setupDebugDraw();
} }
debugLayer.container.visible = this.debugMode;
}; };
Engine.prototype.setupDebugDraw = function () { Engine.prototype.setupDebugDraw = function () {
// set debug draw var debugSprite = DomController.getDebugCanvas().getContext("2d");
this.debugDraw = new DebugDraw();
this.debugDraw.SetSprite(debugLayer.graphics); // set debug draw
this.debugDraw = new Box2D.Dynamics.b2DebugDraw();
this.debugDraw.SetSprite(debugSprite);
this.debugDraw.SetDrawScale(Settings.RATIO); this.debugDraw.SetDrawScale(Settings.RATIO);
this.debugDraw.SetFillAlpha(0.5); this.debugDraw.SetFillAlpha(0.5);
this.debugDraw.SetLineThickness(1.0); this.debugDraw.SetLineThickness(1.0);
@ -53,7 +49,7 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) {
); );
this.world.SetDebugDraw(this.debugDraw); this.world.SetDebugDraw(this.debugDraw);
}; }
Engine.prototype.update = function () { Engine.prototype.update = function () {
Parent.prototype.update.call(this); Parent.prototype.update.call(this);
@ -61,7 +57,7 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) {
if(this.debugMode) { if(this.debugMode) {
this.world.DrawDebugData(); this.world.DrawDebugData();
} }
}; }
return Engine; return Engine;
}); })

View file

@ -4,21 +4,15 @@ define([
"Game/Config/Settings" "Game/Config/Settings"
], ],
function (Parent, nc, Settings) { function (Parent, Nc, Settings) {
"use strict"; function Player(id, physicsEngine, user) {
function Player(id, physicsEngine, user, isMe) {
Parent.call(this, id, physicsEngine, user); Parent.call(this, id, physicsEngine, user);
this.healthBarView = null; this.playerInfoView = null;
this.healthBarViewVisibleTimeout = null; this.playerInfoViewVisibleTimeout = null;
this.healthBarViewVisible = false; this.playerInfoViewVisible = false;
this.initHealthBar(); this.initHealthBar();
this.ncTokens = (this.ncTokens || []).concat([
nc.on(nc.ns.client.game.events.render, this.render, this)
]);
} }
Player.prototype = Object.create(Parent.prototype); Player.prototype = Object.create(Parent.prototype);
@ -35,36 +29,36 @@ function (Parent, nc, Settings) {
Player.prototype.initHealthBar = function() { Player.prototype.initHealthBar = function() {
var self = this; var self = this;
this.healthBarViewVisible = false; this.playerInfoViewVisible = false;
var options = { var options = {
x: 100, x: 100,
y: 100, y: 100,
healthFactor: this.stats.health / 100, healthFactor: this.stats.health / 100,
visible: this.healthBarViewVisible visible: this.playerInfoViewVisible
}; };
var callback = function(healthBarView) { var callback = function(playerInfoView) {
self.healthBarView = healthBarView; self.playerInfoView = playerInfoView;
} }
nc.trigger(nc.ns.client.view.healthBar.createAndAdd, callback, options); Nc.trigger(Nc.ns.client.view.playerInfo.createAndAdd, callback, options);
}; };
Player.prototype.onHealthChange = function() { Player.prototype.onHealthChange = function() {
if(this.stats.health != 100) { if(this.stats.health != 100) {
this.setHealthBarVisible(true); this.setPlayerInfoVisible(true);
} }
}; };
Player.prototype.spawn = function(x, y) { Player.prototype.spawn = function(x, y) {
Parent.prototype.spawn.call(this, x, y); Parent.prototype.spawn.call(this, x, y);
this.setHealthBarVisible(false); this.setPlayerInfoVisible(false);
}; };
Player.prototype.setHealthBarVisible = function(visible) { Player.prototype.setPlayerInfoVisible = function(visible) {
var self = this; var self = this;
this.healthBarViewVisible = visible; this.playerInfoViewVisible = visible;
if(this.healthBarViewVisibleTimeout) clearTimeout(this.healthBarViewVisibleTimeout); if(this.playerInfoViewVisibleTimeout) clearTimeout(this.playerInfoViewVisibleTimeout);
if(visible) { if(visible) {
var position = this.getPosition(); var position = this.getPosition();
@ -73,45 +67,44 @@ function (Parent, nc, Settings) {
x: position.x * Settings.RATIO, x: position.x * Settings.RATIO,
y: position.y * Settings.RATIO, y: position.y * Settings.RATIO,
healthFactor: this.stats.health / 100, healthFactor: this.stats.health / 100,
visible: this.healthBarViewVisible visible: this.playerInfoViewVisible
}; };
nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, options); Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, options);
this.healthBarViewVisibleTimeout = setTimeout(function() { this.playerInfoViewVisibleTimeout = setTimeout(function() {
self.healthBarViewVisible = false; self.playerInfoViewVisible = false;
nc.trigger(nc.ns.client.view.healthBar.update, self.healthBarView, {visible: self.healthBarViewVisible}); Nc.trigger(Nc.ns.client.view.playerInfo.update, self.playerInfoView, {visible: self.playerInfoViewVisible});
}, Settings.HEALTH_DISPLAY_TIME * 1000); }, Settings.HEALTH_DISPLAY_TIME * 1000);
} else { } else {
nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, {visible: this.healthBarViewVisible}); Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, {visible: this.playerInfoViewVisible});
} }
}; };
Player.prototype.getNickname = function() {
return this.user.options.nickname;
};
Player.prototype.render = function() { Player.prototype.render = function() {
if(this.doll) { if(this.doll) {
this.doll.render(); this.doll.render();
} }
if(this.healthBarViewVisible) { if(this.playerInfoViewVisible) {
var position = this.getPosition(); var position = this.getPosition();
var options = { var options = {
healthFactor: this.stats.health / 100, healthFactor: this.stats.health / 100,
x: position.x * Settings.RATIO, x: position.x * Settings.RATIO,
y: position.y * Settings.RATIO, y: position.y * Settings.RATIO,
} }
nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, options); Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, options);
} }
}; };
Player.prototype.isHoldingSomething = function() {
return !!this.holdingItem;
};
Player.prototype.destroy = function() { Player.prototype.destroy = function() {
clearTimeout(this.healthBarViewVisibleTimeout); clearTimeout(this.playerInfoViewVisibleTimeout);
nc.trigger(nc.ns.client.view.healthBar.remove, this.healthBarView); Nc.trigger(Nc.ns.client.view.playerInfo.remove, this.playerInfoView);
nc.off(this.ncTokens);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };

View file

@ -1,53 +0,0 @@
define([
"Lib/Utilities/QuerySelector",
"Lib/Utilities/NotificationCenter"
],
function (qs, nc) {
"use strict";
function PointerLockManager() {
this.canvas = qs.$("#canvas");
this.listeners = [];
if (!document) {
throw new Error("Using PointerLockManager, but window.document is not defined.");
}
document.addEventListener('pointerlockchange', this.update.bind(this), false);
document.addEventListener('mozpointerlockchange', this.update.bind(this), false);
document.addEventListener('webkitpointerlockchange', this.update.bind(this), false);
this.ncTokens = [
nc.on(nc.ns.client.pointerLock.request, this.request, this)
];
}
PointerLockManager.prototype.request = function() {
var canvas = this.canvas;
canvas.requestPointerLock = canvas.requestPointerLock ||
canvas.mozRequestPointerLock ||
canvas.webkitRequestPointerLock;
// Ask the browser to lock the pointer
canvas.requestPointerLock();
}
// called by the browser event and others
PointerLockManager.prototype.update = function(e, options) {
options = options ? options : {};
nc.trigger(nc.ns.client.pointerLock.change, this.isLocked(), options);
};
PointerLockManager.prototype.isLocked = function() {
return document.pointerLockElement === this.canvas ||
document.mozPointerLockElement === this.canvas ||
document.webkitPointerLockElement === this.canvas;
};
return new PointerLockManager();
});

View file

@ -1,67 +0,0 @@
define([
"Lib/Utilities/Abstract",
"Lib/Utilities/NotificationCenter"
],
function (Abstract, nc) {
"use strict";
function Layer(name, options) {
this.name = name;
this.parallaxSpeed = options.parallaxSpeed || 0;
this.zoom = {
current: window.innerWidth / 600,
target: window.innerWidth / 600
};
this.position = {
current: { x: 0, y: 0},
target: { x: 0, y: 0}
};
if(options.levelSize) {
this.position.current.x = -options.levelSize.width / 2;
this.position.current.y = -options.levelSize.height / 2;
}
this.ncTokens = [];
}
Object.defineProperty(Layer, 'ID', {
value: {
TILE: 'tile',
ITEM: 'item',
SPAWN: 'spawnpoints'
}
});
Abstract.prototype.addMethod.call(Layer, 'show');
Abstract.prototype.addMethod.call(Layer, 'hide');
Abstract.prototype.addMethod.call(Layer, 'createMesh', ['texturePath', 'callback', 'options']);
Abstract.prototype.addMethod.call(Layer, 'createAnimatedMesh', ['texturePaths', 'callback', 'options']);
Abstract.prototype.addMethod.call(Layer, 'addMesh', ['mesh']);
Abstract.prototype.addMethod.call(Layer, 'removeMesh', ['mesh']);
Abstract.prototype.addMethod.call(Layer, 'updateMesh', ['mesh', 'options']);
Abstract.prototype.addMethod.call(Layer, 'render', ['centerPosition']);
Layer.prototype.getName = function() {
return this.name;
};
Layer.prototype.setPosition = function(centerPosition) {
this.position.target.x = centerPosition.x;
this.position.target.y = centerPosition.y;
};
Layer.prototype.setZoom = function(z) {
this.zoom.target = z;
};
Layer.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
nc.off(this.ncTokens[i]);
};
};
return Layer;
});

View file

@ -1,106 +0,0 @@
define([
"Lib/Utilities/Abstract",
"Game/Client/View/DomController",
"Game/Config/Settings",
"Lib/Utilities/Exception",
"Lib/Utilities/NotificationCenter"
],
function (Abstract, domController, Settings, Exception, nc) {
"use strict";
function AbstractView () {
this.me = null;
this.canvas = null;
this.debugMode = false;
this.ncTokens = [
nc.on(nc.ns.client.view.display.change, this.onDisplaySizeChange, this),
nc.on(nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this),
nc.on(nc.ns.client.game.zoomIn, this.onZoomIn, this),
nc.on(nc.ns.client.game.zoomOut, this.onZoomOut, this),
nc.on(nc.ns.client.game.zoomReset, this.onZoomReset, this),
nc.on(nc.ns.client.view.preloadBar.update, this.onUpdateLoader, this),
];
}
Abstract.prototype.addMethod.call(AbstractView, 'render');
Abstract.prototype.addMethod.call(AbstractView, 'addFilter', ['mesh', 'options']);
Abstract.prototype.addMethod.call(AbstractView, 'removeFilter', ['mesh', 'options']);
Abstract.prototype.addMethod.call(AbstractView, 'setCameraPosition', ['x', 'y']);
Abstract.prototype.addMethod.call(AbstractView, 'onZoomIn');
Abstract.prototype.addMethod.call(AbstractView, 'onZoomOut');
Abstract.prototype.addMethod.call(AbstractView, 'onZoomReset');
Abstract.prototype.addMethod.call(AbstractView, 'toggleInfo', ['show', 'string']);
Abstract.prototype.addMethod.call(AbstractView, 'onUpdateLoader', ['progress']);
AbstractView.prototype.isWebGlEnabled = function () {
try {
return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' );
} catch(e) {
return false;
}
}
AbstractView.prototype.initCanvas = function (canvas) {
this.canvas = canvas;
domController.initCanvas(canvas);
}
AbstractView.prototype.setMe = function(player) {
this.me = player;
};
/*
AbstractView.prototype.calculateCameraPosition = function() {
var reference = this.me.getPosition();
var pos = {};
pos.x = reference.x;
pos.y = reference.y;
pos.x = pos.x * Settings.RATIO;
pos.y = -(pos.y * Settings.RATIO);
pos.x += this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4;
pos.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4;
return pos;
};
*/
AbstractView.prototype.onDisplaySizeChange = function(isFullScreen) {
/*
if (!isFullScreen) {
Settings.STAGE_WIDTH = 600;
Settings.STAGE_HEIGHT = 400;
} else {
// FIXME: Create FIXME meme (dumb and dumber)
// FIXME: don't overwrite Settings
Settings.STAGE_WIDTH = window.innerWidth;
Settings.STAGE_HEIGHT = window.innerHeight;
}
*/
Settings.STAGE_WIDTH = window.innerWidth;
Settings.STAGE_HEIGHT = window.innerHeight;
};
AbstractView.prototype.onToggleDebugMode = function(debugMode) {
if(debugMode) {
//this.setCameraPosition(-Settings.STAGE_WIDTH / 2, -Settings.STAGE_HEIGHT / 2);
}
this.debugMode = debugMode;
};
AbstractView.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
nc.off(this.ncTokens[i]);
};
};
return AbstractView;
});

View file

@ -1,168 +1,91 @@
define([ define([
"Game/Config/Settings", 'Game/Config/Settings',
"Lib/Utilities/NotificationCenter", 'Lib/Utilities/NotificationCenter',
"Lib/Vendor/Screenfull", "Lib/Vendor/Stats",
"Game/Client/View/Graph", "Lib/Vendor/Screenfull"
"Game/Client/PointerLockManager"
], ],
function (Settings, nc, Screenfull, Graph, pointerLockManager) { function (Settings, Nc, Stats, Screenfull) {
"use strict";
function DomController() { function DomController() {
this.canvas = null; this.canvas = document.getElementById("canvas");
this.debugCanvas = null;
this.stats = null; this.stats = null;
this.ping = null; this.ping = null;
this.nickContainer = null;
this.fpsContainer = null;
this.devToolsContainer = null;
this.frames = 0;
this.canvas = document.getElementById("canvas"); Nc.on(Nc.ns.client.view.events.ready, this.initDevTools, this);
this.initDevTools();
} }
DomController.prototype.initDevTools = function() { DomController.prototype.initDevTools = function() {
var self = this; var self = this;
var li, button, label;
this.devToolsContainer = document.getElementById("menuBar");
// create back to menu button
li = document.createElement("li");
li.id = "back-to-menu";
button = document.createElement("button");
button.innerHTML = "Menu";
button.onclick = function() {
window.location.href="/";
};
li.appendChild(button);
this.devToolsContainer.appendChild(li);
// create user name
li = document.createElement("li");
label = document.createElement("label");
label.appendChild(document.createTextNode("?"));
li.appendChild(label);
this.devToolsContainer.appendChild(li);
this.nickContainer = label;
// create fps label with updater
li = document.createElement("li");
label = document.createElement("label");
label.id = "label-fps";
li.appendChild(label);
this.devToolsContainer.appendChild(li);
this.fpsContainer = label;
/*
// create new fps meter
li = document.createElement("li");
var fpsCanvas = document.createElement("canvas");
fpsCanvas.id = "graph-fps";
fpsCanvas.width = "100";
fpsCanvas.height = "27";
li.appendChild(fpsCanvas);
this.devToolsContainer.appendChild(li);
this.fpsGraph = new Graph(fpsCanvas.getContext("2d"), true);
this.fpsGraph.onUpdate(function(value){
self.fpsContainer.innerHTML = "FPS:" + value;
var color,
alpha = 0.8;
if (value >= 50) {
color = "rgba(136, 209, 018, " + alpha + ")";
} else if (value > 25) {
color = "rgba(204, 114, 018, " + alpha + ")";
} else {
color = "rgba(224, 018, 018, " + 1 + ")";
}
return color;
});
// create new ping meter
li = document.createElement("li");
var pingCanvas = document.createElement("canvas");
pingCanvas.id = "graph-fps";
pingCanvas.width = "100";
pingCanvas.height = "27";
li.appendChild(pingCanvas);
this.devToolsContainer.appendChild(li);
this.pingGraph = new Graph(pingCanvas.getContext("2d"), false, {
scaleOverride: false,
scaleStartValue: 0,
scaleStepWidth: 0,
scaleSteps: 0
});
*/
setInterval(function() {
self.fpsContainer.innerHTML = "FPS:" + self.frames;
self.frames = 0;
}, 1000);
// create Ping: container
li = document.createElement("li");
this.ping = document.createElement("label");
li.appendChild(this.ping);
this.devToolsContainer.appendChild(li);
// create debug mode
li = document.createElement("li");
label = document.createElement("label");
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.onclick = function(e) {
nc.trigger(nc.ns.client.view.debugMode.toggle, e.target.checked);
};
label.appendChild(checkbox);
label.appendChild(document.createTextNode("Debug"));
li.appendChild(label);
this.devToolsContainer.appendChild(li);
// create dev tools container
this.devToolsContainer = document.createElement("div");
this.devToolsContainer.id = "devtools";
document.body.appendChild(this.devToolsContainer);
// create Fullscreen // create Fullscreen
li = document.createElement("li"); var p = document.createElement("p");
li.id = "fullscreen"; var button = document.createElement("button");
button = document.createElement("button");
button.innerHTML = "Fullscreen"; button.innerHTML = "Fullscreen";
button.onclick = function() { button.onclick = function() {
if(Screenfull.enabled) { if(Screenfull.enabled) {
pointerLockManager.request();
Screenfull.request(self.canvas); Screenfull.request(self.canvas);
} }
}; }
li.appendChild(button); p.appendChild(button);
this.devToolsContainer.appendChild(li); this.devToolsContainer.appendChild(p);
// FIXME : isn't this a weird place for this?
window.onresize = function() { window.onresize = function() {
nc.trigger(nc.ns.client.view.display.change); if(Screenfull.enabled) {
}; Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen);
}
}
// create Ping: container
this.ping = document.createElement("span");
this.devToolsContainer.appendChild(this.ping);
// create FPS stats
this.stats = new Stats();
this.stats.setMode(0);
this.devToolsContainer.appendChild(this.stats.domElement);
// create debug mode
var label = document.createElement("label");
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.onclick = function(e) {
Nc.trigger(Nc.ns.client.view.debugMode.toggle, e.target.checked);
self.getDebugCanvas().style.display = e.target.checked ? "" : "none";
}
label.appendChild(checkbox);
label.appendChild(document.createTextNode("Debug"));
this.devToolsContainer.appendChild(label);
// create health
this.health = document.createElement("span");
this.health.innerHTML = "Health: 100";
p = document.createElement("p");
p.appendChild(this.health);
this.devToolsContainer.appendChild(p);
}; };
DomController.prototype.setNick = function (nick) { DomController.prototype.statsBegin = function() {
this.nickContainer.innerHTML = nick; if(this.stats) {
this.stats.begin();
}
}; };
DomController.prototype.fpsStep = function() { DomController.prototype.statsEnd = function() {
this.frames++; if(this.stats) {
// this.fpsGraph.step(); this.stats.end();
}
}; };
DomController.prototype.setPing = function(ping) { DomController.prototype.setPing = function(ping) {
this.ping.innerHTML = "Ping:" + ping; this.ping.innerHTML = "Ping: " + ping;
// this.pingGraph.addValue(ping);
}; };
DomController.prototype.getCanvasContainer = function () { DomController.prototype.getCanvasContainer = function () {
@ -173,32 +96,31 @@ function (Settings, nc, Screenfull, Graph, pointerLockManager) {
} else { } else {
throw 'Canvas Container missing: #' + Settings.CANVAS_DOM_ID; throw 'Canvas Container missing: #' + Settings.CANVAS_DOM_ID;
} }
}; }
DomController.prototype.getCanvas = function () { DomController.prototype.getCanvas = function () {
return this.canvas; return this.canvas;
}; }
DomController.prototype.initCanvas = function (canvas) { DomController.prototype.initCanvas = function (canvas) {
nc.trigger(nc.ns.client.view.display.change, Screenfull.isFullscreen); Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen);
};
DomController.prototype.setConnected = function(connected) {
if(connected) {
document.body.style.backgroundColor = '';
} else {
document.body.style.backgroundColor = '#aaaaaa';
this.ping.innerHTML = "Disconnected. ".replace(/ /g, '&nbsp;');
this.ping.style.color = "#ff0000";
/*
self = this;
setTimeout(function(){self.ping.innerHTML = "Reload Page...".replace(/ /g, '&nbsp;');}, 3000);
setTimeout(function(){self.ping.innerHTML = "Reload in 3...".replace(/ /g, '&nbsp;');}, 6000);
setTimeout(function(){self.ping.innerHTML = "Reload in 2...".replace(/ /g, '&nbsp;');}, 7000);
setTimeout(function(){self.ping.innerHTML = "Reload in 1...".replace(/ /g, '&nbsp;');}, 8000);
setTimeout(function(){self.ping.innerHTML = "Reload now. ".replace(/ /g, '&nbsp;'); location.reload(); }, 9000);
*/
} }
DomController.prototype.getDebugCanvas = function () {
if(!this.debugCanvas) {
var canvas = document.createElement('canvas');
canvas.width = Settings.STAGE_WIDTH;
canvas.height = Settings.STAGE_HEIGHT;
this.debugCanvas = canvas;
this.getCanvasContainer().appendChild(canvas);
}
return this.debugCanvas;
}
DomController.prototype.setHealth = function(health) {
this.health.innerHTML = "Health: " + parseInt(health, 10);
}; };

View file

@ -1,99 +0,0 @@
define([
"Lib/Vendor/Chart"
],
function (Chart) {
"use strict";
function Graph(ctx, isStepCounter, newOptions) {
var numberOfGraphBars = 25;
var empty = new Array(numberOfGraphBars);
for (var i = empty.length - 1; i >= 0; i--) empty[i] = -1;
var data = {
labels: empty,
datasets: [
{
label: "no label",
fillColor: "rgba(220,220,220,1)",
strokeColor: "rgba(220,220,220,1)",
highlightFill: "rgba(220,220,220,1)",
data: empty
},
]};
var options = {
showScale: false,
scaleShowLabels: false,
showTooltips: false,
animation: false,
scaleBeginAtZero : true,
scaleShowGridLines : false,
scaleShowHorizontalLines: true,
scaleShowVerticalLines: true,
barShowStroke : false,
barStrokeWidth : 0,
barValueSpacing : 0,
barDatasetSpacing : 0,
responsive: false,
scaleBackdropPaddingY : 10,
scaleOverride: true,
scaleStartValue: 0,
scaleStepWidth: 1,
scaleSteps: 60
}
if (newOptions) {
if (newOptions.scaleOverride) options.scaleOverride = newOptions.scaleOverride;
if (newOptions.scaleStartValue) options.scaleStartValue = newOptions.scaleStartValue;
if (newOptions.scaleSteps) options.scaleSteps = newOptions.scaleSteps;
if (newOptions.scaleStepWidth) options.scaleStepWidth = newOptions.scaleStepWidth;
}
this.chart = new Chart(ctx).Bar(data, options);
this.stepCounter = 0;
this.currentValue = 0;
this.updateFunction = function(value){};
var self = this;
if (isStepCounter) {
setInterval(function(){
self.addValue(null);
}, 1000);
}
}
Graph.prototype.addValue = function (value) {
value = value ? value : this.stepCounter;
this.chart.addData( [value], "" );
this.currentValue = value;
this.stepCounter = 0;
var color = this.updateFunction(this.currentValue);
color = color ? color : "rgba(136, 209, 018, 1)"; // green
this.chart.datasets[0].bars[this.chart.datasets[0].bars.length-1].fillColor = color;
this.chart.removeData();
this.chart.update();
}
Graph.prototype.step = function() {
this.stepCounter++;
};
Graph.prototype.getCurrentValue = function() {
return this.currentValue;
};
Graph.prototype.onUpdate = function(f) {
this.updateFunction = f;
};
return Graph;
});

View file

@ -1,183 +0,0 @@
define([
"Lib/Utilities/NotificationCenter",
"Lib/Utilities/Exception",
"Game/Client/View/Pixi/Layer"
],
function (nc, Exception, Layer) {
"use strict";
function LayerManager(container, me) {
this.layers = [];
this.container = container;
this.ncTokens = [
nc.on(nc.ns.client.view.layer.createAndInsert, this.createAndInsert, this),
nc.on(nc.ns.client.view.mesh.create, this.createMesh, this),
nc.on(nc.ns.client.view.animatedMesh.create, this.createAnimatedMesh, this),
nc.on(nc.ns.client.view.mesh.add, this.addMesh, this),
nc.on(nc.ns.client.view.mesh.remove, this.removeMesh, this),
nc.on(nc.ns.client.view.mesh.update, this.updateMesh, this),
nc.on(nc.ns.client.view.mesh.addFilter, this.addFilter, this),
nc.on(nc.ns.client.view.mesh.removeFilter, this.removeFilter, this),
nc.on(nc.ns.client.view.mesh.swapMeshIndexes, this.swapMeshIndexes, this),
nc.on(nc.ns.client.view.mesh.swapMeshes, this.swapMeshes, this)
];
}
LayerManager.prototype.render = function(centerPosition, zoom) {
for (var i = 0; i < this.layers.length; i++) {
var layer = this.layers[i];
layer.render(centerPosition, zoom);
}
};
/*
* If no referenceId is given, the layer is inserted in the far background (behind=true)
* or in the foreground (behind=false/null)
*/
LayerManager.prototype.createAndInsert = function(id, options, behind, referenceId) {
var layer = new Layer(id, options);
this.insert(layer, behind, referenceId);
};
LayerManager.prototype.insert = function(newlayer, behind, referenceId) {
var referenceIndex = -1;
behind = !!behind;
if (referenceId) {
for(var i = 0; i < this.layers.length; i++) {
var layer = this.layers[i];
if (layer.getName() === referenceId) {
referenceIndex = i;
break;
}
}
if (referenceIndex === -1) {
throw new Exception('Reference Layer (' + referenceId + ') could not be found');
}
} else {
referenceIndex = behind ? 0 : this.container.children.length;
}
var layerIndex = behind ? referenceIndex : referenceIndex + 1;
this.layers.splice(layerIndex, 0, newlayer);
this.rearrangeLayers();
};
LayerManager.prototype.rearrangeLayers = function() {
var layer;
for (var i = this.layers.length - 1; i >= 0; i--) {
layer = this.layers[i];
if (this.container.children.indexOf(layer.getContainer()) !== -1) {
this.container.removeChild(layer.getContainer());
}
};
if (this.container.children.length !== 0) {
console.warn('Unmanaged stuff in container... ', this.container.children);
//throw new Exception('Unmanaged dirt in container... ');
}
for (var i = 0; i < this.layers.length; i++) {
layer = this.layers[i];
this.container.addChildAt(layer.getContainer(), i);
};
};
LayerManager.prototype.getLayerById = function(id) {
for (var i = 0; i < this.layers.length; i++) {
var layer = this.layers[i];
if (layer.getName() === id) {
return layer;
}
};
return null;
};
/* Delegate methods */
LayerManager.prototype.delegate = function() {
var methodName = arguments[0];
var layerId = arguments[1];
var layer = this.getLayerById(layerId);
if (!layer) {
throw new Exception('Layer (' + layerId + ') does not exist.');
}
var args = arguments;
Array.prototype.splice.call(args, 0, 2);
layer[methodName].apply(layer, args);
};
LayerManager.prototype.createMesh = function() {
var args = arguments;
Array.prototype.splice.call(args, 0, 0, 'createMesh')
this.delegate.apply(this, args);
};
LayerManager.prototype.createAnimatedMesh = function() {
Array.prototype.splice.call(arguments, 0, 0, 'createAnimatedMesh')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.addMesh = function() {
Array.prototype.splice.call(arguments, 0, 0, 'addMesh')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.removeMesh = function() {
Array.prototype.splice.call(arguments, 0, 0, 'removeMesh')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.updateMesh = function() {
Array.prototype.splice.call(arguments, 0, 0, 'updateMesh')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.addFilter = function() {
Array.prototype.splice.call(arguments, 0, 0, 'addFilter')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.removeFilter = function() {
Array.prototype.splice.call(arguments, 0, 0, 'removeFilter')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.swapMeshIndexes = function() {
Array.prototype.splice.call(arguments, 0, 0, 'swapMeshIndexes')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.swapMeshes = function() {
Array.prototype.splice.call(arguments, 0, 0, 'swapMeshes')
this.delegate.apply(this, arguments);
};
LayerManager.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
nc.off(this.ncTokens[i]);
};
for (var i = this.layers.length - 1; i >= 0; i--) {
var layer = this.layers[i];
layer.destroy();
};
};
return LayerManager;
});

View file

@ -1,22 +0,0 @@
define([
'Game/Config/Settings',
'Lib/Utilities/NotificationCenter',
"Lib/Vendor/Stats",
"Lib/Vendor/Screenfull"
],
function (Settings, nc, Stats, Screenfull) {
"use strict";
function Mesh() {
}
Mesh.prototype.render = function() {
};
return Mesh;
});

View file

@ -1,91 +0,0 @@
define([
"Lib/Vendor/Pixi"
],
function (PIXI) {
"use strict";
var Parent = PIXI.AbstractFilter;
function ColorRangeReplaceFilter() {
Parent.call(this);
this.passes = [this];
// set the uniforms
this.uniforms = {
minColor: {type: '3fv', value: [0,0,0]},
maxColor: {type: '3fv', value: [0,0,0]},
newColor: {type: '3fv', value: [0,0,0]},
brightnessOffset: {type: '1f', value: 0}
};
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
'varying vec4 vColor;',
'uniform sampler2D uSampler;',
'uniform vec3 minColor;',
'uniform vec3 maxColor;',
'uniform vec3 newColor;',
'uniform float brightnessOffset;',
'void main(void) {',
' vec4 pixel = texture2D(uSampler, vTextureCoord);',
' if(pixel.x >= minColor.x && pixel.y >= minColor.y && pixel.z >= minColor.z',
' && pixel.w == 1.0',
' && pixel.x <= maxColor.x && pixel.y <= maxColor.y && pixel.z <= maxColor.z) {',
' pixel.rgb = mix(pixel.rgb, vec3(0.2126*pixel.r + 0.7152*pixel.g + 0.0722*pixel.b), 1.0);', // desaturate to gray
' pixel.rgb += brightnessOffset;',
' pixel.rgb *= newColor;',
' }',
' gl_FragColor = pixel;',
'}'
];
}
ColorRangeReplaceFilter.prototype = Object.create(Parent.prototype);
ColorRangeReplaceFilter.prototype.constructor = ColorRangeReplaceFilter;
Object.defineProperty(ColorRangeReplaceFilter.prototype, 'minColor', {
get: function() {
return PIXI.rgb2hex(this.uniforms.minColor.value);
},
set: function(value) {
this.uniforms.minColor.value = PIXI.hex2rgb(value);
}
});
Object.defineProperty(ColorRangeReplaceFilter.prototype, 'maxColor', {
get: function() {
return PIXI.rgb2hex(this.uniforms.maxColor.value);
},
set: function(value) {
this.uniforms.maxColor.value = PIXI.hex2rgb(value);
}
});
Object.defineProperty(ColorRangeReplaceFilter.prototype, 'newColor', {
get: function() {
return PIXI.rgb2hex(this.uniforms.newColor.value);
},
set: function(value) {
this.uniforms.newColor.value = PIXI.hex2rgb(value);
}
});
Object.defineProperty(ColorRangeReplaceFilter.prototype, 'brightnessOffset', {
get: function() {
return this.uniforms.brightnessOffset.value;
},
set: function(value) {
this.uniforms.brightnessOffset.value = value;
}
});
return ColorRangeReplaceFilter;
});

View file

@ -1,179 +0,0 @@
define([
"Lib/Vendor/Box2D"
],
function (Box2D) {
"use strict";
var Parent = Box2D.Dynamics.b2DebugDraw;
function DebugDraw() {
Parent.call(this);
this.m_drawScale = 1;
}
DebugDraw.prototype = Object.create(Parent.prototype);
DebugDraw.prototype.setColor = function(color) {
this.m_ctx.debugColor = color.color;
this.m_ctx.debugFillAlpha = this.m_fillAlpha;
this.m_ctx.lineStyle(1, this.m_ctx.debugColor, this.m_alpha);
};
DebugDraw.prototype.SetSprite = function(sprite) {
this.m_ctx = sprite;
this.m_sprite = {
graphics: {
clear: function () {
sprite.clear();
sprite.lineStyle(1, 0xffffff, 0.8);
}
}
};
this.m_ctx.beginPath = function() {
this.beginFill(this.debugColor, this.debugFillAlpha);
};
this.m_ctx.closePath = function() {
this.endFill();
};
this.m_ctx.fill = function() {
this.endFill();
};
this.m_ctx.stroke = function() {
// do nothing
};
this.m_ctx.arc = function(x, y, radius, startingAngle, endingAngle, counterClockwise) {
this.drawCircle(x, y, radius);
}
};
DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
this.setColor(color);
Parent.prototype.DrawPolygon.call(this, arguments);
};
DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
this.setColor(color);
Parent.prototype.DrawSolidPolygon.apply(this, arguments);
};
DebugDraw.prototype.DrawCircle = function (center, radius, color) {
this.setColor(color);
Parent.prototype.DrawCircle.apply(this, arguments);
};
DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
this.setColor(color);
Parent.prototype.DrawSolidCircle.apply(this, arguments);
};
DebugDraw.prototype.DrawSegment = function (p1, p2, color) {
this.setColor(color);
Parent.prototype.DrawSegment.apply(this, arguments);
};
DebugDraw.prototype.DrawTransform = function (xf) {
this.setColor(0xff0000);
Parent.prototype.DrawTransform.apply(this, arguments);
};
/*
DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
if (!vertexCount) return;
var s = this.m_ctx;
var drawScale = this.m_drawScale;
s.beginPath();
s.strokeStyle = this._color(color.color, this.m_alpha);
s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
for (var i = 1; i < vertexCount; i++) {
s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
}
s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
s.closePath();
s.stroke();
};
DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
if (!vertexCount) return;
var s = this.m_ctx;
var drawScale = this.m_drawScale;
s.beginPath();
s.strokeStyle = this._color(color.color, this.m_alpha);
s.fillStyle = this._color(color.color, this.m_fillAlpha);
s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
for (var i = 1; i < vertexCount; i++) {
s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
}
s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
s.closePath();
s.fill();
s.stroke();
};
DebugDraw.prototype.DrawCircle = function (center, radius, color) {
if (!radius) return;
var s = this.m_ctx;
var drawScale = this.m_drawScale;
s.beginPath();
s.strokeStyle = this._color(color.color, this.m_alpha);
s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI * 2, true);
s.closePath();
s.stroke();
};
DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
if (!radius) return;
var s = this.m_ctx,
drawScale = this.m_drawScale,
cx = center.x * drawScale,
cy = center.y * drawScale;
s.moveTo(0, 0);
s.beginPath();
s.strokeStyle = this._color(color.color, this.m_alpha);
s.fillStyle = this._color(color.color, this.m_fillAlpha);
s.arc(cx, cy, radius * drawScale, 0, Math.PI * 2, true);
s.moveTo(cx, cy);
s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale);
s.closePath();
s.fill();
s.stroke();
};
DebugDraw.prototype.DrawSegment = function (p1, p2, color) {
var s = this.m_ctx,
drawScale = this.m_drawScale;
s.strokeStyle = this._color(color.color, this.m_alpha);
s.beginPath();
s.moveTo(p1.x * drawScale, p1.y * drawScale);
s.lineTo(p2.x * drawScale, p2.y * drawScale);
s.closePath();
s.stroke();
};
DebugDraw.prototype.DrawTransform = function (xf) {
var s = this.m_ctx,
drawScale = this.m_drawScale;
s.beginPath();
s.strokeStyle = this._color(0xff0000, this.m_alpha);
s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale);
s.strokeStyle = this._color(0xff00, this.m_alpha);
s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale);
s.closePath();
s.stroke();
};
*/
return DebugDraw;
});

View file

@ -1,206 +0,0 @@
define([
"Lib/Vendor/Pixi",
"Lib/Utilities/NotificationCenter",
"Game/Config/Settings",
"Lib/Utilities/ColorConverter"
],
function (PIXI, nc, Settings, ColorConverter) {
"use strict";
function GameStats(view) {
this.style = {
borderWidth: 3,
padding: 20,
colors: {
background: 0x000000,
text: "red",
headline: "#880000",
border: 0xAA0000
},
line: {
height: 16,
spacing: 5
},
fontSize: 12
};
this.view = view;
this.container = new PIXI.DisplayObjectContainer();
var blurFilter = new PIXI.BlurFilter();
blurFilter.blurX = 12;
blurFilter.blurY = 12;
var grayFilter = new PIXI.GrayFilter();
grayFilter.gray = 0.85;
this.filters = [blurFilter, grayFilter];
this.background = new PIXI.Graphics();
this.background.alpha = 0.7;
this.container.addChild(this.background);
this.dialog = new PIXI.DisplayObjectContainer();
this.container.addChild(this.dialog);
this.graphics = new PIXI.Graphics();
/*
gameContainer
filters
container
background
dialog
graphics
playerColor
headline
line
*/
this.container.visible = false;
this.sortedPlayers = [];
this.ncTokens = [
nc.on(nc.ns.client.view.gameStats.toggle, this.toggle, this),
nc.on(nc.ns.client.view.gameStats.update, this.update, this)
];
}
GameStats.prototype.getInfoContainer = function() {
return this.container;
};
GameStats.prototype.toggle = function(show) {
if(show) {
this.redraw();
// show stats with filters
this.container.visible = true;
this.view.addFilters(this.filters);
this.filters.forEach(function(filter) { filter.dirty = true; });
} else {
this.container.visible = false;
this.view.removeFilters(this.filters);
}
}
GameStats.prototype.update = function(sortedPlayers) {
this.sortedPlayers = sortedPlayers;
this.redraw();
};
GameStats.prototype.redraw = function() {
this.background.clear();
this.graphics.clear();
this.dialog.removeChildren();
// redraw background
this.background.beginFill(this.style.colors.background);
this.background.drawRect(0, 0, Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT);
this.background.endFill();
// redraw text and graphics
var string = "" +
" #".pad(7, true) + " " +
"Name".pad(12, true) +
"Score".pad(6, false) +
"Deaths".pad(7, false) +
"Health".pad(9, false) + " ";
var line = new PIXI.Text(string, {
font: "normal " + this.style.fontSize + "px 'Joystix'",
fill: this.style.colors.headline
});
line.position = new PIXI.Point(0, 0);
this.dialog.addChild(line);
this.drawPlayers(this.sortedPlayers);
var x = Settings.STAGE_WIDTH / 2 - this.dialog.getBounds().width / 2,
y = Settings.STAGE_HEIGHT / 2 - (this.sortedPlayers.length + 1) * (this.style.line.height + this.style.line.spacing) / 2;
this.dialog.position = new PIXI.Point(x, y);
this.dialog.addChild(this.graphics);
};
GameStats.prototype.drawPlayers = function(sortedPlayers) {
sortedPlayers.forEach(function(player, i) {
this.drawPlayer(player, i + 1);
this.drawPlayerGraphics(player, i + 1)
}, this);
};
GameStats.prototype.drawPlayer = function(player, i) {
var string = (i + ". ").pad(7, false) + " " +
player.getNickname().pad(12, true) +
("" + player.stats.score).pad(6, false) +
("" + player.stats.deaths).pad(7, false) +
("" /* + parseInt(player.stats.health, 10)*/).pad(9, false) + " ";
var line = new PIXI.Text(string, {
font: "normal " + this.style.fontSize + "px 'Joystix'",
fill: this.style.colors.text
});
line.position = new PIXI.Point(
0,
i * (this.style.line.height + this.style.line.spacing)
);
this.dialog.addChild(line);
};
GameStats.prototype.drawPlayerGraphics = function(player, i) {
var converter = new ColorConverter();
// draw shirt color
this.graphics.beginFill(converter.getColorByName(player.getNickname()));
this.graphics.drawRect(
50,
i * (this.style.line.height + this.style.line.spacing),
this.style.line.height,
this.style.line.height
);
// draw health bar
var height = this.style.line.height / 2,
width = height * 7,
borderWidth = 2,
offsetX = 360,
offsetY = (i * (this.style.line.height + this.style.line.spacing)) + ((this.style.line.height - height) / 2);
this.graphics.beginFill(0x000000);
this.graphics.drawRect(offsetX, offsetY, width, height);
this.graphics.endFill();
if(player.stats.health > 0) {
var color = player.stats.health / 100 < Settings.CRITICAL_HEALTH_THRESHOLD
? 0xFF0000
: 0x00FF00;
this.graphics.beginFill(color);
this.graphics.drawRect(
offsetX + borderWidth,
offsetY + borderWidth,
width * player.stats.health / 100 - 2 * borderWidth,
height - 2 * borderWidth
);
this.graphics.endFill();
}
};
GameStats.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
nc.off(this.ncTokens[i]);
};
};
return GameStats;
});

View file

@ -1,322 +0,0 @@
define([
"Game/Client/View/Abstract/Layer",
"Lib/Vendor/Pixi",
"Game/Client/View/Pixi/ColorRangeReplaceFilter",
"Game/Config/Settings",
"Lib/Utilities/ColorConverter",
"Lib/Utilities/NotificationCenter"
],
function (Parent, PIXI, ColorRangeReplaceFilter, Settings, ColorConverter, nc) {
"use strict";
function Layer (name, options) {
Parent.call(this, name, options);
this.container = new PIXI.DisplayObjectContainer();
this.container.x = 0;
this.container.y = 0;
this.static = false;
this.levelSize = {
width: 0,
height: 0
}
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.view.layer.levelSizeUpdate, this.onLevelSizeUpdate, this)
]);
if (Settings.SHOW_LAYER_INFO) {
var self = this;
var g = new PIXI.Graphics();
var converter = new ColorConverter();
var c = converter.getColorByName(name);
var fontSize = 12;
var textOptions = {
font: "normal " + fontSize + "px 'Joystix'",
fill: "#" + c.toString(16),
};
var t = new PIXI.Text(name, textOptions);
var y = 0;
switch (name) {
case "ghost": y++;
case "item": y++;
case "tile": y++;
case "spawn": y=y;
}
t.position = new PIXI.Point(0, fontSize * y);
g.lineStyle (1, c, 1);
g.drawRect (0, 0, 100 + y, 100 + y);
setTimeout(function(){
self.container.addChild(t);
self.container.addChild(g);
}, 500);
}
}
Layer.prototype = Object.create(Parent.prototype);
Layer.prototype.onLevelSizeUpdate = function(levelSize) {
this.levelSize = levelSize;
};
Layer.prototype.getAvailableMeshFilters = function() {
return {
"blur": PIXI.BlurFilter,
"desaturate": PIXI.GrayFilter,
"pixelate": PIXI.PixelateFilter,
"colorRangeReplace": ColorRangeReplaceFilter,
};
};
Layer.prototype.getContainer = function() {
return this.container;
};
Layer.prototype.show = function() {
this.container.visible = true;
};
Layer.prototype.hide = function() {
this.container.visible = false;
};
Layer.prototype.addMesh = function(mesh) {
this.container.addChild(mesh);
};
Layer.prototype.removeMesh = function(mesh) {
this.container.removeChild(mesh);
};
Layer.prototype.swapMeshIndexes = function(meshA, meshB) {
var indexA = this.container.getChildIndex(meshA);
var indexB = this.container.getChildIndex(meshB);
this.container.setChildIndex(meshA, indexB);
this.container.setChildIndex(meshB, indexA);
};
Layer.prototype.swapMeshes = function(meshA, meshB) {
var textureA = meshA.texture;
var textureB = meshB.texture;
meshA.setTexture(textureB);
meshA.onTextureUpdate();
meshA.scale.x = 1;
meshA.scale.y = 1;
meshB.setTexture(textureA);
meshB.onTextureUpdate();
meshB.scale.x = 1;
meshB.scale.y = 1;
};
Layer.prototype.createMesh = function (texturePath, callback, options) {
var texture = (options && options.fromFrame)
? PIXI.Texture.fromFrame(texturePath)
: PIXI.Texture.fromImage(texturePath);
var mesh = new PIXI.Sprite(texture);
if(options) this.updateMesh(mesh, options);
callback(mesh);
};
Layer.prototype.createAnimatedMesh = function (texturePaths, callback, options) {
var textures = [];
for (var i = 0; i < texturePaths.length; i++) {
var texture = (options && options.fromFrame)
? PIXI.Texture.fromFrame(texturePaths[i])
: PIXI.Texture.fromImage(texturePaths[i]);
texture.width = options.width;
texture.height = options.height;
//PIXI.texturesToUpdate.push(texture);
textures.push(texture);
}
var mesh = new PIXI.MovieClip(textures);
if(options) this.updateMesh(mesh, options);
mesh.animationSpeed = 0.5;
mesh.play();
callback(mesh);
}
Layer.prototype.updateMesh = function(mesh, options) {
if (options.x) mesh.position.x = options.x;
if (options.y) mesh.position.y = options.y;
if (options.rotation) mesh.rotation = options.rotation;
if (options.alpha) mesh.alpha = options.alpha;
if (options.width) mesh.width = options.width;
if (options.height) mesh.height = options.height;
if (options.xScale) mesh.width = Math.abs(mesh.width) * options.xScale;
if (options.yScale) mesh.scale.y = options.yScale;
if (options.visible === true || options.visible === false) mesh.visible = options.visible;
if (options.pivot) mesh.pivot = new PIXI.Point(options.pivot.x, options.pivot.y);
if (options.anchor) mesh.anchor = options.anchor;
if (options.animationSpeed) mesh.animationSpeed = options.animationSpeed;
};
Layer.prototype.addFilter = function(mesh, filterName, options) {
// use game container if mesh null
if(mesh === null) {
}
if (!this.getAvailableMeshFilters().hasOwnProperty(filterName)) {
throw new Exception('Filter ' + filterName + ' is not available');
}
var MeshFilter = this.getAvailableMeshFilters()[filterName];
var filter = new MeshFilter();
switch (filterName) {
case 'desaturate':
if (options.amount) filter.gray = options.amount;
break;
case 'blur':
if (options.blurX) filter.blurX = options.blurX;
if (options.blurY) filter.blurY = options.blurY;
break;
case 'colorRangeReplace':
if (options.minColor) filter.minColor = options.minColor;
if (options.maxColor) filter.maxColor = options.maxColor;
if (options.newColor) filter.newColor = options.newColor;
if (options.brightnessOffset) filter.brightnessOffset = options.brightnessOffset;
break;
case 'pixelate':
if (options.sizeX) filter.size.x = options.sizeX;
if (options.sizeY) filter.size.y = options.sizeY;
break;
default:
break;
}
var filters = mesh.filters;
if(!filters) {
filters = [];
} else {
// ensure uniqueness of filter by name
this.removeFilter(mesh, filterName);
}
filters.push(filter);
mesh.filters = filters;
};
Layer.prototype.removeFilter = function(mesh, filterName) {
var filters = mesh.filters;
if(!filters) {
return;
}
// FIXME this should throw an error i think since "options" is not defined here
// maybe we never actually call this method?
var MeshFilter = this.getAvailableMeshFilters()[options.filter];
filters = filters.filter(function(filter){
return !filter instanceof MeshFilter;
});
mesh.filters = filter;
};
Layer.prototype.render = function(centerPosition, zoom) {
this.setPosition(centerPosition);
this.setZoom(zoom);
// Zoom
var zoomStep = (this.zoom.target - this.zoom.current) * Settings.CAMERA_GLIDE / 100;
this.zoom.current += zoomStep;
this.container.scale.x = this.zoom.current;
this.container.scale.y = this.container.scale.x;
/*
// we would need another zoom state,
// to separate fixed zooming (by window size)
// and user zoom by +/-/0 keys
// this snippet would zoom the layers by its parallax
// so further away layers would not zoom as much.
var zoomParallax = this.parallaxSpeed == 0
? 1
: this.parallaxSpeed < 0
? (1 + this.parallaxSpeed)
: this.parallaxSpeed + 1000;
var newZoomTarget = 1 + Math.log(this.zoom.target+2) * (zoomParallax)
console.log(newZoomTarget)
this.container.scale.x = newZoomTarget;
this.container.scale.y = newZoomTarget;
// Later, this would need to be added as well:
this.container.x *= newZoomTarget;
this.container.y *= newZoomTarget;
*/
// Position
if (!this.static) {
var posXStep = (this.position.target.x - this.position.current.x) * Settings.CAMERA_GLIDE / 100;
this.position.current.x += posXStep;
var posYStep = (this.position.target.y - this.position.current.y) * Settings.CAMERA_GLIDE / 100;
this.position.current.y += posYStep;
// Add here to set 0,0 not in the center of the map but the level origin in the top left
// FIXME: use a different kind of flag than "name"
if (this.name == "spawn"
|| this.name == "tile"
|| this.name == "item"
|| this.name == "ghost"
|| this.name == "swiper"
|| this.parallaxSpeed == 0) {
this.container.x = this.position.current.x;
this.container.y = this.position.current.y;
} else {
var x = this.position.current.x + this.levelSize.width / 2;
this.container.x = x - x * -this.parallaxSpeed;
var y = this.position.current.y + this.levelSize.height / 2;
this.container.y = y - y * -this.parallaxSpeed;
}
this.container.x *= this.zoom.current;
this.container.y *= this.zoom.current;
this.container.x += Settings.STAGE_WIDTH / 2;
this.container.y += Settings.STAGE_HEIGHT / 2;
}
};
return Layer;
});

View file

@ -1,20 +0,0 @@
define([
"Game/Client/View/Pixi/Layer",
"Lib/Vendor/Pixi",
],
function (Parent, PIXI) {
"use strict";
function Debug() {
Parent.call(this, "debug", 0.00000001);
this.graphics = new PIXI.Graphics();
this.container.addChild(this.graphics);
}
Debug.prototype = Object.create(Parent.prototype);
return new Debug();
});

View file

@ -1,119 +0,0 @@
define([
"Game/Client/View/Pixi/Layer",
"Lib/Vendor/Pixi",
"Lib/Utilities/NotificationCenter",
"Game/Config/Settings"
],
function (Parent, PIXI, nc, Settings) {
"use strict";
function Ghost() {
Parent.call(this, "ghost", {parallaxSpeed: 0});
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.view.layer.levelSizeUpdate, this.onLevelSizeUpdate, this),
nc.on(nc.ns.client.view.playerArrow.createAndAdd, this.onCreateAndAddPlayerArrow, this),
nc.on(nc.ns.client.view.playerArrow.update, this.onUpdatePlayerArrow, this),
nc.on(nc.ns.client.view.healthBar.createAndAdd, this.onCreateAndAddHealthBar, this),
nc.on(nc.ns.client.view.healthBar.update, this.onUpdateHealthBar, this),
nc.on(nc.ns.client.view.healthBar.remove, this.onRemoveHealthBar, this),
]);
}
Ghost.prototype = Object.create(Parent.prototype);
Ghost.prototype.onLevelSizeUpdate = function(levelSize) {
this.position.current.x = -levelSize.width / 2;
this.position.current.y = -levelSize.height / 2;
};
Ghost.prototype.onCreateAndAddPlayerArrow = function(callback, options) {
var arrow = new PIXI.Graphics();
arrow.visible = false;
this.container.addChild(arrow);
var width = 10,
height = 10;
arrow.beginFill(0xffffff, 0.4);
arrow.lineStyle(0, 0x000000);
arrow.moveTo(0, 0);
arrow.lineTo(width, 0);
arrow.lineTo(width / 2, height);
arrow.endFill();
arrow.pivot = new PIXI.Point(width/2, height/2);
arrow.visible = true;
this.onUpdatePlayerArrow(arrow, options);
callback(arrow);
};
Ghost.prototype.onUpdatePlayerArrow = function(arrow, options) {
var offsetX = 0,
offsetY = -55,
x = offsetX + options.x,
y = offsetY + options.y;
var target = new PIXI.Point(x, y);
arrow.position.x += (target.x -arrow.position.x) * Settings.ARROW_GLIDE / 1.5 / 100;
arrow.position.y += (target.y -arrow.position.y) * Settings.ARROW_GLIDE / 100;
var angle = -Math.atan2(arrow.position.x - x, arrow.position.y - options.y);
angle += 0.785398163 * 4;
arrow.rotation = angle;
};
// Player Info
Ghost.prototype.onCreateAndAddHealthBar = function(callback, options) {
var healthBar = new PIXI.Graphics();
this.container.addChild(healthBar);
this.onUpdateHealthBar(healthBar, options);
callback(healthBar);
};
Ghost.prototype.onUpdateHealthBar = function(healthBar, options) {
var width = 14,
height = 2,
borderWidth = 1,
offsetX = -8,
offsetY = -52;
if(typeof options.healthFactor != 'undefined') {
healthBar.clear();
healthBar.beginFill(0x000000);
healthBar.lineStyle(borderWidth, 0x000000);
healthBar.drawRect(0, 0, width, height);
healthBar.endFill();
if(options.healthFactor > 0) {
var color = 0x00FF00;
if(options.healthFactor < Settings.CRITICAL_HEALTH_THRESHOLD) color = 0xFF0000;
healthBar.beginFill(color);
healthBar.lineStyle(0, 0x000000);
healthBar.drawRect(borderWidth, borderWidth, width * options.healthFactor, height);
healthBar.endFill();
}
}
if (options.x && options.y) healthBar.position = new PIXI.Point(offsetX + options.x, offsetY + options.y);
if (options.visible === true || options.visible === false) healthBar.visible = options.visible;
};
Ghost.prototype.onRemoveHealthBar = function(healthBar) {
this.container.removeChild(healthBar);
};
return Ghost;
});

View file

@ -1,63 +0,0 @@
define([
"Game/Client/View/Pixi/Layer",
"Lib/Vendor/Pixi",
"Lib/Utilities/NotificationCenter",
"Game/Config/Settings"
],
function (Parent, PIXI, nc, Settings) {
"use strict";
function Messages() {
Parent.call(this, "messages", {parallaxSpeed:-1});
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.view.gameStats.kill, this.onKill, this)
]);
this.mainTextOptions = {
font: "normal 22px 'Joystix'",
fill: "#cc0000",
stroke: "rgba(0,0,0,0.8)",
strokeThickness: 6
};
this.mainText = new PIXI.Text("", this.mainTextOptions);
this.container.addChild(this.mainText);
this.mainText.visible = false;
}
Messages.prototype = Object.create(Parent.prototype);
Messages.prototype.onKill = function(options) {
var killer = options.killer.isMe ? "You" : options.killer.name;
var victim = options.victim.isMe
? options.killer.isMe
? "Yourself"
: "You"
: options.victim.name;
var text = killer + " killed " + victim + " with " + options.item;
this.mainText.setText(text);
this.mainText.setStyle(this.mainTextOptions);
this.mainText.position = new PIXI.Point(-this.mainText.width / 2, (Settings.STAGE_HEIGHT / 4) -this.mainText.height / 2);
this.mainText.visible = true;
var self = this;
setTimeout(function(){
self.mainText.visible = false;
}, Settings.SCORE_MESSAGE_TIMEOUT);
}
Messages.prototype.render = function(centerPosition, zoom) {
Parent.prototype.render.call(this, centerPosition, 1);
}
return Messages;
});

View file

@ -1,57 +0,0 @@
define([
"Game/Client/View/Pixi/Layer",
"Lib/Vendor/Pixi",
"Lib/Utilities/NotificationCenter",
"Game/Config/Settings"
],
function (Parent, PIXI, nc, Settings) {
function Swiper() {
Parent.call(this, "swiper", {parallaxSpeed:0});
this.static = true;
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.view.swiper.swipe, this.swipe, this),
nc.on(nc.ns.client.view.swiper.end, this.end, this)
]);
this.sprite = new PIXI.Graphics();
this.container.addChild(this.sprite);
this.end();
}
Swiper.prototype = Object.create(Parent.prototype);
Swiper.prototype.swipe = function(x, y) {
var offset = {
x: Settings.STAGE_WIDTH / 2 / this.zoom.current,
y: Settings.STAGE_HEIGHT / 2 / this.zoom.current,
}
this.sprite.moveTo(offset.x + this.last.x, offset.y + this.last.y);
this.last.x = x;
this.last.y = -y;
this.sprite.lineTo(offset.x + this.last.x, offset.y + this.last.y);
};
Swiper.prototype.end = function(x, y) {
this.sprite.clear();
this.sprite.lineStyle(2, 0xffffff);
this.sprite.alpha = 0.5;
this.last = {
x: 0,
y: 0
}
};
return Swiper;
});

View file

@ -1,317 +0,0 @@
define([
"Game/Client/View/Abstract/View",
"Game/Client/View/DomController",
"Lib/Vendor/Pixi",
"Game/Config/Settings",
"Lib/Utilities/NotificationCenter",
"Lib/Utilities/Exception",
"Game/Client/View/Pixi/GameStats",
"Game/Client/View/LayerManager",
"Game/Client/View/Pixi/Layers/Ghost",
"Game/Client/View/Pixi/Layers/Swiper",
"Game/Client/PointerLockManager",
"Game/Client/View/Pixi/Layers/Debug",
"Game/Client/View/Pixi/Layers/Messages"
],
function (Parent, domController, PIXI, Settings, nc, Exception, GameStats, LayerManager, Ghost, Swiper, pointerLockManager, Debug, Messages) {
"use strict";
function PixiView () {
Parent.call(this);
this.xyz = Math.random()
this.layerManager = null;
this.stage = null;
this.container = null;
this.infoContainer = null;
this.loader = null;
this.currentZoom = Settings.ZOOM_DEFAULT;
this.clickToEnable = null;
this.init();
this.ncTokens = this.ncTokens.concat([
nc.on(nc.ns.client.pointerLock.change, this.onPointerLockChange, this),
nc.on(nc.ns.core.game.events.level.loaded, this.showDefaultLayers, this)
]);
PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;
}
PixiView.prototype = Object.create(Parent.prototype);
PixiView.prototype.init = function () {
var rendererOptions = {
view: domController.getCanvas(),
antialiasing: false,
transparent: false,
resolution: 1
}
if(Settings.USE_WEBGL) {
PIXI.WebGLRenderer.glContextId = 0;
this.renderer = new PIXI.WebGLRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, rendererOptions);
console.log('WebGLRenderer');
} else {
this.renderer = new PIXI.CanvasRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, rendererOptions);
console.warn('CanvasRenderer - not using WebGL!');
}
this.onDisplaySizeChange(false);
this.stage = new PIXI.Stage(0x333333);
this.container = new PIXI.DisplayObjectContainer();
this.stage.addChild(this.container);
this.layerManager = new LayerManager(this.container, this.me);
this.initLoader();
this.initCanvas(this.renderer.view);
this.initPointerLockView();
// Tab Overlay (not using layer manager, cause of filters)
this.gameStats = new GameStats(this);
this.stage.addChild(this.gameStats.getInfoContainer());
this.ghostLayer = new Ghost();
this.ghostLayer.hide();
this.layerManager.insert(this.ghostLayer, false);
this.swiperLayer = new Swiper();
this.swiperLayer.hide()
this.layerManager.insert(this.swiperLayer, false);
this.debugLayer = Debug;
this.debugLayer.hide();
this.layerManager.insert(this.debugLayer, false);
this.messagesLayer = new Messages();
this.messagesLayer.hide();
this.layerManager.insert(this.messagesLayer, false);
this.render();
}
PixiView.prototype.showDefaultLayers = function() {
this.ghostLayer.show();
this.swiperLayer.show()
this.debugLayer.show();
this.messagesLayer.show();
};
PixiView.prototype.render = function () {
if (this.me) {
this.layerManager.render(this.calculateCenterPosition(), this.currentZoom);
}
this.renderer.render(this.stage);
}
PixiView.prototype.initPointerLockView = function() {
if (!Settings.ENABLE_POINTER_LOCK_FILTER) return;
var blurFilter = new PIXI.BlurFilter();
blurFilter.blurX = 42 * this.currentZoom;
blurFilter.blurY = 42 * this.currentZoom;
var pixelFilter = new PIXI.PixelateFilter();
pixelFilter.pixelSize = 10 * this.currentZoom ;
var grayFilter = new PIXI.GrayFilter();
grayFilter.gray = 0.99;
this.pointerLockFilters = [pixelFilter, grayFilter];
this.clickToEnable = new PIXI.Text("Click to start playing.");
this.clickToEnable.visible = false;
this.stage.addChild(this.clickToEnable)
};
PixiView.prototype.onPointerLockChange = function(isLocked, options) {
if (!Settings.ENABLE_POINTER_LOCK_FILTER) return;
if(isLocked) {
this.removeFilters(this.pointerLockFilters);
this.clickToEnable.visible = false;
this.onZoomReset();
} else {
if(!options || options.start !== true) {
this.clickToEnable.setText("Click to continue playing.");
}
this.clickToEnable.setStyle({
font: "normal " + (14 * this.currentZoom) + "px 'Joystix'",
fill: "#ffffff",
stroke: "rgba(0,0,0,0.8)",
strokeThickness: 6 * this.currentZoom
});
this.addFilters(this.pointerLockFilters);
this.pointerLockFilters.forEach(function(filter) { filter.dirty = true; });
this.clickToEnable.position = new PIXI.Point(Settings.STAGE_WIDTH / 2 - this.clickToEnable.width / 2, Settings.STAGE_HEIGHT / 2 - this.clickToEnable.height / 2)
this.clickToEnable.visible = true;
this.onZoomReset();
this.currentZoom *= 0.9;
}
};
PixiView.prototype.removeFilters = function(filters) {
if(this.container && this.container.filters && this.container.filters.length) {
for (var i = this.container.filters.length - 1; i >= 0; i--) {
for (var j = filters.length - 1; j >= 0; j--) {
if (filters[j] === this.container.filters[i]) {
this.container.filters.splice(i, 1);
}
}
}
// weird bug, filters.length cant be 0, must be set to null
if(this.container.filters.length < 1) {
this.container.filters = null;
}
}
};
PixiView.prototype.addFilters = function(filters) {
if (filters.length < 1) return;
if (!this.container) {
return;
}
if (!this.container.filters) {
/*
* slice does a copy, which is important here -
* otherwise this.pointerLockFilters will be manipulated too on remove.
*/
this.container.filters = filters.slice();
return;
}
for (var i = 0; i < filters.length; i++) {
this.container.filters.push(filters[i]);
}
};
PixiView.prototype.calculateCenterPosition = function() {
var target = this.me.getHeadPosition();
var centerPosition = {x: target.x, y: target.y};
centerPosition.x *= Settings.RATIO * -1;
centerPosition.y *= Settings.RATIO * -1;
var lookAt = this.me.getLookAt();
centerPosition.x -= lookAt.x * 600 / 4;
centerPosition.y += lookAt.y * 400 / 4;
return centerPosition;
};
PixiView.prototype.onDisplaySizeChange = function(isFullScreen) {
Parent.prototype.onDisplaySizeChange.call(this, isFullScreen);
this.renderer.resize(window.innerWidth, window.innerHeight);
this.currentZoom = window.innerWidth / 600;
pointerLockManager.update(null, {}); // only to reposition clickToEnable text
};
PixiView.prototype.initLoader = function() {
this.loader = new PIXI.Graphics();
this.stage.addChild(this.loader);
this.onUpdateLoader(0);
};
PixiView.prototype.onUpdateLoader = function(progress) {
var width = 200,
height = 5,
borderWidth = 1;
if(progress < 100) {
this.loader.clear();
this.loader.beginFill(0x000000);
this.loader.lineStyle(borderWidth, 0x000000);
this.loader.drawRect(0, 0, width, height);
this.loader.endFill();
if(progress > 0) {
var color = 0xFF0FA3;
this.loader.beginFill(color);
this.loader.lineStyle(0, 0x000000);
this.loader.drawRect(borderWidth, borderWidth, width * progress / 100, height);
this.loader.endFill();
}
this.loader.position = new PIXI.Point(
Settings.STAGE_WIDTH / 2 - width / 2 - borderWidth,
Settings.STAGE_HEIGHT / 2 - height / 2 - borderWidth
);
}
this.loader.visible = progress < 100;
};
PixiView.prototype.onZoomIn = function() {
if(this.currentZoom + Settings.ZOOM_FACTOR <= Settings.ZOOM_MAX) {
this.currentZoom += Settings.ZOOM_FACTOR;
}
};
PixiView.prototype.onZoomOut = function() {
//if(this.currentZoom - Settings.ZOOM_FACTOR > window.innerWidth / 600) {
this.currentZoom -= Settings.ZOOM_FACTOR;
//}
};
PixiView.prototype.onZoomReset = function() {
this.currentZoom = window.innerWidth / 600;
};
PixiView.prototype.getTexturesFromFrame = function(textureNames) {
var textures = [];
for (var i = 0; i < textureNames.length; i++) {
textures.push(PIXI.Texture.fromFrame(textureNames[i]));
};
return textures;
};
PixiView.prototype.destroy = function() {
this.layerManager.destroy(); // also calls all layers destroy
for (var i = 0; i < this.stage.children.length; i++) {
this.stage.removeChild(this.stage.children[i]);
}
this.renderer.render(this.stage);
this.renderer.destroy();
delete this.renderer;
Parent.prototype.destroy.call(this);
};
return PixiView;
});

View file

@ -1,24 +1,22 @@
define([ define([
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/Exception", "Lib/Utilities/Exception",
"Game/Client/View/Abstract/View", "Game/Client/View/Views/AbstractView",
//"Game/Client/View/Three/View", //"Game/Client/View/Views/ThreeView",
"Game/Client/View/Pixi/View", "Game/Client/View/Views/PixiView",
"Lib/Utilities/NotificationCenter" "Lib/Utilities/NotificationCenter"
], ],
function (Settings, Exception, AbstractView, PixiView, nc) { function (Settings, Exception, AbstractView, PixiView, Nc) {
"use strict";
var ViewManager = {}; var ViewManager = {};
ViewManager.createView = function() { ViewManager.createView = function() {
var view = null var view = null
switch(Settings.VIEW_CONTROLLER) { switch(Settings.VIEW_CONTROLLER) {
//case 'Three': case 'Three':
// view = new ThreeView(); view = new ThreeView();
// break; break;
case 'Pixi': case 'Pixi':
view = new PixiView(); view = new PixiView();
break; break;
@ -38,6 +36,8 @@ function (Settings, Exception, AbstractView, PixiView, nc) {
throw new Exception("In the view", Settings.VIEW_CONTROLLER + 'View', "this.setCanvas(canvas) has not been called with a valid HTMLCanvasElement!"); throw new Exception("In the view", Settings.VIEW_CONTROLLER + 'View', "this.setCanvas(canvas) has not been called with a valid HTMLCanvasElement!");
} }
Nc.trigger(Nc.ns.client.view.events.ready, view);
return view; return view;
} }

View file

@ -0,0 +1,165 @@
define([
"Game/Client/View/DomController",
"Game/Config/Settings",
"Lib/Utilities/Exception",
"Lib/Utilities/NotificationCenter"
],
function (DomController, Settings, Exception, Nc) {
function AbstractView () {
this.me = null;
this.canvas = null;
this.debugMode = false;
this.ncTokens = [
Nc.on(Nc.ns.client.view.mesh.create, this.createMesh, this),
Nc.on(Nc.ns.client.view.animatedMesh.create, this.createAnimatedMesh, this),
Nc.on(Nc.ns.client.view.mesh.add, this.addMesh, this),
Nc.on(Nc.ns.client.view.mesh.remove, this.removeMesh, this),
Nc.on(Nc.ns.client.view.mesh.update, this.updateMesh, this),
Nc.on(Nc.ns.client.view.fullscreen.change, this.onFullscreenChange, this),
Nc.on(Nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this),
Nc.on(Nc.ns.client.view.playerInfo.createAndAdd, this.onCreateAndAddPlayerInfo, this),
Nc.on(Nc.ns.client.view.playerInfo.update, this.onUpdatePlayerInfo, this),
Nc.on(Nc.ns.client.view.playerInfo.remove, this.onRemovePlayerInfo, this),
Nc.on(Nc.ns.client.view.preloadBar.update, this.onUpdateLoader, this),
];
}
AbstractView.prototype.isWebGlEnabled = function () {
try {
return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' );
} catch(e) {
return false;
}
}
AbstractView.prototype.initCanvas = function (canvas) {
this.canvas = canvas;
DomController.initCanvas(canvas);
}
AbstractView.prototype.loadPlayerMesh = function(player) {
throw new Exception('Abstract Function loadPlayerMesh not overwritten');
};
AbstractView.prototype.loadMeshes = function(objects) {
throw new Exception('Abstract Function loadMeshes not overwritten');
};
AbstractView.prototype.render = function () {
throw new Exception('Abstract Function render not overwritten');
}
AbstractView.prototype.createMesh = function (texturePath, callback, options) {
throw new Exception('Abstract Function createMesh not overwritten');
}
AbstractView.prototype.createAnimatedMesh = function (texturePaths, callback, options) {
throw new Exception('Abstract Function createAnimatedMesh not overwritten');
}
AbstractView.prototype.addMesh = function(mesh) {
throw new Exception('Abstract Function addMesh not overwritten');
};
AbstractView.prototype.removeMesh = function(mesh) {
throw new Exception('Abstract Function removeMesh not overwritten');
};
AbstractView.prototype.updateMesh = function(mesh, options) {
throw new Exception('Abstract Function updateMesh not overwritten');
};
AbstractView.prototype.setMe = function(player) {
this.me = player;
};
AbstractView.prototype.addPlayer = function(player) {
throw new Exception('Abstract Function addPlayer not overwritten');
};
AbstractView.prototype.removPlayer = function(player) {
throw new Exception('Abstract Function removPlayer not overwritten');
};
AbstractView.prototype.setCameraPosition = function (x, y) {
throw new Exception('Abstract Function setCameraPosition not overwritten');
}
AbstractView.prototype.calculateCameraPosition = function() {
var reference = this.me.getPosition();
var pos = {};
pos.x = reference.x;
pos.y = reference.y;
pos.x = pos.x * Settings.RATIO;
pos.y = -(pos.y * Settings.RATIO);
pos.x += this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4;
pos.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4;
return pos;
};
AbstractView.prototype.setCameraZoom = function (z) {
throw new Exception('Abstract Function setCameraZoom not overwritten');
};
AbstractView.prototype.onFullscreenChange = function(isFullScreen) {
if (!isFullScreen) {
Settings.STAGE_WIDTH = 600;
Settings.STAGE_HEIGHT = 400;
} else {
// FIXME: Create FIXME meme (dumb and dumber)
// FIXME: don't overwrite Settings
Settings.STAGE_WIDTH = window.innerWidth;
Settings.STAGE_HEIGHT = window.innerHeight;
}
};
AbstractView.prototype.onToggleDebugMode = function(debugMode) {
if(debugMode) {
this.setCameraPosition(-Settings.STAGE_WIDTH / 2, -Settings.STAGE_HEIGHT / 2);
}
this.debugMode = debugMode;
};
AbstractView.prototype.toggleInfo = function(show, string) {
throw new Exception('Abstract Function showInfo not overwritten');
};
AbstractView.prototype.onCreateAndAddPlayerInfo = function(options) {
throw new Exception('Abstract Function onCreateAndAddPlayerInfo not overwritten');
};
AbstractView.prototype.onUpdatePlayerInfo = function(playerInfo, options) {
throw new Exception('Abstract Function onUpdatePlayerInfo not overwritten');
};
AbstractView.prototype.onRemovePlayerInfo = function(playerInfo) {
throw new Exception('Abstract Function onRemovePlayerInfo not overwritten');
};
AbstractView.prototype.onUpdateLoader = function(progress) {
throw new Exception('Abstract Function onUpdateLoader not overwritten');
};
AbstractView.prototype.destroy = function() {
for (var i = 0; i < this.ncTokens.length; i++) {
Nc.off(this.ncTokens[i]);
};
};
return AbstractView;
});

View file

@ -0,0 +1,320 @@
define([
"Game/Client/View/Views/AbstractView",
"Game/Client/View/DomController",
"Lib/Vendor/Pixi",
"Game/Config/Settings",
"Lib/Utilities/NotificationCenter"
],
function (Parent, DomController, PIXI, Settings, Nc) {
function PixiView () {
Parent.call(this);
this.movableObjects = [];
this.stage = null;
this.container = null;
this.infoContainer = null;
this.infoFilters = [];
this.infoBox = null;
this.loader = null;
this.init();
this.pixi = PIXI;
PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;
}
PixiView.prototype = Object.create(Parent.prototype);
PixiView.prototype.init = function () {
var transparent = false;
var antialias = true;
var canvas = DomController.getCanvas();
if(Settings.USE_WEBGL) {
this.renderer = new PIXI.WebGLRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, canvas, transparent, antialias);
console.log('WebGLRenderer')
} else {
this.renderer = new PIXI.CanvasRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, canvas, transparent, antialias);
console.log('CanvasRenderer - not using WebGL!')
}
this.stage = new PIXI.Stage(0x333333);
this.initCamera();
this.initInfo();
this.initLoader();
this.initCanvas(this.renderer.view);
}
PixiView.prototype.render = function () {
if(this.me) {
var pos = this.calculateCameraPosition();
this.setCameraPosition(pos.x, pos.y);
}
this.renderer.render(this.stage);
}
// Meshes
PixiView.prototype.addMesh = function(mesh) {
this.container.addChild(mesh);
};
PixiView.prototype.removeMesh = function(mesh) {
this.container.removeChild(mesh);
};
PixiView.prototype.createMesh = function (texturePath, callback, options) {
var texture = PIXI.Texture.fromImage(texturePath);
var mesh = new PIXI.Sprite(texture);
if(options) this.updateMesh(mesh, options);
callback(mesh);
}
PixiView.prototype.createAnimatedMesh = function (texturePaths, callback, options) {
var textures = [];
for (var i = 0; i < texturePaths.length; i++) {
var texture = PIXI.Texture.fromImage(texturePaths[i]);
texture.width = options.width;
texture.height = options.height;
PIXI.texturesToUpdate.push(texture);
textures.push(texture);
}
var mesh = new PIXI.MovieClip(textures);
if(options) this.updateMesh(mesh, options);
mesh.animationSpeed = 0.5;
mesh.play();
callback(mesh);
}
PixiView.prototype.updateMesh = function(mesh, options) {
if (options.x) mesh.position.x = options.x;
if (options.y) mesh.position.y = options.y;
if (options.rotation) mesh.rotation = options.rotation;
if (options.width) mesh.width = options.width;
if (options.height) mesh.height = options.height;
if (options.xScale) mesh.width = Math.abs(mesh.width) * options.xScale;
if (options.yScale) mesh.scale.y = options.yScale;
if (options.visible === true || options.visible === false) mesh.visible = options.visible;
if (options.pivot) mesh.pivot = new PIXI.Point(options.pivot.x, options.pivot.y);
}
// Camera
PixiView.prototype.initCamera = function () {
this.container = new PIXI.DisplayObjectContainer();
this.stage.addChild(this.container);
}
PixiView.prototype.calculateCameraPosition = function() {
var zoom = this.container.scale.x;
var target = this.me.getHeadPosition();
target.x *= -Settings.RATIO * zoom;
target.y *= -Settings.RATIO * zoom;
target.x -= this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4;
target.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4;
var pos = this.getCameraPosition();
pos.x += (target.x -pos.x) * Settings.CAMERA_GLIDE / 100;
pos.y += (target.y -pos.y) * Settings.CAMERA_GLIDE / 100;
return pos;
};
PixiView.prototype.setCameraPosition = function (x, y) {
if(!this.debugMode) {
this.container.position.x = x + Settings.STAGE_WIDTH / 2;
this.container.position.y = y + Settings.STAGE_HEIGHT / 2;
}
};
PixiView.prototype.getCameraPosition = function () {
var pos = this.container.position;
pos.x = pos.x - Settings.STAGE_WIDTH / 2;
pos.y = pos.y - Settings.STAGE_HEIGHT / 2;
return pos;
};
PixiView.prototype.setCameraZoom = function (z) {
this.container.scale.x = z;
this.container.scale.y = z;
};
PixiView.prototype.onFullscreenChange = function(isFullScreen) {
Parent.prototype.onFullscreenChange.call(this, isFullScreen);
if(isFullScreen) {
this.renderer.resize(window.innerWidth, window.innerHeight);
this.setCameraZoom(window.innerWidth / 600);
} else {
this.renderer.resize(600, 400);
this.setCameraZoom(1);
}
};
// Info Overlay
PixiView.prototype.initInfo = function() {
this.infoContainer = new PIXI.DisplayObjectContainer();
this.stage.addChild(this.infoContainer);
var blurFilter = new PIXI.BlurFilter();
blurFilter.blurX = 12;
blurFilter.blurY = 12;
var grayFilter = new PIXI.GrayFilter();
grayFilter.gray = 0.85;
this.infoFilters = [blurFilter, grayFilter];
this.infoText = new PIXI.Text("", {font: "normal 20px monospace", fill: "red", align: "center"});
this.infoBox = new PIXI.Graphics();
this.infoBox.alpha = 0.7;
this.infoContainer.addChild(this.infoBox);
this.infoContainer.addChild(this.infoText);
this.infoContainer.visible = false;
};
PixiView.prototype.toggleInfo = function(show, string) {
if(show) {
this.infoText.setText(string);
this.infoText.updateText();
this.infoText.dirty = false;
var x = Settings.STAGE_WIDTH / 2 - this.infoText.width / 2,
y = Settings.STAGE_HEIGHT / 2 - this.infoText.height / 2;
this.infoText.position = new PIXI.Point(x, y);
var borderWidth = 3;
var padding = 20;
this.infoBox.clear();
this.infoBox.beginFill(0x000000);
this.infoBox.lineStyle(borderWidth, 0xAA0000);
this.infoBox.drawRect(0, 0, this.infoText.width - borderWidth + 2 * padding * 2, this.infoText.height - borderWidth + 2 * padding);
this.infoBox.endFill();
this.infoBox.position.x = this.infoText.position.x + borderWidth/2 - padding * 2;
this.infoBox.position.y = this.infoText.position.y + borderWidth/2 - padding;
this.infoContainer.visible = true;
this.container.filters = this.infoFilters;
this.infoFilters.forEach(function(filter) { filter.dirty = true; });
} else {
this.infoText.setText("...");
this.infoContainer.visible = false;
this.container.filters = null;
}
};
// Player Info
PixiView.prototype.onCreateAndAddPlayerInfo = function(callback, options) {
var playerInfo = new PIXI.Graphics();
this.container.addChild(playerInfo);
this.onUpdatePlayerInfo(playerInfo, options);
callback(playerInfo);
};
PixiView.prototype.onUpdatePlayerInfo = function(playerInfo, options) {
var width = 14,
height = 2,
borderWidth = 1,
offsetX = -8,
offsetY = -52;
if(typeof options.healthFactor != 'undefined') {
playerInfo.clear();
playerInfo.beginFill(0x000000);
playerInfo.lineStyle(borderWidth, 0x000000);
playerInfo.drawRect(0, 0, width, height);
playerInfo.endFill();
if(options.healthFactor > 0) {
var color = 0x00FF00;
if(options.healthFactor < 0.30) color = 0xFF0000;
playerInfo.beginFill(color);
playerInfo.lineStyle(0, 0x000000);
playerInfo.drawRect(borderWidth, borderWidth, width * options.healthFactor, height);
playerInfo.endFill();
}
}
if (options.x && options.y) playerInfo.position = new PIXI.Point(offsetX + options.x, offsetY + options.y);
if (options.visible === true || options.visible === false) playerInfo.visible = options.visible;
};
PixiView.prototype.onRemovePlayerInfo = function(playerInfo) {
this.container.removeChild(playerInfo);
};
PixiView.prototype.initLoader = function() {
this.loader = new PIXI.Graphics();
this.stage.addChild(this.loader);
this.onUpdateLoader(0);
};
PixiView.prototype.onUpdateLoader = function(progress) {
var width = 200,
height = 5,
borderWidth = 1;
if(progress < 100) {
this.loader.clear();
this.loader.beginFill(0x000000);
this.loader.lineStyle(borderWidth, 0x000000);
this.loader.drawRect(0, 0, width, height);
this.loader.endFill();
if(progress > 0) {
var color = 0xFF0FA3;
this.loader.beginFill(color);
this.loader.lineStyle(0, 0x000000);
this.loader.drawRect(borderWidth, borderWidth, width * progress / 100, height);
this.loader.endFill();
}
this.loader.position = new PIXI.Point(
Settings.STAGE_WIDTH / 2 - width / 2 - borderWidth,
Settings.STAGE_HEIGHT / 2 - height / 2 - borderWidth
);
}
this.loader.visible = progress < 100;
};
PixiView.prototype.destroy = function() {
for (var i = 0; i < this.stage.children.length; i++) {
this.stage.removeChild(this.stage.children[i]);
}
this.renderer.render(this.stage);
Parent.prototype.destroy.call(this);
};
return PixiView;
});

View file

@ -1,12 +1,11 @@
define([ define([
"Game/Client/View/Abstract/View", "Game/Client/View/Views/AbstractView",
"Game/Client/View/DomController",
"Lib/Vendor/Three", "Lib/Vendor/Three",
"Game/Config/Settings" "Game/Config/Settings"
], ],
function (Parent, Three, Settings) { function (Parent, DomController, Three, Settings) {
"use strict";
function ThreeView () { function ThreeView () {
Parent.call(this); Parent.call(this);

View file

@ -1,14 +1,7 @@
define([ define(function() {
],
function () {
"use strict";
var ItemSettings = { var ItemSettings = {
// weight is a number between 0.1 for very light and 10 for very heavy
"Default": "Default":
{ {
"category": "", "category": "",
@ -22,7 +15,7 @@ function () {
"rotation": "0", "rotation": "0",
"bounce": "0", "bounce": "0",
"grabAngle": "-1.5", "grabAngle": "-1.5",
"danger": "0", "danger": "1",
"bodyType": "dynamic", "bodyType": "dynamic",
}, },
@ -32,7 +25,7 @@ function () {
"image": "chest.png", "image": "chest.png",
"type": "ragdoll", "type": "ragdoll",
"weight": "7", "weight": "5",
"width": "6", "width": "6",
"height": "12", "height": "12",
@ -207,7 +200,7 @@ function () {
"category": "kitchen", "category": "kitchen",
"image": "fridge.gif", "image": "fridge.gif",
"weight": "5", "weight": "10",
"width": "31", "width": "31",
"height": "53", "height": "53",
@ -220,12 +213,11 @@ function () {
"category": "kitchen", "category": "kitchen",
"image": "microwave.gif", "image": "microwave.gif",
"weight": "4.6", "weight": "3.6",
"width": "19", "width": "19",
"height": "12", "height": "12",
"grabAngle": "-0.1", "grabAngle": "-0.1",
"danger": "2",
}, },
"Coffeemachine": "Coffeemachine":
@ -248,24 +240,12 @@ function () {
"height": "9", "height": "9",
}, },
"Table":
{
"category": "kitchen",
"image": "table.gif",
"weight": "3.5",
"width": "60",
"height": "21",
"grabAngle": "-0.2",
},
"Banana": "Banana":
{ {
"category": "kitchen", "category": "kitchen",
"image": "banana.gif", "image": "banana.gif",
"weight": "3", "weight": "1",
"width": "5", "width": "5",
"height": "9", "height": "9",
@ -335,45 +315,6 @@ function () {
"grabAngle": "-0.2", "grabAngle": "-0.2",
}, },
"Couch":
{
"category": "livingroom",
"image": "couch.gif",
"weight": "7",
"width": "50",
"height": "29",
"bounce": "3",
"grabAngle": "-0.2",
},
"Cactus":
{
"category": "livingroom",
"image": "cactus.gif",
"weight": "2.5",
"width": "17",
"height": "31",
"danger": "1.9",
"grabAngle": "-0.2",
},
"Piano":
{
"category": "livingroom",
"image": "piano.gif",
"weight": "10",
"width": "66",
"height": "48",
"grabAngle": "-0.2",
},
"Bible": "Bible":
{ {
"category": "livingroom", "category": "livingroom",
@ -411,19 +352,21 @@ function () {
}, },
"RubeDoll":
"Rube":
{ {
"category": "kitchen", "category": "kitchen",
"image": "banana.gif", "image": "banana.gif",
"weight": "3", // "type": "rube",
"width": "15", "weight": "1",
"width": "5",
"height": "9", "height": "9",
"type": "rubedoll", "grabAngle": "0.5",
"grabAngle": "0.001", // seems to be a bug, that 0 does not work! }
} }
};
return ItemSettings; return ItemSettings;
}); });

View file

@ -1,68 +1,50 @@
define([ define(function() {
],
function () {
"use strict";
var Settings = { var Settings = {
STAGE_WIDTH: 600, STAGE_WIDTH: 600,
STAGE_HEIGHT: 400, STAGE_HEIGHT: 400,
ZOOM_FACTOR: 0.8,
ZOOM_DEFAULT: 1,
ZOOM_MAX: 10,
// BOX2D INITIALATORS // BOX2D INITIALATORS
BOX2D_WORLD_AABB_SIZE: 3000, BOX2D_WORLD_AABB_SIZE: 3000,
BOX2D_ALLOW_SLEEP: true, BOX2D_ALLOW_SLEEP: true,
BOX2D_GRAVITY: 26, BOX2D_GRAVITY: 26,
BOX2D_VELOCITY_ITERATIONS: 20, BOX2D_VELOCITY_ITERATIONS: 5,
BOX2D_POSITION_ITERATIONS: 10, // 200/100 created problems (awful teleporting when repositioning joints) BOX2D_POSITION_ITERATIONS: 5,
BOX2D_TIME_STEP: 1 / 60, BOX2D_TIME_STEP: 1 / 60,
// PATHS // PATHS
GRAPHICS_PATH: "static/img/", GRAPHICS_PATH: 'static/img/',
GRAPHICS_SUBPATH_ITEMS: "Items/", GRAPHICS_SUBPATH_ITEMS: 'Items/',
GRAPHICS_SUBPATH_CHARACTERS: "Characters/", GRAPHICS_SUBPATH_CHARACTERS: 'Characters/',
GRAPHICS_SUBPATH_TILES: "Tiles/", GRAPHICS_SUBPATH_TILES: 'Tiles/',
MAPS_PATH: "static/maps/tiled/", MAPS_PATH: 'static/maps/tiled/',
AUDIO_PATH: "static/sounds/",
CHANNEL_RECORDING_PATH: "recordings/",
CHANNEL_PLAY_RECORDING: false, //"Varberg-2015-03-15T23:10:29.316Z-stones.log",
RATIO: 21, //35 RATIO: 21, //35
// original tile size is 25 but we want it to resize to 20 // original tile size is 25 but we want it to resize to 20
ORIGINAL_TILE_SIZE: 25, ORIGINAL_TILE_SIZE: 25,
TILE_SIZE: 20, TILE_SIZE: 20,
CAMERA_IS_ORTHOGRAPHIC: true, CAMERA_IS_ORTHOGRAPHIC: true,
CAMERA_GLIDE: 6, // % of the way per frame CAMERA_GLIDE: 12, // % of the way per frame
VIEW_CONTROLLER: 0 ? "Three" : "Pixi", VIEW_CONTROLLER: 0 ? 'Three' : 'Pixi',
ARROW_GLIDE: 30, // % of the way per frame
SHOW_LAYER_INFO: false,
ENABLE_POINTER_LOCK_FILTER: true,
// GAME PLAY // GAME PLAY
WALK_SPEED: 4, WALK_SPEED: 4,
RUN_SPEED: 8, RUN_SPEED: 8,
FLY_SPEED: 6.2, FLY_SPEED: 6.2,
JUMP_SPEED: 16, JUMP_SPEED: 20,
JUMP_STOP_DAMPING_FACTOR: 0.4, JUMP_STOP_DAMPING_FACTOR: 0.5,
MAX_THROW_FORCE: 28, MAX_THROW_FORCE: 18 * 3.5,
MAX_THROW_ANGULAR_VELOCITY: 3, MAX_THROW_ANGULAR_VELOCITY: 0,
MAX_RUNNING_WEIGHT: 9, MAX_RUNNING_WEIGHT: 9,
RESPAWN_TIME: 5, RESPAWN_TIME: 5,
HEALTH_DISPLAY_TIME: 2, HEALTH_DISPLAY_TIME: 2,
CRITICAL_HEALTH_THRESHOLD: 0.3, RAGDOLL_DESTRUCTION_TIME: 20,
RAGDOLL_DESTRUCTION_TIME: 10,
VIEWPORT_SPEED_FACTOR: 640,
VIEWPORT_LOOK_AHEAD: 0.1,
SCORE_MESSAGE_TIMEOUT: 3500,
// restitution: bouncyness, friction: rubbing, density: mass // restitution: bouncyness, friction: rubbing, density: mass
TILE_FRICTION: 0.99, TILE_FRICTION: 0.99,
TILE_RESTITUTION: 0.1, TILE_RESTITUTION: 0.1,
PLAYER_DENSITY: 12.2, //3.68, PLAYER_DENSITY: 3.68,
PLAYER_FRICTION: 5, PLAYER_FRICTION: 5,
PLAYER_MOTION_FRICTION: 0.1, PLAYER_MOTION_FRICTION: 0.1,
PLAYER_RESTITUTION: 0.0, PLAYER_RESTITUTION: 0.0,
@ -74,29 +56,27 @@ function () {
ITEM_LINEAR_DAMPING: 0.02, ITEM_LINEAR_DAMPING: 0.02,
// BROWSER // BROWSER
CANVAS_DOM_ID: "canvasContainer", CANVAS_DOM_ID: 'canvasContainer',
IS_BROWSER_ENVIRONMENT: typeof window !== "undefined", IS_BROWSER_ENVIRONMENT: typeof window !== 'undefined',
USE_WEBGL: true, USE_WEBGL: true,
// NETWORKING // NETWORKING
NETWORK_UPDATE_INTERVAL: 70, // in milliseconds NETWORK_UPDATE_INTERVAL: 70,
CHANNEL_DESTRUCTION_TIME: 30,
NETWORK_LOG_INCOMING: false, NETWORK_LOG_INCOMING: false,
NETWORK_LOG_OUTGOING: false, NETWORK_LOG_OUTGOING: false,
NETWORK_LOG_FILTER: ["ping", "pong", "worldUpdate", "lookAt"], NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'],
// CHANNEL // CHANNEL
CHANNEL_MAX_USERS: 20, CHANNEL_END_ROUND_TIME: 4, //10,
CHANNEL_DESTRUCTION_TIME: 0.5 * 60, CHANNEL_DEFAULT_MAX_USERS: 40,
CHANNEL_END_ROUND_TIME: 20, //10, CHANNEL_DEFAULT_SCORE_LIMIT: 10,
CHANNEL_DEFAULT_MAX_USERS: 10, CHANNEL_DEFAULT_LEVELS: ['stones2', 'debug', 'stones2', 'debug'],
CHANNEL_DEFAULT_SCORE_LIMIT: 5,
CHANNEL_DEFAULT_LEVELS: ["debug"],
CHANNEL_RECORD_SESSION: false,
// ME STATE // ME STATE
ME_STATE_MAX_DIFFERENCE_METERS: 1, ME_STATE_MAX_DIFFERENCE_METERS: 1,
PUNKBUSTER_DIFFERENCE_METERS: 1 PUNKBUSTER_DIFFERENCE_METERS: 1
}; }
Settings.TILE_RATIO = Settings.ORIGINAL_TILE_SIZE / Settings.TILE_SIZE; Settings.TILE_RATIO = Settings.ORIGINAL_TILE_SIZE / Settings.TILE_SIZE;

View file

@ -4,8 +4,6 @@ define([
function (Box2D) { function (Box2D) {
"use strict";
function Detector () { function Detector () {
this.listener = new Box2D.Dynamics.b2ContactListener(); this.listener = new Box2D.Dynamics.b2ContactListener();
this.listener.BeginContact = this.beginContact.bind(this); this.listener.BeginContact = this.beginContact.bind(this);

View file

@ -1,21 +1,20 @@
define([ define(function () {
],
function () {
function PlayerController (player) { function PlayerController (player) {
this.player = player; this.player = player;
this._shift;
this._isJumping;
this._walkingDirectionStatus = 0; this._walkingDirectionStatus = 0;
} }
PlayerController.prototype.moveLeft = function () { PlayerController.prototype.moveLeft = function () {
if(!this.isPlayerInputAllowed()) return;
this.player.move(-1); this.player.move(-1);
this._walkingDirectionStatus = -1; this._walkingDirectionStatus = -1;
} }
PlayerController.prototype.moveRight = function () { PlayerController.prototype.moveRight = function () {
if(!this.isPlayerInputAllowed()) return;
this.player.move(1); this.player.move(1);
this._walkingDirectionStatus = 1; this._walkingDirectionStatus = 1;
} }
@ -26,7 +25,7 @@ function () {
} }
PlayerController.prototype.jump = function () { PlayerController.prototype.jump = function () {
if(!this.isPlayerInputAllowed()) return; this._isJumping = true;
this.player.jump(); this.player.jump();
} }
@ -35,31 +34,15 @@ function () {
} }
PlayerController.prototype.lookAt = function (options) { PlayerController.prototype.lookAt = function (options) {
if(!this.isPlayerInputAllowed()) return;
if(options) this.player.lookAt(options.x, options.y); if(options) this.player.lookAt(options.x, options.y);
} }
PlayerController.prototype.activateModifier = function() {
if (!this.isPlayerInputAllowed()) return;
this.player.activateModifier();
};
PlayerController.prototype.deactivateModifier = function() {
if (!this.isPlayerInputAllowed()) return;
this.player.deactivateModifier();
};
PlayerController.prototype.update = function () { PlayerController.prototype.update = function () {
if(this._walkingDirectionStatus != 0) { if(this._walkingDirectionStatus != 0) {
this.player.move(this._walkingDirectionStatus); this.player.move(this._walkingDirectionStatus);
} }
} }
// Default behaviour - may be needed later?
PlayerController.prototype.isPlayerInputAllowed = function() {
return true;
};
PlayerController.prototype.destroy = function() { PlayerController.prototype.destroy = function() {
// extend if necessary // extend if necessary
}; };

View file

@ -4,28 +4,24 @@ define([
"Game/" + GLOBALS.context + "/Player", "Game/" + GLOBALS.context + "/Player",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Game/" + GLOBALS.context + "/GameObjects/Doll", "Game/" + GLOBALS.context + "/GameObjects/Doll",
"Game/" + GLOBALS.context + "/GameObjects/GameObject",
"Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Utilities/Assert",
], ],
function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert) { function (PhysicsEngine, TiledLevel, Player, Nc, Doll) {
"use strict";
function GameController (options) { function GameController (options) {
this.options = options; this.options = options;
this.players = {}; this.players = {};
this.level = null; this.level = null;
this.worldUpdateObjects = {}; this.gameObjects = null;
this.resetGameObjects();
this.physicsEngine = new PhysicsEngine(); this.physicsEngine = new PhysicsEngine();
this.physicsEngine.setCollisionDetector(); this.physicsEngine.setCollisionDetector();
this.ncTokens = [ this.ncTokens = [
nc.on(nc.ns.core.game.worldUpdateObjects.add, this.onWorldUpdateObjectAdd, this), Nc.on(Nc.ns.core.game.gameObject.add, this.onGameObjectAdd, this),
nc.on(nc.ns.core.game.worldUpdateObjects.remove, this.onWorldUpdateObjectRemove, this) Nc.on(Nc.ns.core.game.gameObject.remove, this.onGameObjectRemove, this)
]; ];
this.loadLevel(options.levelUid); this.loadLevel(options.levelUid);
@ -37,61 +33,46 @@ function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert)
// extend for both sides if necessary // extend for both sides if necessary
}; };
GameController.prototype.onWorldUpdateObjectAdd = function(object) { GameController.prototype.resetGameObjects = function() {
this.worldUpdateObjects[object.uid] = object; this.gameObjects = {
fixed: [],
animated: []
};
}; };
GameController.prototype.onWorldUpdateObjectRemove = function(object) { GameController.prototype.onGameObjectAdd = function(type, object) {
delete this.worldUpdateObjects[object.uid]; 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.getPhysicsEngine = function () { GameController.prototype.getPhysicsEngine = function () {
return this.physicsEngine; 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) { GameController.prototype.loadLevel = function (levelUid) {
if (this.level) { if (this.level) {
this.level.destroy(); this.level.destroy();
this.worldUpdateObjects = {}; this.resetGameObjects();
} }
this.level = new TiledLevel(levelUid, this.physicsEngine); this.level = new TiledLevel(levelUid, this.physicsEngine, this.gameObjects);
};
/*
* This is now in core, because the recorder/player
* uses the world update mechanism on the channel side
*/
GameController.prototype.onWorldUpdate = function (updateData) {
for (var uid in updateData) {
var gameObject = this.worldUpdateObjects[uid];
if (!(gameObject instanceof GameObject)) {
console.warn('Can\'t find object ' + uid + ' in worldUpdateObjects pool:', Object.keys(this.worldUpdateObjects));
continue;
}
this.updateGameObject(gameObject, updateData[uid]);
}
};
GameController.prototype.updateGameObject = function(gameObject, gameObjectUpdate) {
gameObject.setUpdateData(gameObjectUpdate);
} }
GameController.prototype.onResetLevel = function() { GameController.prototype.onResetLevel = function() {
this.loadLevel(this.level.uid); this.loadLevel(this.level.uid);
}; };
/*
GameController.prototype.userJoined = function (user) {
this.players[user.id] = this.createPlayer(user);
}
*/
GameController.prototype.onUserLeft = function (userId) { GameController.prototype.onUserLeft = function (userId) {
var player = this.players[userId]; var player = this.players[userId];
if(!player) { if(!player) {
@ -101,34 +82,47 @@ function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert)
player.destroy(); player.destroy();
delete this.players[userId]; delete this.players[userId];
}; }
GameController.prototype.createPlayer = function(user, revealedGameController) { GameController.prototype.createPlayer = function(user) {
var player = new Player(user.id, this.physicsEngine, user, revealedGameController); var player = new Player(user.id, this.physicsEngine, user);
this.players[user.id] = player; this.players[user.id] = player;
return player; return player;
}; };
GameController.prototype.destroy = function () { GameController.prototype.destroy = function () {
for(var player in this.players) { for(var player in this.players) {
this.players[player].destroy(); // this.players[player].destroy();
// FIXME:
// commented out for now, because players are in gameObjects array.
// try using a real gameobject for the health bar
} }
// FIXME ns.client in core? for (var i = 0; i < this.ncTokens.length; i++) {
nc.trigger(nc.ns.client.game.events.destroy); Nc.off(this.ncTokens[i]);
};
// Testing after destroy if worldUpdateObjects is empty /*
// events.game.destroy -> gameobjects.destroy() -> nc.trigger(worldUpdateObjects.remove) * Contents of gameObject: Players, Items, Tiles, RagDolls
if(Object.keys(this.worldUpdateObjects).length > 0) { * No Dolls.
console.warn('Not all worldUpdateObjects have been removed... ', Object.keys(this.worldUpdateObjects)); */
}
for (var key in this.gameObjects) {
for (var i = 0; i < this.gameObjects[key].length; i++) {
var gameObject = this.gameObjects[key][i];
gameObject.destroy();
};
};
this.gameObjects = {
fixed: [],
animated: []
};
this.physicsEngine.destroy(); this.physicsEngine.destroy();
this.worldUpdateObjects = null; }
nc.off(this.ncTokens);
};
return GameController; return GameController;
}); });

View file

@ -1,17 +1,13 @@
define([ define([
"Game/" + GLOBALS.context + "/GameObjects/GameObject", "Game/" + GLOBALS.context + "/GameObjects/GameObject",
"Lib/Utilities/Exception",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Game/Config/Settings", "Game/Config/Settings",
"Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/Collision/Detector",
"Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Lib/Utilities/Assert"
], ],
function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Assert) { function (Parent, Box2D, Settings, CollisionDetector, Item, Nc) {
"use strict";
function Doll (physicsEngine, uid, player) { function Doll (physicsEngine, uid, player) {
@ -28,8 +24,8 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.standing = false; this.standing = false;
this.moveDirection = 0; this.moveDirection = 0;
this.lookDirection = 0; this.lookDirection = 0;
this.legs = null; this.legs;
this.footSensor = null; this.footSensor;
this.actionState = null; this.actionState = null;
this.lookAtXY = { x:0, y:0 }; this.lookAtXY = { x:0, y:0 };
this.reachableItems = { this.reachableItems = {
@ -40,12 +36,11 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.holdingJoint = null; this.holdingJoint = null;
this.holdingItem = null; this.holdingItem = null;
this.ragDoll = {head: null, body: null}; // FIXME: wtf is this? can we remove it? this.ragDoll = {head: null, body: null};
this.createFixtures(); this.createFixtures();
this.body.SetActive(false); this.body.SetActive(false);
nc.trigger(nc.ns.core.game.worldUpdateObjects.add, this);
} }
Doll.prototype = Object.create(Parent.prototype); Doll.prototype = Object.create(Parent.prototype);
@ -61,10 +56,6 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
}; };
Doll.prototype.createFixtures = function () { Doll.prototype.createFixtures = function () {
Assert.number(this.width, this.height);
Assert.number(this.reachDistance);
Assert.number(this.areaSize);
var self = this; var self = this;
var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
@ -73,15 +64,13 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
fixtureDef.restitution = Settings.PLAYER_RESTITUTION; fixtureDef.restitution = Settings.PLAYER_RESTITUTION;
var headShape = new Box2D.Collision.Shapes.b2CircleShape(); var headShape = new Box2D.Collision.Shapes.b2CircleShape();
var radius = this.width / 2 / Settings.RATIO; headShape.SetRadius(this.width / 2 / Settings.RATIO);
headShape.SetRadius(radius);
headShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(0, -(this.height - (this.width / 2)) / Settings.RATIO)); headShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(0, -(this.height - (this.width / 2)) / Settings.RATIO));
fixtureDef.shape = headShape; fixtureDef.shape = headShape;
fixtureDef.isSensor = false; fixtureDef.isSensor = false;
fixtureDef.userData = { fixtureDef.userData = {
onCollisionChange: this.onImpact.bind(this) onCollisionChange: this.onImpact.bind(this)
}; }
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
@ -114,7 +103,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
fixtureDef.userData = { fixtureDef.userData = {
onCollisionChange: this.onFootSensorDetection.bind(this) onCollisionChange: this.onFootSensorDetection.bind(this)
}; }
this.footSensor = this.body.CreateFixture(fixtureDef); this.footSensor = this.body.CreateFixture(fixtureDef);
@ -133,7 +122,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
onCollisionChange: function(isColliding, fixture) { onCollisionChange: function(isColliding, fixture) {
self.onFixtureWithinReach(isColliding, "left", fixture); self.onFixtureWithinReach(isColliding, "left", fixture);
} }
}; }
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
var grabSensorRightShape = new Box2D.Collision.Shapes.b2PolygonShape(); var grabSensorRightShape = new Box2D.Collision.Shapes.b2PolygonShape();
@ -152,7 +141,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
onCollisionChange: function(isColliding, fixture) { onCollisionChange: function(isColliding, fixture) {
self.onFixtureWithinReach(isColliding, "right", fixture); self.onFixtureWithinReach(isColliding, "right", fixture);
} }
}; }
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
@ -171,7 +160,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
fixtureDef.userData = { fixtureDef.userData = {
onCollisionChange: function(isColliding, fixture) { onCollisionChange: function(isColliding, fixture) {
var userData = fixture.GetBody().GetUserData(); var userData = fixture.GetBody().GetUserData()
if(userData instanceof Doll) { if(userData instanceof Doll) {
var doll = userData; var doll = userData;
var i = self.nearbyDolls.indexOf(doll); var i = self.nearbyDolls.indexOf(doll);
@ -186,29 +175,28 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
} }
} }
} }
}; }
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
}; }
Doll.prototype.setActionState = function(state) { Doll.prototype.setActionState = function(state) {
this.actionState = state; this.actionState = state;
}; }
Doll.prototype.getActionState = function() { Doll.prototype.getActionState = function() {
return this.actionState; return this.actionState;
}; }
Doll.prototype.isWalking = function() { Doll.prototype.isWalking = function() {
return ["walk", "walkback", "run"].indexOf(this.actionState) >= 0; return ["walk", "walkback", "run"].indexOf(this.actionState) >= 0;
}; }
Doll.prototype.spawn = function (x, y) { Doll.prototype.spawn = function (x, y) {
Assert.number(x, y);
this.body.SetPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO)); this.body.SetPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO));
this.body.SetActive(true); this.body.SetActive(true);
this.setActionState("fall"); this.setActionState("fall");
}; }
Doll.prototype.getHeadPosition = function() { Doll.prototype.getHeadPosition = function() {
var pos = this.body.GetPosition(); var pos = this.body.GetPosition();
@ -221,21 +209,19 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
Doll.prototype.setFriction = function (friction) { Doll.prototype.setFriction = function (friction) {
if(!friction) friction = -1; if(!friction) friction = -1;
Assert.number(friction);
if (this.legs.GetFriction() != friction) { if (this.legs.GetFriction() != friction) {
this.legs.SetFriction(friction); this.legs.SetFriction(friction);
} }
}; }
Doll.prototype.move = function (direction, modifierActivated) { Doll.prototype.move = function (direction) {
this.moveDirection = direction; this.moveDirection = direction;
var speed; var speed;
var isHoldingHeavyItem = this.holdingItem && this.holdingItem.options.weight > Settings.MAX_RUNNING_WEIGHT; var isHoldingHeavyItem = this.holdingItem && this.holdingItem.options.weight > Settings.MAX_RUNNING_WEIGHT;
switch(true) { switch(true) {
case direction == this.lookDirection && this.isStanding() && !isHoldingHeavyItem && !modifierActivated: case direction == this.lookDirection && this.isStanding() && !isHoldingHeavyItem:
speed = Settings.RUN_SPEED; speed = Settings.RUN_SPEED;
break; break;
@ -256,15 +242,13 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.setFriction(Settings.PLAYER_MOTION_FRICTION); this.setFriction(Settings.PLAYER_MOTION_FRICTION);
this.body.SetAwake(true); this.body.SetAwake(true);
Assert.number(speed, direction);
var vector = new Box2D.Common.Math.b2Vec2(speed * direction, this.body.GetLinearVelocity().y); var vector = new Box2D.Common.Math.b2Vec2(speed * direction, this.body.GetLinearVelocity().y);
this.body.SetLinearVelocity(vector); this.body.SetLinearVelocity(vector);
if(this.isStanding()) { if(this.isStanding()) {
if(this.moveDirection == this.lookDirection) { if(this.moveDirection == this.lookDirection) {
if(isHoldingHeavyItem || modifierActivated) { if(isHoldingHeavyItem) {
this.setActionState("walk"); this.setActionState("walk");
} else { } else {
this.setActionState("run"); this.setActionState("run");
@ -274,7 +258,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.setActionState("walkback"); this.setActionState("walkback");
} }
} }
}; }
Doll.prototype.stop = function () { Doll.prototype.stop = function () {
this.moveDirection = 0; this.moveDirection = 0;
@ -286,20 +270,20 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
vector.x *= Settings.JUMP_STOP_DAMPING_FACTOR; vector.x *= Settings.JUMP_STOP_DAMPING_FACTOR;
this.body.SetLinearVelocity(vector); this.body.SetLinearVelocity(vector);
} }
}; }
Doll.prototype.jump = function () { Doll.prototype.jump = function () {
if (this.isStanding()) { if (this.isStanding()) {
this.body.SetAwake(true); this.body.SetAwake(true);
var vector = new Box2D.Common.Math.b2Vec2(0, -Settings.JUMP_SPEED); var vector = new Box2D.Common.Math.b2Vec2(0, -Settings.JUMP_SPEED);
this.body.SetLinearVelocity(vector); this.body.SetLinearVelocity(vector);
this.setStanding(false); this.setStanding(false);
this.setActionState("jump"); this.setActionState("jump");
} }
}; }
Doll.prototype.jumpStop = function () { Doll.prototype.jumpStop = function () {
if (!this.isStanding() ) { if (!this.isStanding() ) {
@ -310,17 +294,17 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.body.SetLinearVelocity(vector); this.body.SetLinearVelocity(vector);
} }
} }
}; }
Doll.prototype.setStanding = function (isStanding) { Doll.prototype.setStanding = function (isStanding) {
if (this.standing == isStanding) return; if (this.standing == isStanding) return;
this.standing = isStanding; this.standing = isStanding;
if(isStanding) this.setActionState("stand"); if(isStanding) this.setActionState("stand");
}; }
Doll.prototype.isStanding = function () { Doll.prototype.isStanding = function () {
return this.standing; return this.standing;
}; }
Doll.prototype.lookAt = function(x, y) { Doll.prototype.lookAt = function(x, y) {
var oldLookDirection = this.lookDirection; var oldLookDirection = this.lookDirection;
@ -354,12 +338,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
} }
var bodyPosition = this.body.GetPosition(); var bodyPosition = this.body.GetPosition();
Assert.number(this.width, this.height);
Assert.number(this.lookDirection);
var handPosition = new Box2D.Common.Math.b2Vec2( var handPosition = new Box2D.Common.Math.b2Vec2(
bodyPosition.x + ((this.width / 2 / Settings.RATIO) * this.lookDirection), bodyPosition.x + ((this.width / 2 / Settings.RATIO) * this.lookDirection),
bodyPosition.y - this.height / 4 * 2 / Settings.RATIO // 2/3 of the body height bodyPosition.y - this.height / 3 * 2 / Settings.RATIO // 2/3 of the body height
); );
this.holdingItem.reposition(handPosition, this.lookDirection); this.holdingItem.reposition(handPosition, this.lookDirection);
@ -371,31 +352,19 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
} }
}; };
Doll.prototype.throw = function(item, options) { Doll.prototype.throw = function(item, x, y) {
if(this.holdingJoint) {
this.body.GetWorld().DestroyJoint(this.holdingJoint); this.body.GetWorld().DestroyJoint(this.holdingJoint);
} else {
// log stack if we called throw without a holdingJoint
var w = new Error("Throwing without a holdingJoint");
console.error(w.message + "\n" + w.stack);
}
this.holdingJoint = null; this.holdingJoint = null;
this.holdingItem = null; this.holdingItem = null;
var dollVelocity = { item.throw(x, y);
x: this.body.GetLinearVelocity().x,
y: this.body.GetLinearVelocity().y
};
item.throw(options, dollVelocity);
}; };
Doll.prototype.isAnotherPlayerNearby = function() { Doll.prototype.isAnotherPlayerNearby = function() {
return this.nearbyDolls.length > 0; return this.nearbyDolls.length > 0;
}; };
Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { // jshint unused:false Doll.prototype.onFootSensorDetection = function(isColliding, fixture) {
var self = this; var self = this;
@ -432,9 +401,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
self.setStanding(false); self.setStanding(false);
} }
} }
}; }
Doll.prototype.onImpact = function(isColliding, fixture) { // jshint unused:false Doll.prototype.onImpact = function(isColliding, fixture) {
// overwrite if necessary // overwrite if necessary
}; };
@ -452,7 +421,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
this.reachableItems[side].splice(i, 1); this.reachableItems[side].splice(i, 1);
} }
} }
}; }
Doll.prototype.getVelocities = function() { Doll.prototype.getVelocities = function() {
return { return {
@ -463,7 +432,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser
Doll.prototype.update = function() { Doll.prototype.update = function() {
if (this.body.GetLinearVelocity().x === 0 && this.isWalking()) { if (this.body.GetLinearVelocity().x == 0 && this.isWalking()) {
this.stop(); this.stop();
} }
@ -472,16 +441,7 @@ 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() { Doll.prototype.destroy = function() {
nc.trigger(nc.ns.core.game.worldUpdateObjects.remove, this);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };

View file

@ -1,24 +1,16 @@
define([ define([
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/Exception", "Lib/Utilities/Exception"
"Lib/Utilities/Assert",
"Lib/Utilities/NotificationCenter"
], ],
function (Box2D, Exception, Assert, nc) { function (Box2D, Exception) {
"use strict";
function GameObject(physicsEngine, uid) { function GameObject(physicsEngine, uid) {
this.uid = uid; this.uid = uid;
var def = this.getBodyDef(); var def = this.getBodyDef();
def.userData = this; def.userData = this;
this.body = physicsEngine.createBody(def); 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() { GameObject.prototype.getBodyDef = function() {
@ -26,14 +18,11 @@ function (Box2D, Exception, Assert, nc) {
}; };
GameObject.prototype.destroy = function() { GameObject.prototype.destroy = function() {
if(this.body instanceof Box2D.Dynamics.b2Body) { if(this.body instanceof Box2D.Dynamics.b2Body) {
this.body.GetWorld().DestroyBody(this.body); this.body.GetWorld().DestroyBody(this.body);
} else { } else {
throw new Exception("can not destroy body"); throw new Exception("can not destroy body");
} }
nc.off(this.ncTokens);
}; };
GameObject.prototype.getBody = function() { GameObject.prototype.getBody = function() {
@ -44,20 +33,6 @@ function (Box2D, Exception, Assert, nc) {
return this.body.GetPosition().Copy(); 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; return GameObject;
}); });

View file

@ -1,16 +1,13 @@
define([ define([
"Game/" + GLOBALS.context + "/GameObjects/GameObject", "Game/" + GLOBALS.context + "/GameObjects/GameObject",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/OptionsHelper", "Lib/Utilities/Options",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/Exception", "Lib/Utilities/Exception",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Lib/Utilities/Assert"
], ],
function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { function (Parent, Box2D, Options, Settings, Exception, Nc) {
"use strict";
function Item(physicsEngine, uid, options) { function Item(physicsEngine, uid, options) {
@ -26,28 +23,25 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) {
y: parseFloat(options.y) y: parseFloat(options.y)
}; };
this.options = optionsHelper.merge(floatOptions, options); this.options = Options.merge(floatOptions, options);
if(!this.options.category) { if(!this.options.category) {
// FIXME add more validation // FIXME add more validation
//console.warn('item category empty (' + this.options.name + ')' ); console.warn('item category empty (' + this.options.name + ')' );
} }
Parent.call(this, physicsEngine, uid); Parent.call(this, physicsEngine, uid);
this.createFixture(); this.createFixture();
this.body.ResetMassData(); this.body.ResetMassData();
this.flipDirection = 1; this.flipDirection = 1;
if (this.body.GetMass() < 1) {
this.body.SetBullet(true);
}
nc.trigger(nc.ns.core.game.worldUpdateObjects.add, this); Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this);
} }
Item.prototype = Object.create(Parent.prototype); Item.prototype = Object.create(Parent.prototype);
Item.prototype.getBodyDef = function() { Item.prototype.getBodyDef = function() {
Assert.number(this.options.x, this.options.y);
var bodyDef = new Box2D.Dynamics.b2BodyDef(); var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
bodyDef.position.x = this.options.x / Settings.RATIO; bodyDef.position.x = this.options.x / Settings.RATIO;
@ -55,18 +49,14 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) {
bodyDef.angle = 0; bodyDef.angle = 0;
return bodyDef; return bodyDef;
}; }
Item.prototype.getFixtureDef = function() { Item.prototype.getFixtureDef = function() {
Assert.number(this.options.width, this.options.height);
Assert.number(this.options.weight);
Assert.number(this.options.bounce);
var itemShape; var itemShape;
var w = this.options.width / Settings.RATIO; var w = this.options.width / Settings.RATIO;
var h = this.options.height / Settings.RATIO; var h = this.options.height / Settings.RATIO;
if(this.options.type == "circle") { if(this.options.type == 'circle'){
var r = (w + h) / 4 ; var r = (w + h) / 4 ;
itemShape = new Box2D.Collision.Shapes.b2CircleShape(); itemShape = new Box2D.Collision.Shapes.b2CircleShape();
itemShape.SetRadius(r); itemShape.SetRadius(r);
@ -76,19 +66,25 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) {
itemShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(h/2))); itemShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(h/2)));
} }
var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
fixtureDef.shape = itemShape; fixtureDef.shape = itemShape;
fixtureDef.density = this.options.weight; var offset = 4,
factor = 80;
var density = ((this.options.weight + offset) / this.options.width / this.options.height) * factor;
fixtureDef.density = density;
fixtureDef.friction = Settings.ITEM_FRICTION; fixtureDef.friction = Settings.ITEM_FRICTION;
fixtureDef.restitution = this.options.bounce ? this.options.bounce / 10 : Settings.ITEM_RESTITUTION; fixtureDef.restitution = this.options.bounce
? this.options.bounce / 10
: Settings.ITEM_RESTITUTION;
fixtureDef.isSensor = false; fixtureDef.isSensor = false;
fixtureDef.userData = { fixtureDef.userData = {
onCollisionChange: this.onCollisionChange.bind(this) onCollisionChange: this.onCollisionChange.bind(this)
}; }
return fixtureDef; return fixtureDef;
}; };
@ -96,7 +92,7 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) {
Item.prototype.createFixture = function () { Item.prototype.createFixture = function () {
var fixtureDef = this.getFixtureDef(); var fixtureDef = this.getFixtureDef();
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
}; }
Item.prototype.flip = function(direction) { Item.prototype.flip = function(direction) {
this.flipDirection = direction; this.flipDirection = direction;
@ -104,61 +100,48 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) {
// FIXME: implement body flip if necessary // FIXME: implement body flip if necessary
}; };
Item.prototype.beingGrabbed = function(player) { // jshint unused:false Item.prototype.beingGrabbed = function(player) {
// overwrite if necessary // overwrite if necessary
}; };
Item.prototype.beingReleased = function(player) { // jshint unused:false Item.prototype.beingReleased = function(player) {
// overwrite if necessary // overwrite if necessary
}; };
Item.prototype.onCollisionChange = function(isColliding, fixture, info) { // jshint unused:false Item.prototype.onCollisionChange = function(isColliding, fixture, info) {
// overwrite if necessary // overwrite if necessary
}; };
Item.prototype.reposition = function(handPosition, direction) { Item.prototype.reposition = function(handPosition, direction) {
Assert.number(handPosition.x, handPosition.y);
Assert.number(direction);
Assert.number(this.options.width);
Assert.number(this.options.grabAngle);
this.body.SetAwake(true); this.body.SetAwake(true);
var position = new Box2D.Common.Math.b2Vec2( var position = new Box2D.Common.Math.b2Vec2(
handPosition.x + ((this.options.width / Settings.RATIO / 2) * direction), handPosition.x + ((this.options.width / Settings.RATIO / 2) * direction),
handPosition.y handPosition.y
); )
this.body.SetPosition(position); this.body.SetPosition(position);
this.body.SetAngle((this.options.grabAngle || 0.0) * direction);
this.flip(direction); this.flip(direction);
this.body.SetAngle((this.options.grabAngle || 0) * direction);
}; };
Item.prototype.getGrabPoint = function() { Item.prototype.getGrabPoint = function() {
return this.body.GetWorldCenter(); return this.body.GetWorldCenter();
}; };
Item.prototype.throw = function(options, carrierVelocity) { Item.prototype.throw = function(x, y) {
this.accelerateBody(this.body, options, carrierVelocity); var body = this.body;
};
Item.prototype.accelerateBody = function(body, options, carrierVelocity) {
Assert.number(this.options.weight);
Assert.number(carrierVelocity.x, carrierVelocity.y);
Assert.number(options.x, options.y);
Assert.number(options.av);
body.SetAwake(true); body.SetAwake(true);
var x = options.x * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.x; var vector = new Box2D.Common.Math.b2Vec2(
var y = -options.y * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.y; x * Settings.MAX_THROW_FORCE / this.options.weight,
var vector = new Box2D.Common.Math.b2Vec2(x, y); -y * Settings.MAX_THROW_FORCE / this.options.weight
body.SetLinearVelocity(vector); );
this.body.SetLinearVelocity(vector);
var av = -options.av * Settings.MAX_THROW_ANGULAR_VELOCITY; body.SetAngularVelocity(Settings.MAX_THROW_ANGULAR_VELOCITY * x);
body.SetAngularVelocity(av);
}; };
Item.prototype.destroy = function() { Item.prototype.destroy = function() {
nc.trigger(nc.ns.core.game.worldUpdateObjects.remove, this); Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this);
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };

View file

@ -2,15 +2,10 @@ define([
"Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Lib/Utilities/Assert",
"Lib/Utilities/OptionsHelper",
"Game/Config/ItemSettings",
], ],
function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { function (Parent, Box2D, Settings, Nc) {
"use strict";
function RagDoll(physicsEngine, uid, options) { function RagDoll(physicsEngine, uid, options) {
@ -95,15 +90,16 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
// FIXME
var ragdollOptions = optionsHelper.merge(ItemSettings.RagDoll, ItemSettings.Default);
options = optionsHelper.merge(options, ragdollOptions);
Parent.call(this, physicsEngine, uid, options); Parent.call(this, physicsEngine, uid, options);
//this.createSensor(); //this.createSensor();
this.limbs = {}; this.limbs = {};
this.addHead();
this.addHead();
this.addLimb( this.addLimb(
@ -137,6 +133,7 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
this.addLimb( this.addLimb(
"upperLeftArm", "upperLeftArm",
this.body, this.body,
@ -164,7 +161,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
0, 0,
options.limbs.upperRightArm.height / 2 options.limbs.upperRightArm.height / 2
); );
} }
RagDoll.prototype = Object.create(Parent.prototype); RagDoll.prototype = Object.create(Parent.prototype);
@ -185,14 +181,10 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
var bodyDef = Parent.prototype.getBodyDef.call(this); var bodyDef = Parent.prototype.getBodyDef.call(this);
bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING; bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING;
bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
bodyDef.position.y -= this.options.height / 2 / Settings.RATIO; // position it on top of ground
return bodyDef; return bodyDef;
}; };
RagDoll.prototype.getFixtureDef = function() { RagDoll.prototype.getFixtureDef = function() {
Assert.number(this.options.limbs.chest.width, this.options.limbs.chest.height);
var fixtureDef = Parent.prototype.getFixtureDef.call(this); var fixtureDef = Parent.prototype.getFixtureDef.call(this);
fixtureDef.density = Settings.PLAYER_DENSITY; fixtureDef.density = Settings.PLAYER_DENSITY;
fixtureDef.friction = Settings.PLAYER_FRICTION; fixtureDef.friction = Settings.PLAYER_FRICTION;
@ -212,8 +204,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
}; };
RagDoll.prototype.createSensor = function() { RagDoll.prototype.createSensor = function() {
Assert.number(this.options.width, this.options.height);
var w = this.options.width / Settings.RATIO; var w = this.options.width / Settings.RATIO;
var h = this.options.height / Settings.RATIO; var h = this.options.height / Settings.RATIO;
@ -226,18 +216,14 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
fixtureDef.userData = { fixtureDef.userData = {
onCollisionChange: this.onCollisionChange.bind(this) onCollisionChange: this.onCollisionChange.bind(this)
}; }
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
}; };
RagDoll.prototype.addHead = function() { RagDoll.prototype.addHead = function() {
Assert.number(this.options.x, this.options.y);
Assert.number(this.options.limbs.head.x, this.options.limbs.head.y);
Assert.number(this.options.limbs.head.width);
var x = this.options.x + this.options.limbs.head.x, var x = this.options.x + this.options.limbs.head.x,
y = this.options.y + this.options.limbs.head.y - this.options.height / 2; // position it on top of ground; y = this.options.y + this.options.limbs.head.y;
var bodyDef = new Box2D.Dynamics.b2BodyDef(); var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
@ -282,13 +268,8 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
}; };
RagDoll.prototype.addLimb = function(name, connectTo, xOffset, yOffset) { RagDoll.prototype.addLimb = function(name, connectTo, xOffset, yOffset) {
Assert.number(xOffset, yOffset);
Assert.number(this.options.x, this.options.y);
Assert.number(this.options.limbs[name].x, this.options.limbs[name].y);
Assert.number(this.options.limbs[name].width, this.options.limbs[name].height);
var x = this.options.x + this.options.limbs[name].x, var x = this.options.x + this.options.limbs[name].x,
y = this.options.y + this.options.limbs[name].y - this.options.height / 2; // position it on top of ground;; y = this.options.y + this.options.limbs[name].y;
var bodyDef = new Box2D.Dynamics.b2BodyDef(); var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING; bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING;
@ -339,10 +320,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
}; };
RagDoll.prototype.reposition = function(handPosition, direction) { RagDoll.prototype.reposition = function(handPosition, direction) {
Assert.number(this.options.limbs.head.x, this.options.limbs.head.y);
Assert.number(this.options.grabAngle);
Assert.number(direction);
Parent.prototype.reposition.call(this, handPosition, direction); Parent.prototype.reposition.call(this, handPosition, direction);
var chestPosition = this.body.GetPosition(); var chestPosition = this.body.GetPosition();
@ -350,25 +327,30 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
var position = new Box2D.Common.Math.b2Vec2( var position = new Box2D.Common.Math.b2Vec2(
chestPosition.x + this.options.limbs.head.x / Settings.RATIO, chestPosition.x + this.options.limbs.head.x / Settings.RATIO,
chestPosition.y + this.options.limbs.head.y / Settings.RATIO chestPosition.y + this.options.limbs.head.y / Settings.RATIO
); )
this.limbs.head.SetPosition(position); this.limbs.head.SetPosition(position);
this.limbs.head.SetAngle((this.options.grabAngle || 0.0) * direction); this.limbs.head.SetAngle((this.options.grabAngle || 0) * direction);
}; };
RagDoll.prototype.throw = function(options, carrierVelocity) { RagDoll.prototype.throw = function(x, y) {
Parent.prototype.throw.call(this, options, carrierVelocity); Parent.prototype.throw.call(this, x, y);
var limbDampingFactor = 1;
for(var name in this.limbs) { for(var name in this.limbs) {
var body = this.limbs[name]; var body = this.limbs[name];
body.SetAwake(true);
this.accelerateBody(body, options, carrierVelocity); var vector = new Box2D.Common.Math.b2Vec2(
x * Settings.MAX_THROW_FORCE * limbDampingFactor / this.options.weight,
-y * Settings.MAX_THROW_FORCE * limbDampingFactor / this.options.weight
);
body.SetLinearVelocity(vector);
// body.SetAngularVelocity(Settings.MAX_THROW_ANGULAR_VELOCITY * x);
} }
}; };
RagDoll.prototype.setVelocities = function(options) { RagDoll.prototype.setVelocities = function(options) {
Assert.number(options.linearVelocity.x, options.linearVelocity.y);
Assert.number(options.angularVelocity);
this.body.SetLinearVelocity(options.linearVelocity); this.body.SetLinearVelocity(options.linearVelocity);
this.body.SetAngularVelocity(options.angularVelocity); this.body.SetAngularVelocity(options.angularVelocity);
for(var name in this.limbs) { for(var name in this.limbs) {
@ -378,6 +360,7 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) {
RagDoll.prototype.destroy = function() { RagDoll.prototype.destroy = function() {
Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this);
var world = this.body.GetWorld(); var world = this.body.GetWorld();
for (var name in this.limbs) { for (var name in this.limbs) {

View file

@ -6,8 +6,6 @@ define([
function (Parent, Box2D, Settings) { function (Parent, Box2D, Settings) {
"use strict";
function RagDoll(physicsEngine, uid, options) { function RagDoll(physicsEngine, uid, options) {
Parent.call(this, physicsEngine, uid, options); Parent.call(this, physicsEngine, uid, options);
this.body.GetWorld().DestroyBody(this.body); this.body.GetWorld().DestroyBody(this.body);

File diff suppressed because it is too large Load diff

View file

@ -1,223 +0,0 @@
define([
"Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Vendor/RubeLoader",
"Lib/Vendor/Box2D",
"Game/Config/Settings",
"Lib/Utilities/Assert",
"Lib/Utilities/NotificationCenter",
"Lib/Utilities/Matrix",
"json!Game/Asset/RubeDoll.json" // using requirejs json loader plugin
],
function (Parent, RubeLoader, Box2D, Settings, Assert, nc, Matrix, RubeDollJson) {
"use strict";
function RubeDoll(physicsEngine, uid, options) {
Assert.number(options.x, options.y);
this.rubeLoader = null;
this.body = null;
this.limbs = {};
this.joints = null;
this.limits = [];
var chest = null;
this.rubeLoader = new RubeLoader(RubeDollJson, physicsEngine.getWorldForRubeLoader());
this.loadRubeDollFromScene(options);
Parent.call(this, physicsEngine, uid, options);
physicsEngine.destroyBody(this.body);
this.body = this.limbs.chest;
delete this.limbs.chest;
this.body.SetUserData(this);
this.flip(options.direction || 1);
}
RubeDoll.prototype = Object.create(Parent.prototype);
RubeDoll.prototype.loadRubeDollFromScene = function(options) {
var scene = this.rubeLoader.getScene();
for (var i in scene.bodies) {
var body = scene.bodies[i];
var position = body.GetPosition().Copy();
position.Add(new Box2D.Common.Math.b2Vec2(
options.x / Settings.RATIO,
options.y / Settings.RATIO
));
body.SetPosition(position);
this.limbs[body.name] = body;
// code snipped possibly needed for filtering between doll and rubedoll while holding
//var filterData = new Box2D.Dynamics.b2FilterData();
//filterData.groupIndex = -66;
//if(body.name != "head" && body.name != "chest") {
// for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) {
// fixture.SetFilterData(filterData);
// }
//}
}
this.joints = scene.joints;
var count = 0;
for (var i in this.joints) {
this.limits[i] = {
lower: this.joints[i].GetLowerLimit(),
upper: this.joints[i].GetUpperLimit(),
};
/*
this.joints[i].EnableLimit(false);
if(count < 4 && this.joints[i] instanceof Box2D.Dynamics.Joints.b2RevoluteJoint) {
console.log(i);
} else {
body.GetWorld().DestroyJoint(this.joints[i]);
}
count++;
*/
}
};
RubeDoll.prototype.getFixtureDef = function() {
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
fixtureDef.shape = new Box2D.Collision.Shapes.b2CircleShape();
return fixtureDef;
};
RubeDoll.prototype.flip = function(direction) {
var oldFlipDirection = this.flipDirection;
Parent.prototype.flip.call(this, direction);
if(oldFlipDirection != direction) {
for (var i in this.joints) {
var joint = this.joints[i];
var limits = this.limits[i];
if (joint instanceof Box2D.Dynamics.Joints.b2RevoluteJoint) {
if (direction > 0) {
joint.SetLimits(limits.lower, limits.upper);
continue;
}
var a1 = limits.lower * -1;
var a2 = limits.upper * -1;
if (a2 > a1) {
joint.SetLimits(a1, a2);
} else {
joint.SetLimits(a2, a1);
}
// joint.SetAngle(joint.GetAngle() * -1);
}
}
}
};
RubeDoll.prototype.reposition = function(handPosition, direction) {
var oldPosition = this.getPosition();
var oldAngle = this.body.GetAngle();
var oldDirection = this.flipDirection;
// calls flip() at the end of Parent reposition()
Parent.prototype.reposition.call(this, handPosition, direction);
var differenceAngle = oldAngle - this.body.GetAngle();
//this.body.SetLinearVelocity(new Box2D.Common.Math.b2Vec2(0, 0));
var offset = Box2D.Common.Math.b2Math.SubtractVV(this.getPosition(), oldPosition);
var grabAngle = (this.options.grabAngle || 0.001);
for(var key in this.limbs) {
var limb = this.limbs[key];
// Setting position offset first (floor to hand)
var position = limb.GetPosition().Copy();
position.Add(offset);
limb.SetPosition(position);
// grabing local point to "rotate" around (x, y position transform only)
var localPoint = this.body.GetLocalPoint(limb.GetPosition().Copy());
// create rotation matrix from chest rotation difference
var mat = Box2D.Common.Math.b2Mat22.FromAngle(differenceAngle);
// matrix multiplication with local limb position
position = Box2D.Common.Math.b2Math.MulTMV(mat, localPoint);
// translating back to global position
var globalPoint = this.body.GetWorldPoint(position);
limb.SetPosition(globalPoint);
// relative limb rotating by chest rotation difference
var d = (oldDirection == direction) ? -1 : 1;
limb.SetAngle((limb.GetAngle() - differenceAngle) * d);
//limb.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
//limb.SetLinearVelocity(new Box2D.Common.Math.b2Vec2(0, 0));
}
};
RubeDoll.prototype.setVelocities = function(options) {
Assert.number(options.linearVelocity.x, options.linearVelocity.y);
Assert.number(options.angularVelocity);
this.body.SetLinearVelocity(options.linearVelocity);
this.body.SetAngularVelocity(options.angularVelocity);
for(var name in this.limbs) {
this.limbs[name].SetLinearVelocity(options.linearVelocity);
}
};
RubeDoll.prototype.getPosition = function() {
return this.body.GetPosition().Copy();
};
RubeDoll.prototype.getHeadPosition = function() {
return this.limbs.head.GetPosition().Copy();
};
RubeDoll.prototype.setUpdateData = function(update) {
Parent.prototype.setUpdateData.call(this, update);
/*
for(var name in update.limbs) {
Assert.number(update.limbs[name].p.x, update.limbs[name].p.y);
Assert.number(update.limbs[name].a);
Assert.number(update.limbs[name].lv.x, update.limbs[name].lv.y);
Assert.number(update.limbs[name].av);
this.limbs[name].SetAwake(true);
this.limbs[name].SetPosition(update.limbs[name].p);
this.limbs[name].SetAngle(update.limbs[name].a);
this.limbs[name].SetLinearVelocity(update.limbs[name].lv);
this.limbs[name].SetAngularVelocity(update.limbs[name].av);
}
*/
}
RubeDoll.prototype.destroy = function() {
var world = this.body.GetWorld();
for (var name in this.limbs) {
world.DestroyBody(this.limbs[name]);
}
Parent.prototype.destroy.call(this);
};
return RubeDoll;
});

View file

@ -1,103 +1,10 @@
define([ define([
"Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Game/Config/Settings", "Game/Config/Settings"
"Lib/Utilities/Assert"
], ],
function (Parent, Box2D, Settings, Assert) { function (Parent, Box2D, Settings) {
"use strict";
function Skateboard(physicsEngine, uid, options) {
Parent.call(this, physicsEngine, uid, options);
}
Skateboard.prototype = Object.create(Parent.prototype);
Skateboard.prototype.createFixture = function () {
Assert.number(this.options.width, this.options.height);
Assert.number(this.options.weight);
var deckShape = new Box2D.Collision.Shapes.b2PolygonShape();
var w = this.options.width / Settings.RATIO;
var h = 2 / Settings.RATIO;
deckShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(4.5 / Settings.RATIO)));
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
fixtureDef.shape = deckShape;
var offset = 4,
factor = 80;
var density = ((this.options.weight + offset) / this.options.width / this.options.height) * factor;
fixtureDef.density = density;
fixtureDef.friction = Settings.ITEM_FRICTION;
fixtureDef.restitution = 0.2;
fixtureDef.isSensor = false;
this.body.CreateFixture(fixtureDef);
this.addWheel(
-8,
-2.5
);
this.addWheel(
7,
-2.5
);
};
Skateboard.prototype.addWheel = function(x, y) {
Assert.number(x, y);
var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
bodyDef.position.x = x / Settings.RATIO;
bodyDef.position.y = y / Settings.RATIO;
bodyDef.angle = 0;
var wheelShape = new Box2D.Collision.Shapes.b2CircleShape();
wheelShape.SetRadius(2.5 / Settings.RATIO);
wheelShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO));
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
var offset = 4,
factor = 80;
var density = ((0.1 + offset) / 3 / 3) * factor;
fixtureDef.density = density;
fixtureDef.shape = wheelShape;
fixtureDef.restitution = 0.2;
fixtureDef.isSensor = false;
fixtureDef.friction = 0.0005;
this.body.CreateFixture(fixtureDef);
};
Skateboard.prototype.flip = function(direction) {
this.flipDirection = direction;
};
return Skateboard;
});
/*
define([
"Game/" + GLOBALS.context + "/GameObjects/Item",
"Lib/Vendor/Box2D",
"Game/Config/Settings",
"Lib/Utilities/Assert"
],
function (Parent, Box2D, Settings, Assert) {
"use strict";
function Skateboard(physicsEngine, uid, options) { function Skateboard(physicsEngine, uid, options) {
@ -118,8 +25,6 @@ function (Parent, Box2D, Settings, Assert) {
Skateboard.prototype = Object.create(Parent.prototype); Skateboard.prototype = Object.create(Parent.prototype);
Skateboard.prototype.createFixture = function () { Skateboard.prototype.createFixture = function () {
Assert.number(this.options.width, this.options.height);
Assert.number(this.options.weight);
var deckShape = new Box2D.Collision.Shapes.b2PolygonShape(); var deckShape = new Box2D.Collision.Shapes.b2PolygonShape();
var w = this.options.width / Settings.RATIO; var w = this.options.width / Settings.RATIO;
@ -138,10 +43,9 @@ function (Parent, Box2D, Settings, Assert) {
fixtureDef.isSensor = false; fixtureDef.isSensor = false;
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
}; }
Skateboard.prototype.addWheel = function(x, y) { Skateboard.prototype.addWheel = function(x, y) {
Assert.number(x, y);
var bodyDef = new Box2D.Dynamics.b2BodyDef(); var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
@ -160,20 +64,15 @@ function (Parent, Box2D, Settings, Assert) {
fixtureDef.density = density; fixtureDef.density = density;
fixtureDef.shape = wheelShape; fixtureDef.shape = wheelShape;
fixtureDef.isSensor = false; fixtureDef.isSensor = false;
fixtureDef.friction = 0;
var wheelBody = this.body.GetWorld().CreateBody(bodyDef); var wheelBody = this.body.GetWorld().CreateBody(bodyDef);
wheelBody.CreateFixture(fixtureDef); wheelBody.CreateFixture(fixtureDef);
//var revoluteJointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef(); var revoluteJointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef();
var revoluteJointDef = new Box2D.Dynamics.Joints.b2WeldJointDef(); revoluteJointDef.enableMotor = false;
//revoluteJointDef.enableMotor = false;
revoluteJointDef.Initialize(this.body, wheelBody, wheelBody.GetWorldCenter()); revoluteJointDef.Initialize(this.body, wheelBody, wheelBody.GetWorldCenter());
var j = this.body.GetWorld().CreateJoint(revoluteJointDef); this.body.GetWorld().CreateJoint(revoluteJointDef);
// FIXME this means, that we will have bodies in the world, which must not be // FIXME this means, that we will have bodies in the world, which must not be
// updated (wheels) because they are always connected to a body which will be updated. // updated (wheels) because they are always connected to a body which will be updated.
@ -186,13 +85,18 @@ function (Parent, Box2D, Settings, Assert) {
// FIXME: implement body flip if necessary // FIXME: implement body flip if necessary
}; };
Skateboard.prototype.throw = function(options, carrierVelocity) { Skateboard.prototype.throw = function(x, y) {
Parent.prototype.throw.call(this, options, carrierVelocity); Parent.prototype.throw.call(this, x, y);
for (var i = 0; i < this.wheels.length; i++) { for (var i = 0; i < this.wheels.length; i++) {
var body = this.wheels[i]; var body = this.wheels[i];
body.SetAwake(true);
this.accelerateBody(body, options, carrierVelocity); var vector = new Box2D.Common.Math.b2Vec2(
x * Settings.MAX_THROW_FORCE / this.options.weight,
-y * Settings.MAX_THROW_FORCE / this.options.weight
);
body.SetLinearVelocity(vector);
} }
}; };
@ -207,4 +111,3 @@ function (Parent, Box2D, Settings, Assert) {
return Skateboard; return Skateboard;
}); });
*/

View file

@ -5,10 +5,8 @@ define([
function (Parent, Box2D) { function (Parent, Box2D) {
"use strict";
function SpectatorDoll(physicsEngine, uid, player) { function SpectatorDoll(physicsEngine, uid, player) {
//Parent.call(this, physicsEngine, uid); Parent.call(this, physicsEngine, uid);
} }
SpectatorDoll.prototype = Object.create(Parent.prototype); SpectatorDoll.prototype = Object.create(Parent.prototype);
@ -34,9 +32,6 @@ function (Parent, Box2D) {
SpectatorDoll.prototype.update = function() { SpectatorDoll.prototype.update = function() {
}; };
SpectatorDoll.prototype.destroy = function() {
};
return SpectatorDoll; return SpectatorDoll;
}); });

View file

@ -3,25 +3,22 @@ define([
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/Exception", "Lib/Utilities/Exception",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter"
"Lib/Utilities/Assert"
], ],
function (Parent, Box2D, Settings, Exception, nc, Assert) { function (Parent, Box2D, Settings, Exception, Nc) {
"use strict";
function Tile(physicsEngine, uid, options) { function Tile(physicsEngine, uid, options) {
this.options = options; this.options = options;
Parent.call(this, physicsEngine, uid); Parent.call(this, physicsEngine, uid);
this.createPhysicTile(this.options); this.createPhysicTile(this.options);
Nc.trigger(Nc.ns.core.game.gameObject.add, 'fixed', this);
} }
Tile.prototype = Object.create(Parent.prototype); Tile.prototype = Object.create(Parent.prototype);
Tile.prototype.getBodyDef = function() { Tile.prototype.getBodyDef = function() {
Assert.number(this.options.x, this.options.y);
Assert.number(this.options.r);
var bodyDef = new Box2D.Dynamics.b2BodyDef(); var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody; bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody;
@ -30,7 +27,7 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) {
bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180; bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180;
return bodyDef; return bodyDef;
}; }
Tile.prototype.createPhysicTile = function (tile) { Tile.prototype.createPhysicTile = function (tile) {
var vertices = this.createVertices(tile); var vertices = this.createVertices(tile);
@ -44,7 +41,7 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) {
fixtureDef.restitution = Settings.TILE_RESTITUTION; fixtureDef.restitution = Settings.TILE_RESTITUTION;
fixtureDef.isSensor = false; fixtureDef.isSensor = false;
this.body.CreateFixture(fixtureDef); this.body.CreateFixture(fixtureDef);
}; }
Tile.prototype.createVertices = function (tile) { Tile.prototype.createVertices = function (tile) {
var vs = []; var vs = [];
@ -105,17 +102,22 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) {
default: default:
throw new Exception("Tile Creation - no shape given"); throw new Exception("Tile Creation - no shape given");
break;
} }
return vs; return vs;
}; }
Tile.prototype.mkArg = function (multiplier) { Tile.prototype.mkArg = function (multiplier) {
return Settings.TILE_SIZE / 2 / Settings.RATIO * multiplier; return Settings.TILE_SIZE / 2 / Settings.RATIO * multiplier;
}; }
Tile.prototype.addVec = function (vs, m1, m2) { Tile.prototype.addVec = function (vs, m1, m2) {
return vs.push(new Box2D.Common.Math.b2Vec2(this.mkArg(m1), this.mkArg(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; return Tile;

View file

@ -2,17 +2,14 @@ define([
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Lib/Utilities/Abstract",
"Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/Collision/Detector",
"Game/" + GLOBALS.context + "/GameObjects/Tile", "Game/" + GLOBALS.context + "/GameObjects/Tile",
"Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Item",
"Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard", "Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard",
"Game/" + GLOBALS.context + "/GameObjects/Items/RagDoll", "Game/" + GLOBALS.context + "/GameObjects/Items/RagDoll",
"Game/" + GLOBALS.context + "/GameObjects/Items/RubeDoll" "Game/" + GLOBALS.context + "/GameObjects/Items/Rube"
], function (Settings, Box2D, nc, Abstract, CollisionDetector, Tile, Item, Skateboard, RagDoll, RubeDoll) { ], function (Settings, Box2D, Nc, CollisionDetector, Tile, Item, Skateboard, RagDoll, Rube) {
"use strict";
function Level (uid, engine) { function Level (uid, engine) {
this.uid = uid; this.uid = uid;
@ -20,83 +17,87 @@ define([
this.levelObject = null; this.levelObject = null;
this.isLoaded = false; this.isLoaded = false;
this.load(this.uid); this.load(this.uid);
this.spawnPoints = null;
} }
Level.prototype.load = function (uid) { Level.prototype.load = function (uid) {
var self = this; var self = this;
// FIXME: check if theres a security hazard here (user injected path) var path = Settings.MAPS_PATH + uid + ".json"
var path = Settings.MAPS_PATH + uid + ".json"; this.loadLevelDataFromPath(path, function(levelData) {
this.loadLevelDataFromPath(path, function (levelData) { self.levelData = levelData;
self.setup(levelData); self.createTiles();
self.createItems();
self.isLoaded = true;
Nc.trigger(Nc.ns.core.game.events.level.loaded);
}); });
};
Level.prototype.setup = function(levelData) { // jshint unused:false
this.isLoaded = true;
nc.trigger(nc.ns.core.game.events.level.loaded);
};
Level.prototype.createItems = function(options) {
for (var i = 0; i < options.length; i++) {
var uid = "item-" + i;
this.createItem(uid, options[i]);
} }
};
Level.prototype.createItem = function(uid, options) { Level.prototype.createItem = function(uid, options) {
switch(options.type) { switch(options.type) {
case "skateboard": case 'skateboard':
return new Skateboard(this.engine, uid, options); return new Skateboard(this.engine, uid, options);
case "ragdoll": case 'ragdoll':
return new RagDoll(this.engine, uid, options); return new RagDoll(this.engine, uid, options);
case "rubedoll": case 'rube':
return new RubeDoll(this.engine, uid, options); return new Rube(this.engine, uid, options);
default: default:
return new Item(this.engine, uid, options); return new Item(this.engine, uid, options);
} }
}; };
Level.prototype.createTiles = function(options) {
for (var i = 0; i < options.length; i++) {
new Tile(this.engine, "tile-" + i, options[i]);
}
};
Level.prototype.createSpawnPoints = function(points) {
this.spawnPoints = points;
};
Level.prototype.setupLayer = function(options, behind, referenceId) { // jshint unused:false
// will be extended (so far only in client)
};
Level.prototype.createContainer = function(options) { // jshint unused:false
// nothing to do here yet, in the future perhaps synchronize day/night graphics
};
Level.prototype.getRandomSpawnPoint = function() { Level.prototype.getRandomSpawnPoint = function() {
if(!this.spawnPoints) { throw new Error("Level not loaded.");
return { return {
x: 150 + Math.random() * 300, x: 150 + Math.random() * 300,
y: -500 y: -500
}; };
}
var size = this.spawnPoints.length;
var object = this.spawnPoints[parseInt(Math.random() * (size -1), 10)];
return {
x: object.x / Settings.TILE_RATIO,
y: object.y / Settings.TILE_RATIO
};
}; };
Level.prototype.destroy = function () { Level.prototype.destroy = function () {
/*
for (var key in this.gameObjects) {
for (var i = 0; i < this.gameObjects[key].length; i++) {
this.gameObjects[key][i].destroy();
}
}
*/
this.isLoaded = false; this.isLoaded = false;
}
/* Extended by TiledLevel
Level.prototype.createTiles = function () {
if (!this.levelData || !this.levelData.tiles || this.levelData.tiles.length < 1) {
throw "Level: Can't create physic tiles, no tiles found";
}
var tiles = this.levelData.tiles;
for (var i = 0; i < tiles.length; i++) {
var options = tiles[i];
//options.m = this.tileAtPositionExists(options.x, options.y - 1) ? "Soil" : "GrassSoil";
options.m = "Soil";
//this.gameObjects.fixed.push(
new Tile(this.engine, "tile-" + i, options);
//);
}
}
*/
/* Extended by TiledLevel
Level.prototype.createItems = function() {
if (!this.levelData || !this.levelData.items) {
return;
}
var items = this.levelData.items;
for (var i = 0; i < items.length; i++) {
var options = items[i];
var uid = "item-" + i;
var item = this.createItem(uid, options);
//this.gameObjects.animated.push(item);
}; };
};
*/
return Level; return Level;
}); })

View file

@ -3,191 +3,115 @@ define([
"Game/Config/Settings", "Game/Config/Settings",
"Game/Config/ItemSettings", "Game/Config/ItemSettings",
"Lib/Vendor/Box2D", "Lib/Vendor/Box2D",
"Lib/Utilities/OptionsHelper", "Lib/Utilities/Options",
"Lib/Utilities/Exception", "Lib/Utilities/Exception",
"Lib/Utilities/NotificationCenter",
"Lib/Utilities/Assert",
"Game/Client/View/Abstract/Layer",
"Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/Collision/Detector",
"Game/" + GLOBALS.context + "/GameObjects/Tile", "Game/" + GLOBALS.context + "/GameObjects/Tile",
"Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Item",
"Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard", "Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard",
], function (Parent, Settings, ItemSettings, Box2D, optionsHelper, Exception, nc, Assert, AbstractLayer, CollisionDetector, Tile, Item, Skateboard) { ], function (Parent, Settings, ItemSettings, Box2D, Options, Exception, CollisionDetector, Tile, Item, Skateboard) {
"use strict";
// Public
function TiledLevel (path, engine) { function TiledLevel (path, engine) {
this.layerMapping = {
tiles: this.createTiles.bind(this),
items: this.createItems.bind(this),
spawnpoints: this.createSpawnPoints.bind(this)
//collision: this.createTiles.bind(this), collision renamed to tiles
};
this.levelData = null; this.levelData = null;
Parent.call(this, path, engine); Parent.call(this, path, engine);
} }
TiledLevel.prototype = Object.create(Parent.prototype); TiledLevel.prototype = Object.create(Parent.prototype);
TiledLevel.prototype.createTiles = function () {
TiledLevel.prototype.setup = function(levelData) { if (!this.levelData) {
this.levelData = levelData; throw "Level: Can't create level, nothing found";
var spawnpointsExists = levelData.layers.some(function(o) {
return o.name == AbstractLayer.ID.SPAWN;
});
if (!spawnpointsExists) {
console.warn("No layerMapping for level file layer: " + layerOptions.name);
return;
} }
function getLayerId(name, i) { var collisionLayer = this.getLayer(this.levelData, "collision");
var mapping = {
tiles: AbstractLayer.ID.TILE,
items: AbstractLayer.ID.ITEM,
spawnpoints: AbstractLayer.ID.SPAWN
};
if(mapping[name]) {
return mapping[name];
}
return "layer-" + i + "-" + name; if(collisionLayer) {
}
var spawnpointsFound = false, for (var i = 0; i < collisionLayer.data.length; i++) {
lastLayerId = null;
// from spawnpoints to background var gid = collisionLayer.data[i];
for (var i = levelData.layers.length - 1; i >= 0; i--) {
var layerOptions = levelData.layers[i];
layerOptions.z = i;
layerOptions.layerId = getLayerId(layerOptions.name, i);
if (layerOptions.name == AbstractLayer.ID.SPAWN) {
spawnpointsFound = true;
}
if (!spawnpointsFound) {
continue;
}
// Setting up spawnpoints and then all layers behind it
this.setupLayer(layerOptions, true, lastLayerId);
if(this.layerMapping[layerOptions.name]) {
this.layerMapping[layerOptions.name](layerOptions);
}
lastLayerId = layerOptions.layerId;
}
spawnpointsFound = false; // reset (used in mkLayer)
lastLayerId = AbstractLayer.ID.SPAWN;
// from spawnpoints to foreground
for (var i = 0; i < levelData.layers.length; i++) {
var layerOptions = levelData.layers[i];
layerOptions.z = i;
layerOptions.layerId = getLayerId(layerOptions.name, i);
if (layerOptions.name == AbstractLayer.ID.SPAWN) {
spawnpointsFound = true;
continue;
}
if (!spawnpointsFound) {
continue;
}
// Setting up all layers before
this.setupLayer(layerOptions, false, lastLayerId);
if(this.layerMapping[layerOptions.name]) {
this.layerMapping[layerOptions.name](layerOptions);
}
lastLayerId = layerOptions.layerId;
}
Parent.prototype.setup.call(this, levelData);
};
TiledLevel.prototype.createTiles = function(options) {
var data = options.data;
var tilesOptions = [];
for (var i = 0; i < data.length; i++) {
var gid = data[i];
if(gid === 0) continue; if(gid === 0) continue;
var imagePath = this.getTileImagePath(gid); var imagePath = this.getTileImagePath(gid);
var parts = imagePath.split("/"); var parts = imagePath.split("/");
var tileType = parts[parts.length - 1].split(".")[0].split(""); var tileType = parts[parts.length - 1].split(".")[0].split("");
// FIXME rename s to shape, r to rotation etc. // FIXME rename s to shape, r to rotation etc.
var tileOptions = { var options = {
s: parseInt(tileType[0], 10), s: parseInt(tileType[0], 10),
r: parseInt(tileType[1], 10), r: parseInt(tileType[1], 10),
t: imagePath, t: imagePath,
x: i % options.width, x: i % collisionLayer.width,
y: parseInt(i / options.width , 10) y: parseInt(i / collisionLayer.height , 10)
};
tilesOptions.push(tileOptions);
} }
Parent.prototype.createTiles.call(this, tilesOptions); //this.gameObjects.fixed.push(
}; new Tile(this.engine, "tile-" + i, options);
//);
}
} else {
console.warn("Level: No collision Layer given");
}
}
TiledLevel.prototype.createItems = function() {
var objects = this.getLayer(this.levelData, "items").objects;
TiledLevel.prototype.createItems = function(options) {
var objects = options.objects;
var itemsOptions = [];
for (var i = 0; i < objects.length; i++) { for (var i = 0; i < objects.length; i++) {
options = this.gatherOptions(objects[i]); var object = objects[i];
itemsOptions.push(options);
}
Parent.prototype.createItems.call(this, itemsOptions); var options = this.gatherOptions(object);
var uid = "item-" + i;
var item = this.createItem(uid, options);
//this.gameObjects.animated.push(item);
}; };
TiledLevel.prototype.createSpawnPoints = function(options) {
var points = options.objects.map(function(o) {
return { x: o.x, y: o.y };
});
Parent.prototype.createSpawnPoints.call(this, points);
}; };
TiledLevel.prototype.gatherOptions = function(tiledObject) { TiledLevel.prototype.gatherOptions = function(tiledObject) {
var options = this.getDefaultItemSettingsByName(tiledObject.name); var options = {};
options.name = tiledObject.name; options.name = tiledObject.name;
options.x = (tiledObject.x + options.width / 2) / Settings.TILE_RATIO; options.rotation = tiledObject.rotation;
options.width = tiledObject.width / Settings.TILE_RATIO;
options.height = tiledObject.height / Settings.TILE_RATIO;
options.x = (tiledObject.x + tiledObject.width / 2) / Settings.TILE_RATIO;
options.y = (tiledObject.y + options.height / 2) / Settings.TILE_RATIO; options.y = (tiledObject.y + options.height / 2) / Settings.TILE_RATIO;
// FIXME: check RAD vs. DEG for options.rotation = tiledObject.rotation;
if (!options.width) options.width = undefined;
if (!options.height) options.height = undefined;
var defaultOptions = this.getDefaultItemSettingsByName(options.name);
options = Options.merge(options, defaultOptions);
//options = Options.merge(tiledObject.properties, options);
return options; return options;
}; };
TiledLevel.prototype.getDefaultItemSettingsByName = function(name) { TiledLevel.prototype.getDefaultItemSettingsByName = function(name) {
if(!name) { if(!name) {
throw new Exception("Item name cannot be be empty"); throw new Exception('Item name cannot be be empty');
} }
if(ItemSettings[name] === undefined) { if(ItemSettings[name] === undefined) {
throw new Exception("Item name (" + name + ") cannot be found in item list"); throw new Exception('Item name (' + name + ') cannot be found in item list');
} }
return optionsHelper.merge(ItemSettings[name], ItemSettings.Default); var options = ItemSettings.Default;
options = Options.merge(ItemSettings[name], options);
return options;
}; };
TiledLevel.prototype.getTileImagePath = function(gid) { TiledLevel.prototype.getTileImagePath = function(gid) {
@ -198,7 +122,35 @@ define([
return tileset.tiles["" + (gid - offset)].image; return tileset.tiles["" + (gid - offset)].image;
} }
} }
}
TiledLevel.prototype.getRandomSpawnPoint = function() {
if(!this.levelData) {
return Parent.prototype.getRandomSpawnPoint.call(this);
} else {
var spawnLayer = this.getLayer(this.levelData, "spawnpoints");
var size = spawnLayer.objects.length;
var object = spawnLayer.objects[parseInt(Math.random() * (size -1), 10)];
return {
x: object.x / Settings.TILE_RATIO,
y: object.y / Settings.TILE_RATIO
}
}
};
TiledLevel.prototype.getLayer = function(levelData, name) {
for (var i = 0; i < levelData.layers.length; i++) {
if(levelData.layers[i].name === name) {
return levelData.layers[i];
}
}
throw "Layer '" + name + "' not found.";
}; };
return TiledLevel; return TiledLevel;
}); })

View file

@ -5,9 +5,7 @@ define([
"Lib/Utilities/NotificationCenter" "Lib/Utilities/NotificationCenter"
], ],
function (Settings, Box2D, CollisionDetector, nc) { function (Settings, Box2D, CollisionDetector, Nc) {
"use strict";
function Engine () { function Engine () {
this.world = new Box2D.Dynamics.b2World( this.world = new Box2D.Dynamics.b2World(
@ -15,30 +13,33 @@ function (Settings, Box2D, CollisionDetector, nc) {
Settings.BOX2D_ALLOW_SLEEP Settings.BOX2D_ALLOW_SLEEP
); );
this.world.SetWarmStarting(true); this.world.SetWarmStarting(true);
this.ground = null;
this.lastStep = Date.now(); this.lastStep = Date.now();
this.worldQueue = []; this.worldQueue = [];
this.ncTokens = [ this.ncTokens = [
nc.on(nc.ns.channel.engine.worldQueue.add, this.addToWorldQueue, this) Nc.on(Nc.ns.channel.engine.worldQueue.add, this.addToWorldQueue, this)
]; ];
} }
Engine.prototype.getWorld = function () {
return this.world;
}
Engine.prototype.getGround = function () {
return this.ground;
}
Engine.prototype.setCollisionDetector = function () { Engine.prototype.setCollisionDetector = function () {
var detector = new CollisionDetector(); var detector = new CollisionDetector();
this.world.SetContactListener(detector.getListener()); this.world.SetContactListener(detector.getListener());
} }
Engine.prototype.getWorldForRubeLoader = function() {
return this.world;
};
Engine.prototype.createBody = function (bodyDef) { Engine.prototype.createBody = function (bodyDef) {
return this.world.CreateBody(bodyDef); var body = this.world.CreateBody(bodyDef);
} if(!this.ground) this.ground = body;
return body;
Engine.prototype.destroyBody = function (body) {
return this.world.DestroyBody(body);
} }
Engine.prototype.addToWorldQueue = function(callback) { Engine.prototype.addToWorldQueue = function(callback) {
@ -62,8 +63,8 @@ function (Settings, Box2D, CollisionDetector, nc) {
} }
Engine.prototype.destroy = function() { Engine.prototype.destroy = function() {
nc.offAll(this.ncTokens);
delete this.world; delete this.world;
Nc.offAll(this.ncTokens);
}; };

View file

@ -1,19 +1,16 @@
define([ define([
"Game/" + GLOBALS.context + "/GameObjects/Doll", "Game/" + GLOBALS.context + "/GameObjects/Doll",
"Game/" + GLOBALS.context + "/Control/PlayerController",
"Game/Config/Settings", "Game/Config/Settings",
"Lib/Utilities/NotificationCenter", "Lib/Utilities/NotificationCenter",
"Lib/Utilities/Exception", "Lib/Utilities/Exception",
"Lib/Utilities/ColorConverter",
"Game/" + GLOBALS.context + "/GameObjects/SpectatorDoll", "Game/" + GLOBALS.context + "/GameObjects/SpectatorDoll",
"Game/" + GLOBALS.context + "/GameObjects/Items/RubeDoll" "Game/" + GLOBALS.context + "/GameObjects/Items/RagDoll"
], ],
function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, SpectatorDoll, RubeDoll) {
"use strict"; function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) {
function Player (id, physicsEngine, user, revealedGameController) { function Player (id, physicsEngine, user) {
this.stats = { this.stats = {
health: 100, health: 100,
deaths: 0, deaths: 0,
@ -22,23 +19,18 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
this.user = user; this.user = user;
this.physicsEngine = physicsEngine; this.physicsEngine = physicsEngine;
this.playerController = null; // pre-initialise with null, because client/players don't get one this.playerController = null;
this.doll; this.doll;
this.id = id; this.id = id;
this.spawned = false; this.isSpawned = false;
this.holdingItem = null; this.holdingItem = null;
this.inBetweenRounds = true;
this.spectatorDoll = new SpectatorDoll(this.physicsEngine, "spectatorDoll-" + this.id, this); this.spectatorDoll = new SpectatorDoll(this.physicsEngine, "spectatorDoll-" + this.id, this);
this.revealedGameController = revealedGameController;
this.modifierActivated = false; Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this);
} }
Player.prototype.getNickname = function() {
return this.user.options.nickname;
};
Player.prototype.getActiveDoll = function() { Player.prototype.getActiveDoll = function() {
if(this.spawned) { if(this.isSpawned) {
return this.doll; return this.doll;
} else if (this.ragDoll) { } else if (this.ragDoll) {
return this.ragDoll; return this.ragDoll;
@ -49,13 +41,9 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
Player.prototype.spawn = function (x, y) { Player.prototype.spawn = function (x, y) {
this.doll = new Doll(this.physicsEngine, "doll-" + this.id, this); this.doll = new Doll(this.physicsEngine, "doll-" + this.id, this);
this.doll.spawn(x, y); this.doll.spawn(x, y);
this.spawned = true; this.isSpawned = true;
} }
Player.prototype.isSpawned = function() {
return this.spawned;
};
Player.prototype.getPosition = function () { Player.prototype.getPosition = function () {
return this.getActiveDoll().getPosition(); return this.getActiveDoll().getPosition();
} }
@ -66,73 +54,54 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
Player.prototype.move = function (direction) { Player.prototype.move = function (direction) {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.move(direction, this.modifierActivated); this.doll.move(direction);
} }
Player.prototype.stop = function () { Player.prototype.stop = function () {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.stop(); this.doll.stop();
} }
Player.prototype.jump = function () { Player.prototype.jump = function () {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.jump(); this.doll.jump();
} }
Player.prototype.jumpStop = function () { Player.prototype.jumpStop = function () {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.jumpStop(); this.doll.jumpStop();
} }
Player.prototype.lookAt = function (x, y) { Player.prototype.lookAt = function (x, y) {
if(!this.spawned) return false; if(!this.isSpawned) return false;
// FIXME implement spectator movement here // FIXME implement spectator movement here
this.doll.lookAt(x, y); this.doll.lookAt(x, y);
} }
Player.prototype.activateModifier = function () {
if(!this.spawned) return false;
this.modifierActivated = true;
}
Player.prototype.deactivateModifier = function () {
if(!this.spawned) return false;
this.modifierActivated = false;
}
Player.prototype.grab = function(item) { Player.prototype.grab = function(item) {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.grab(item); this.doll.grab(item);
item.beingGrabbed(this); item.beingGrabbed(this);
this.holdingItem = item; this.holdingItem = item;
}; };
Player.prototype.throw = function(options, item) { Player.prototype.throw = function(x, y, item) {
if(!this.spawned) return false; if(!this.isSpawned) return false;
this.doll.throw(item, options); this.doll.throw(item, x, y);
item.beingReleased(this); item.beingReleased(this);
this.holdingItem = null; this.holdingItem = null;
}; };
Player.prototype.kill = function(killedByPlayer, ragDollId) { Player.prototype.kill = function(killedByPlayer, ragDollId) {
if(!this.spawned) return false; if(!this.isSpawned) return false;
// FIXME: do something better then just respawn in GameController // FIXME: do something better then just respawn in GameController
if(this.holdingItem) { if(this.holdingItem) {
var options = { this.throw(0, 0, this.holdingItem)
x: 0,
y: 0,
av: 0
};
this.throw(options, this.holdingItem)
} }
// prepare for creating the ragdoll // prepare for creating the ragdoll
var converter = new ColorConverter();
var primaryColor = converter.getColorByName(this.getNickname());
var options = { var options = {
x: this.getPosition().x * Settings.RATIO, x: this.getPosition().x * Settings.RATIO,
y: this.getPosition().y * Settings.RATIO, y: this.getPosition().y * Settings.RATIO,
@ -141,23 +110,21 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
image: "chest.png", image: "chest.png",
name: "RagDoll", name: "RagDoll",
rotation: 0, rotation: 0,
type: "rubedoll", type: "ragdoll",
weight: 3, weight: 3,
width: 5, width: 5,
height: 12, height: 12
primaryColor: primaryColor,
direction: this.doll.lookDirection
}; };
var rubeDoll = new RubeDoll(this.physicsEngine, "rubeDoll-" + this.id + "-" + ragDollId, options); var ragDoll = new RagDoll(this.physicsEngine, "ragDoll-" + this.id + "-" + ragDollId, options);
rubeDoll.setVelocities(this.doll.getVelocities()); ragDoll.setVelocities(this.doll.getVelocities());
this.spawned = false; this.isSpawned = false;
this.doll.destroy(); this.doll.destroy();
this.doll = null; this.doll = null;
this.ragDoll = rubeDoll; this.ragDoll = ragDoll;
}; };
Player.prototype.update = function () { Player.prototype.update = function () {
@ -173,21 +140,14 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
Player.prototype.destroy = function () { Player.prototype.destroy = function () {
// FIXME add destroy nc hook Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this);
if(this.holdingItem) { if(this.holdingItem) {
var options = { this.throw(0, 0, this.holdingItem);
x: 0,
y: 0,
av: 0
};
this.throw(options, this.holdingItem);
} }
this.spectatorDoll.destroy(); 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) { if(this.doll) {
this.doll.destroy(); this.doll.destroy();
} }
@ -197,13 +157,9 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect
} }
} }
Player.prototype.setInBetweenRounds = function(inBetweenRounds) { Player.prototype.setPlayerController = function(playerController) {
this.inBetweenRounds = inBetweenRounds; this.playerController = playerController;
}; }
Player.prototype.isInBetweenRounds = function() {
return this.inBetweenRounds;
};
return Player; return Player;
}); });

View file

@ -1,7 +1,4 @@
define([ define(function () {
],
function () {
function User (id, options) { function User (id, options) {
this.id = id; this.id = id;

View file

@ -1,20 +0,0 @@
define([
"Lib/Utilities/Exception"
],
function (Exception) {
"use strict";
function Abstract() {
}
Abstract.prototype.addMethod = function(methodName, params) {
this.prototype[methodName] = function() {
throw new Exception("Abstract method", this, methodName + "(" + params.join(', ') + ") not overwritten.");
}
}
return Abstract;
});

View file

@ -1,21 +0,0 @@
define([
"Lib/Utilities/Exception"
],
function (Exception) {
"use strict";
var Assert = {};
Assert.number = function() {
for (var i = 0; i < arguments.length; i++) {
if(isNaN(parseFloat(arguments[i]))) {
throw new Exception("Assert: not a number ", JSON.stringify(arguments));
}
}
};
return Assert;
});

View file

@ -1,22 +0,0 @@
define([
"Lib/Utilities/Core/Extensions"
],
function (Parent) {
//"use strict";
console.checkpoint = function (s) {
console.log(" \033[32mbeep - \033[0m" + s);
}
console.warn = function (s) {
console.log(" \033[33mwarn - \033[0m" + s);
}
console.error = function (s) {
console.log(" \033[31merror - \033[0m" + s);
}
});

View file

@ -1,8 +0,0 @@
define([
"Lib/Utilities/Core/Extensions"
],
function (Parent) {
"use strict";
});

View file

@ -1,83 +0,0 @@
define([
"Lib/Vendor/CryptoJS"
],
function (CryptoJS) {
"use strict";
function ColorConverter() {
this.sin = 0;
var palette = [
0x634c72,
0x724c5e,
0x787950,
0x507971,
0x506a79,
0x8c423c,
0x557e4a,
0x436785,
0xa62423,
0x427f87,
0x472e1a,
0x4d667c,
0x2a3c49,
0x7c7e2b,
0x3b3c21,
0x263c27,
0x7e897e,
0xb55014,
0x978c32,
0x739137,
0x46824f,
0x19b0b4,
0x1c1eb1,
0xccb206,
0x433e20,
0x201a13,
0x145396,
0x313d08,
0xb7a345,
0xdc168a,
0x310505,
0x051631,
];
/*
var element, color;
var start = 5;
var step = 4;
var max = 16;
for(var r=start; r<max; r+=step) {
for(var g=start; g<max; g+=step) {
for(var b=start; b<max; b+=step) {
color = r.toString(16)
+ r.toString(16)
+ g.toString(16)
+ g.toString(16)
+ b.toString(16)
+ b.toString(16);
palette.push(parseInt(color, 16));
}
}
}*/
this.palette = palette;
}
ColorConverter.prototype.getColorByName = function(name) {
name = CryptoJS.MD5(name).toString();
var ac = 0;
for(var c = 0; c < name.length; c++) {
ac += name.charCodeAt(c) * 3;
}
return this.palette[ac % this.palette.length];
}
return ColorConverter;
});

View file

@ -1,24 +0,0 @@
define([
],
function () {
"use strict";
String.prototype.toUpperCaseFirstChar = function () {
var f = this.charAt(0).toUpperCase();
return f + this.substr(1);
}
String.prototype.pad = function (max, alignLeft) {
var string = this.substring(0, max - 1);
var spaces = new Array( max - string.length + 1 ).join(" ");
if(alignLeft) {
return string + spaces;
} else {
return spaces + string;
}
}
});

View file

@ -17,8 +17,7 @@ function() {
this.message = message.join(" "); this.message = message.join(" ");
var e = Error.call(this, this.message); Error.call(this, this.message);
console.error(e.stack);
} }
Exception.prototype = Object.create(Error.prototype); Exception.prototype = Object.create(Error.prototype);

26
app/Lib/Utilities/Extensions.js Executable file
View file

@ -0,0 +1,26 @@
define([
],
function() {
String.prototype.toUpperCaseFirstChar = function () {
var f = this.charAt(0).toUpperCase();
return f + this.substr(1);
}
if(GLOBALS.context == "Channel") {
console.checkpoint = function (s) {
console.log(' \033[32mbeep - \033[0m' + s);
}
console.warn = function (s) {
console.log(' \033[33mwarn - \033[0m' + s);
}
console.error = function (s) {
console.log(' \033[31merror - \033[0m' + s);
}
}
});

View file

@ -1,334 +0,0 @@
define([
],
/*
Stolen from Pixi V2
*/
function () {
"use strict";
/**
* The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
*
* @class Point
* @constructor
* @param x {Number} position of the point on the x axis
* @param y {Number} position of the point on the y axis
*/
var Point = function(x, y)
{
/**
* @property x
* @type Number
* @default 0
*/
this.x = x || 0;
/**
* @property y
* @type Number
* @default 0
*/
this.y = y || 0;
};
/**
* Creates a clone of this point
*
* @method clone
* @return {Point} a copy of the point
*/
Point.prototype.clone = function()
{
return new Point(this.x, this.y);
};
/**
* Sets the point to a new x and y position.
* If y is omitted, both x and y will be set to x.
*
* @method set
* @param [x=0] {Number} position of the point on the x axis
* @param [y=0] {Number} position of the point on the y axis
*/
Point.prototype.set = function(x, y)
{
this.x = x || 0;
this.y = y || ( (y !== 0) ? this.x : 0 ) ;
};
// constructor
Point.prototype.constructor = Point;
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
/**
* The Matrix class is now an object, which makes it a lot faster,
* here is a representation of it :
* | a | b | tx|
* | c | d | ty|
* | 0 | 0 | 1 |
*
* @class Matrix
* @constructor
*/
var Matrix = function()
{
/**
* @property a
* @type Number
* @default 1
*/
this.a = 1;
/**
* @property b
* @type Number
* @default 0
*/
this.b = 0;
/**
* @property c
* @type Number
* @default 0
*/
this.c = 0;
/**
* @property d
* @type Number
* @default 1
*/
this.d = 1;
/**
* @property tx
* @type Number
* @default 0
*/
this.tx = 0;
/**
* @property ty
* @type Number
* @default 0
*/
this.ty = 0;
};
/**
* Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows:
*
* a = array[0]
* b = array[1]
* c = array[3]
* d = array[4]
* tx = array[2]
* ty = array[5]
*
* @method fromArray
* @param array {Array} The array that the matrix will be populated from.
*/
Matrix.prototype.fromArray = function(array)
{
this.a = array[0];
this.b = array[1];
this.c = array[3];
this.d = array[4];
this.tx = array[2];
this.ty = array[5];
};
/**
* Creates an array from the current Matrix object.
*
* @method toArray
* @param transpose {Boolean} Whether we need to transpose the matrix or not
* @return {Array} the newly created array which contains the matrix
*/
Matrix.prototype.toArray = function(transpose)
{
if(!this.array) this.array = new Float32Array(9);
var array = this.array;
if(transpose)
{
array[0] = this.a;
array[1] = this.b;
array[2] = 0;
array[3] = this.c;
array[4] = this.d;
array[5] = 0;
array[6] = this.tx;
array[7] = this.ty;
array[8] = 1;
}
else
{
array[0] = this.a;
array[1] = this.c;
array[2] = this.tx;
array[3] = this.b;
array[4] = this.d;
array[5] = this.ty;
array[6] = 0;
array[7] = 0;
array[8] = 1;
}
return array;
};
/**
* Get a new position with the current transformation applied.
* Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering)
*
* @method apply
* @param pos {Point} The origin
* @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input)
* @return {Point} The new point, transformed through this matrix
*/
Matrix.prototype.apply = function(pos, newPos)
{
newPos = newPos || new Point();
newPos.x = this.a * pos.x + this.c * pos.y + this.tx;
newPos.y = this.b * pos.x + this.d * pos.y + this.ty;
return newPos;
};
/**
* Get a new position with the inverse of the current transformation applied.
* Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input)
*
* @method applyInverse
* @param pos {Point} The origin
* @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input)
* @return {Point} The new point, inverse-transformed through this matrix
*/
Matrix.prototype.applyInverse = function(pos, newPos)
{
newPos = newPos || new Point();
var id = 1 / (this.a * this.d + this.c * -this.b);
newPos.x = this.d * id * pos.x + -this.c * id * pos.y + (this.ty * this.c - this.tx * this.d) * id;
newPos.y = this.a * id * pos.y + -this.b * id * pos.x + (-this.ty * this.a + this.tx * this.b) * id;
return newPos;
};
/**
* Translates the matrix on the x and y.
*
* @method translate
* @param {Number} x
* @param {Number} y
* @return {Matrix} This matrix. Good for chaining method calls.
**/
Matrix.prototype.translate = function(x, y)
{
this.tx += x;
this.ty += y;
return this;
};
/**
* Applies a scale transformation to the matrix.
*
* @method scale
* @param {Number} x The amount to scale horizontally
* @param {Number} y The amount to scale vertically
* @return {Matrix} This matrix. Good for chaining method calls.
**/
Matrix.prototype.scale = function(x, y)
{
this.a *= x;
this.d *= y;
this.c *= x;
this.b *= y;
this.tx *= x;
this.ty *= y;
return this;
};
/**
* Applies a rotation transformation to the matrix.
* @method rotate
* @param {Number} angle The angle in radians.
* @return {Matrix} This matrix. Good for chaining method calls.
**/
Matrix.prototype.rotate = function(angle)
{
var cos = Math.cos( angle );
var sin = Math.sin( angle );
var a1 = this.a;
var c1 = this.c;
var tx1 = this.tx;
this.a = a1 * cos-this.b * sin;
this.b = a1 * sin+this.b * cos;
this.c = c1 * cos-this.d * sin;
this.d = c1 * sin+this.d * cos;
this.tx = tx1 * cos - this.ty * sin;
this.ty = tx1 * sin + this.ty * cos;
return this;
};
/**
* Appends the given Matrix to this Matrix.
*
* @method append
* @param {Matrix} matrix
* @return {Matrix} This matrix. Good for chaining method calls.
*/
Matrix.prototype.append = function(matrix)
{
var a1 = this.a;
var b1 = this.b;
var c1 = this.c;
var d1 = this.d;
this.a = matrix.a * a1 + matrix.b * c1;
this.b = matrix.a * b1 + matrix.b * d1;
this.c = matrix.c * a1 + matrix.d * c1;
this.d = matrix.c * b1 + matrix.d * d1;
this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx;
this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty;
return this;
};
/**
* Resets this Matix to an identity (default) matrix.
*
* @method identity
* @return {Matrix} This matrix. Good for chaining method calls.
*/
Matrix.prototype.identity = function()
{
this.a = 1;
this.b = 0;
this.c = 0;
this.d = 1;
this.tx = 0;
this.ty = 0;
return this;
};
return Matrix;
});

View file

@ -4,10 +4,8 @@ define([
function (Exception) { function (Exception) {
"use strict";
function populate(obj, path) { function populate(obj, path) {
path = path || "nc.ns"; path = path || "Nc.ns";
for(var key in obj) { for(var key in obj) {
if(!obj.hasOwnProperty(key)) continue; if(!obj.hasOwnProperty(key)) continue;
if(obj[key] === null) { if(obj[key] === null) {
@ -23,56 +21,35 @@ function (Exception) {
this.topics = {}; this.topics = {};
this.subUid = -1; this.subUid = -1;
var i = 0;
this.ns = { this.ns = {
client: { client: {
pointerLock: {
request: null,
change: null
},
view: { view: {
layer: {
createAndInsert: null,
levelSizeUpdate: null
},
mesh: { mesh: {
create: null, create: null,
add: null, add: null,
remove: null, remove: null,
update: null, update: null
addFilter: null,
removeFilter: null,
swapMeshIndexes: null,
swapMeshes: null
}, },
animatedMesh: { animatedMesh: {
create: null create: null
}, },
healthBar: { playerInfo: {
createAndAdd: null, createAndAdd: null,
remove: null, remove: null,
update: null update: null
}, },
playerArrow: {
createAndAdd: null,
update: null
},
preloadBar: { preloadBar: {
update: null update: null
}, },
display: { fullscreen: {
change: null change: null
}, },
debugMode: { debugMode: {
toggle: null toggle: null
}, },
gameStats: { events: {
toggle: null, ready: null
kill: null,
update: null
},
swiper: {
swipe: null,
end: null
} }
}, },
input: { input: {
@ -84,16 +61,9 @@ function (Exception) {
} }
}, },
game: { game: {
events: { gameInfo: {
render: null,
destroy: null
},
gameStats: {
toggle: null toggle: null
}, }
zoomIn: null,
zoomOut: null,
zoomReset: null
}, },
to: { to: {
server: { server: {
@ -105,9 +75,9 @@ function (Exception) {
}, },
core: { core: {
game: { game: {
worldUpdateObjects: { gameObject: {
add: null, add: null,
remove: null, remove: null
}, },
events: { events: {
level: { level: {
@ -137,10 +107,8 @@ function (Exception) {
}, },
game: { game: {
player: { player: {
killed: null, killed: null
clearFingerPrints: null }
},
} }
}, },
engine: { engine: {
@ -194,20 +162,17 @@ function (Exception) {
}; };
populate(this.ns); populate(this.ns);
} }
NotificationCenter.prototype.validate = function(topic) { NotificationCenter.prototype.validate = function(topic) {
if (topic === undefined) {
throw new Exception("Topic not registered in nc. See stack trace.");
}
if (typeof topic === 'object') { if (typeof topic === 'object') {
throw new Exception("Topic bad format " + JSON.stringify(topic)); throw new Exception("Topic bad format " + JSON.stringify(topic));
} }
if (topic.indexOf("nc.ns") !== 0) { if (topic.indexOf("Nc.ns") !== 0) {
throw new Exception("Topic bad format, does not begin with nc.ns. : " + topic); throw new Exception("Topic bad format, does not begin with Nc.ns. : " + topic);
} }
}; };
@ -216,7 +181,7 @@ function (Exception) {
this.validate(topic); this.validate(topic);
if (!this.topics[topic]) { if (!this.topics[topic]) {
//console.warn("No such topic " + topic + ". Could not trigger. arguments: " + arguments.join); console.warn("No such topic " + topic + ". Could not trigger. arguments: " + arguments.join);
} }
var args = Array.prototype.slice.call(arguments, 1); var args = Array.prototype.slice.call(arguments, 1);
@ -249,24 +214,18 @@ function (Exception) {
NotificationCenter.prototype.off = function (token) { NotificationCenter.prototype.off = function (token) {
if(token && token.constructor === Array) {
this.offAll(token);
return;
}
for(var m in this.topics) { for(var m in this.topics) {
if (this.topics[m]) { if (this.topics[m]) {
for(var i = 0, j = this.topics[m].length; i < j; i++) { for(var i = 0, j = this.topics[m].length; i < j; i++) {
if (this.topics[m][i].token === token) { if (this.topics[m][i].token === token) {
this.topics[m].splice(i, 1); this.topics[m].splice(i, 1);
return; return token;
} }
} }
} }
} }
} }
// should be treated as a private function - use nc.off(Array);
NotificationCenter.prototype.offAll = function (tokens) { NotificationCenter.prototype.offAll = function (tokens) {
for (var i = 0; i < tokens.length; i++) { for (var i = 0; i < tokens.length; i++) {
this.off(tokens[i]); this.off(tokens[i]);

View file

@ -4,21 +4,18 @@ define([
function (Exception) { function (Exception) {
"use strict"; function Options() {
function OptionsHelper() {
} }
// FIXME we could actually use Object.assign() for merging here Options.prototype.merge = function(options, preset) {
OptionsHelper.prototype.merge = function(options, preset) {
if(!preset && !options) { if(!preset && !options) {
throw new Exception("OptionsHelper requires objects"); throw new Exception("Options requires objects");
} }
if(preset.constructor !== Object && options.constructor !== Object) { if(preset.constructor !== Object && options.constructor !== Object) {
throw new Exception("OptionsHelper requires objects"); throw new Exception("Options requires objects");
} }
if(!preset || preset.constructor !== Object) { if(!preset || preset.constructor !== Object) {
@ -44,7 +41,7 @@ function (Exception) {
if(options[key].constructor !== Object) { if(options[key].constructor !== Object) {
preset[key] = options[key]; preset[key] = options[key];
} else { } else {
preset[key] = OptionsHelper.prototype.merge.call(this, options[key], preset[key]); preset[key] = Options.prototype.merge.call(this, options[key], preset[key]);
} }
} }
} }
@ -52,6 +49,6 @@ function (Exception) {
return preset; return preset;
} }
return new OptionsHelper(); return new Options();
}); });

View file

@ -5,8 +5,6 @@ define([
function (Parser, Exception) { function (Parser, Exception) {
"use strict";
var Helper = {} var Helper = {}
Helper.encodeCommand = function (command, options) { Helper.encodeCommand = function (command, options) {

View file

@ -3,8 +3,6 @@ define([
function () { function () {
"use strict";
var Parser = {}; var Parser = {};
Parser.encode = function (message) { Parser.encode = function (message) {

Some files were not shown because too many files have changed in this diff Show more