implemented level load, more to do see #1

This commit is contained in:
Jeena 2014-01-29 03:24:08 +01:00
parent b02036a019
commit 953159e6bd
12 changed files with 333 additions and 409 deletions

View file

@ -1,9 +1,31 @@
define([
"Game/Core/Loader/Level"
"Game/Core/Loader/Level",
"Game/Config/Settings"
],
function(Parent) {
return Parent;
function (Parent, Settings) {
function Level (uid, engine, gameObjects) {
Parent.call(this, uid, engine, gameObjects);
}
Level.prototype = Object.create(Parent.prototype);
Level.prototype.loadLevelDataFromPath = function (path, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
callback(JSON.parse(xhr.responseText))
} else {
console.error("Ajax error: " + xhr.status + " " + xhr.statusText)
}
}
}
xhr.open("GET", path, true);
xhr.send(null);
}
return Level;
});

View file

@ -50,7 +50,7 @@ function (ProtocolHelper, GameController, User, NotificationCenter, Settings, Do
Networker.prototype.onJoinSuccess = function (options) {
this.gameController = new GameController();
this.gameController.loadLevel("default.json");
this.gameController.loadLevel(options.levelUid);
this.onUserJoined(options.userId);
this.gameController.onJoinMe(options.userId);

View file

@ -15,7 +15,7 @@ define({
GRAPHICS_SUBPATH_ITEMS: 'Items/',
GRAPHICS_SUBPATH_CHARACTERS: 'Characters/',
GRAPHICS_SUBPATH_TILES: 'Tiles/',
MAPS_PATH: 'static/maps/'
MAPS_PATH: 'static/maps/chuck/',
RATIO: 21, //35
TILE_SIZE: 15, //15, 25 is original picture

View file

@ -12,7 +12,6 @@ function (PhysicsEngine, Level, Player) {
animated: [],
fixed: []
};
this.levelPath = null;
this.physicsEngine = new PhysicsEngine();
this.physicsEngine.setCollisionDetector();
@ -28,8 +27,7 @@ function (PhysicsEngine, Level, Player) {
return this.physicsEngine;
}
GameController.prototype.loadLevel = function (path) {
this.levelPath = path;
GameController.prototype.loadLevel = function (levelUid) {
if (this.level) {
this.level.destroy();
@ -39,12 +37,11 @@ function (PhysicsEngine, Level, Player) {
};
}
this.level = new Level(path, this.physicsEngine, this.gameObjects);
this.level.loadLevelInToEngine();
this.level = new Level(levelUid, this.physicsEngine, this.gameObjects);
}
GameController.prototype.onResetLevel = function() {
this.loadLevel(this.levelPath);
this.loadLevel(this.level.uid);
};

View file

@ -1,26 +1,30 @@
define([
"Game/Config/Settings",
"Lib/Vendor/Box2D",
"Lib/Vendor/Box2D",
"Lib/Utilities/NotificationCenter",
"Game/" + GLOBALS.context + "/Collision/Detector",
"Game/" + GLOBALS.context + "/GameObjects/Tile",
"Game/" + GLOBALS.context + "/GameObjects/Item",
"Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard",
"Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard"
], function (Settings, Box2D, CollisionDetector, Tile, Item, Skateboard) {
], function (Settings, Box2D, NotificationCenter, CollisionDetector, Tile, Item, Skateboard) {
// Public
function Level (path, engine, gameObjects) {
this.path = path;
function Level (uid, engine, gameObjects) {
this.uid = uid;
this.engine = engine;
this.levelObject = null;
this.gameObjects = gameObjects;
this.load(this.uid);
}
Level.prototype.loadLevelInToEngine = function (callback) {
this.loadLevelObjectFromPath(this.path, function(levelData){
this.createTiles(levelData);
this.createItems(levelData);
callback();
Level.prototype.load = function (uid) {
var self = this;
var path = Settings.MAPS_PATH + uid + ".json"
this.loadLevelDataFromPath(path, function(levelData) {
self.createTiles(levelData);
self.createItems(levelData);
NotificationCenter.trigger("game/level/loaded");
});
}
@ -46,12 +50,13 @@ define([
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));
}
}
Level.prototype.createItems = function() {
if (!levelData || !levelData.tiles) {
Level.prototype.createItems = function(levelData) {
if (!levelData || !levelData.items) {
return;
}
var items = levelData.items;
@ -73,307 +78,5 @@ define([
};
};
Level.prototype.loadLevelObjectFromPath = function (path) {
// TODO: load JSON levelObject from path
// s: shape
// x: x-position
// y: y-position
// r: rotation (optional)
// Shapes:
// 1
// o o o
// o o o
// o o o
// 2
// o
// o o
// o o o
// 3
// o
// o
// o o
// 4
// o
// o o o
// o o o
// 5
// o
// o
// o o
// 6
// o
// o o o
// o o o
// 7
//
// o
// o o
// 8
// o o
// o o o
// o o o
this.levelObject = this.levelObject || {
/*
Material densities (g/cm^3):
wood: 0.63
steel: 7.859
banana: 0.95
microwave: 3.744
*/
items: [
{
name:'Banana',
image:'banana.gif',
type:'rectangle',
category:'kitchen',
weight: 1,
width:5,
height:9,
depth: 3,
x:21,
y:0,
rotation: 0,
grabAngle: 0.5
},
{
name:'Refridgerator',
image:'fridge.gif',
type:'rectangle',
category:'kitchen',
weight: 10,
width:31,
height:53,
x:120,
y:0,
rotation: 0,
grabAngle: -0.5
},
{
name:'Microwave',
image:'microwave.gif',
type:'rectangle',
category:'kitchen',
weight: 4,
width:19,
height:12,
depth: 12,
x:100,
y:0,
rotation: 0,
grabAngle: -0.1
},
{
name:'Large Cleaver',
image:'cleaver_large.gif',
type:'rectangle',
category:'kitchen',
weight: 3,
width:8,
height:22,
x:40,
y:0,
rotation: 0,
grabAngle: 0.3
},
{
name:'Small Cleaver',
image:'cleaver_small.gif',
type:'rectangle',
category:'kitchen',
weight:2,
width:6,
height:17,
x:60,
y:0,
rotation: 0,
grabAngle: 0.3
},
{
name:'Coffeemachine',
image:'coffeemachine.gif',
type:'rectangle',
category:'kitchen',
weight:2.4,
width:11,
height:14,
x:80,
y:0,
rotation: 0
},
{
name:'Knife',
image:'knife.gif',
type:'rectangle',
category:'kitchen',
weight:1.5,
width:4,
height:15,
x:140,
y:0,
rotation: 0,
grabAngle: 0.3
},
{
name:'Laundry Machine',
image:'laundry_machine.gif',
type:'rectangle',
category:'laundry',
weight: 15,
width:24,
height:31,
x:600,
y:0,
rotation: 0,
grabAngle: -0.5
},
{
name:'Skateboard',
image:'skateboard.gif',
type:'skateboard',
category:'outdoor',
weight: 1.5,
width:26,
height:6,
x:200,
y:0,
rotation: 0,
grabAngle: -1.5
},
{
name:'Football',
image:'football.gif',
type:'circle',
category:'outdoor',
weight: 2,
width:10,
height:10,
x:350,
y:0,
rotation: 0,
grabAngle: -1.5,
bounce: 6
}
],
tiles: /*
(function() {
var tiles = [];
for (var i = 0; i < 50; i++) {
tiles.push({
s:1,
x:i,
y:5
})
};
return tiles;
})()
*/
[
{s:1, x:0, y:0, r:0},
{s:1, x:1, y:1, r:0},
{s:1, x:3, y:18},
{s:1, x:37, y:27},
{s:1, x:20, y:24},
{s:1, x:24, y:27},
{s:1, x:37, y:26},
{s:1, x:9, y:18},
{s:2, x:32, y:25, r:1},
{s:1, x:23, y:27},
{s:3, x:34, y:24, r:1},
{s:1, x:35, y:28},
{s:4, x:17, y:21},
{s:2, x:21, y:24},
{s:2, x:42, y:23, r:3},
{s:3, x:30, y:24, r:3},
{s:2, x:22, y:25},
{s:1, x:40, y:25},
{s:1, x:38, y:26},
{s:1, x:8, y:18},
{s:1, x:38, y:25},
{s:1, x:28, y:28},
{s:1, x:36, y:27},
{s:1, x:7, y:18},
{s:2, x:20, y:23},
{s:2, x:43, y:23, r:1},
{s:6, x:31, y:24},
{s:1, x:16, y:21},
{s:1, x:1, y:18},
{s:1, x:31, y:29},
{s:2, x:30, y:25, r:2},
{s:4, x:11, y:18},
{s:1, x:28, y:27},
{s:1, x:28, y:26},
{s:1, x:28, y:29},
{s:1, x:19, y:23},
{s:5, x:12, y:18, r:1},
{s:1, x:42, y:24},
{s:6, x:33, y:24, r:2},
{s:1, x:39, y:25},
{s:1, x:33, y:29},
{s:1, x:29, y:29},
{s:1, x:21, y:25},
{s:1, x:27, y:27},
{s:5, x:16, y:20, r:1},
{s:1, x:5, y:18},
{s:5, x:18, y:21, r:1},
{s:4, x:13, y:19},
{s:1, x:14, y:20},
{s:1, x:30, y:29},
{s:1, x:4, y:18},
{s:1, x:6, y:18},
{s:1, x:2, y:18},
{s:1, x:32, y:24},
{s:1, x:34, y:29},
{s:1, x:32, y:29},
{s:2, x:1, y:16},
{s:1, x:10, y:18},
{s:1, x:42, y:25},
{s:2, x:28, y:25, r:3},
{s:2, x:0, y:16, r:2},
{s:1, x:22, y:27},
{s:1, x:25, y:27},
{s:1, x:31, y:25},
{s:5, x:14, y:19, r:1},
{s:1, x:41, y:25},
{s:1, x:36, y:28},
{s:4, x:15, y:20},
{s:2, x:19, y:22},
{s:3, x:26, y:26, r:3},
{s:1, x:26, y:27},
{s:1, x:18, y:22},
{s:6, x:27, y:26},
{s:1, x:22, y:26},
{s:1, x:1, y:17},
{s:1, x:35, y:29},
{s:1, x:12, y:19}
]
}
}
// TODO remove hack
/*
Level.prototype.tileAtPositionExists = function(x, y) {
for (var i = 0; i < this.levelObject.tiles.length; i++) {
var o = this.levelObject.tiles[i];
if(o.x == x && o.y == y) return true;
}
return false;
};
*/
return Level;
})

View file

@ -2,22 +2,26 @@
"Game/Server/GameController",
"Lib/Utilities/NotificationCenter",
"Game/Server/User",
"Lib/Utilities/Protocol/Helper"
"Lib/Utilities/Protocol/Helper",
"Lib/Utilities/Options"
],
function (GameController, NotificationCenter, User, ProtocolHelper) {
function (GameController, NotificationCenter, User, ProtocolHelper, Options) {
function Channel (pipeToLobby, name) {
function Channel (pipeToLobby, name, options) {
var self = this;
this.options = options = Options.merge(options, {
levelUids: ["dungeon"]
});
this.name = name;
this.users = {};
this.pipeToLobby = pipeToLobby;
this.gameController = new GameController(this);
this.gameController.loadLevel("default.json");
NotificationCenter.on('channel/controlCommand', function (message) {
ProtocolHelper.applyCommand(message.data, self);
@ -41,6 +45,11 @@
var joinedUsers = Object.keys(this.users);
var spawnedPlayers = this.gameController.getSpawnedPlayersAndTheirPositions();
var worldUpdate = this.gameController.getWorldUpdateObject(true);
var levelUid = null;
if(this.gameController.level) {
levelUid = this.gameController.level.uid;
}
this.users[user.id] = user;
@ -49,8 +58,8 @@
channelName: this.name,
joinedUsers: joinedUsers,
spawnedPlayers: spawnedPlayers,
worldUpdate: worldUpdate
worldUpdate: worldUpdate,
levelUid: levelUid
};
NotificationCenter.trigger('user/' + user.id + "/joinSuccess", options);

View file

@ -18,14 +18,16 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
Parent.call(this);
this.updateWorld();
NotificationCenter.on('user/joined', this.userJoined, this);
NotificationCenter.on('user/left', this.userLeft, this); // FIXME: refactor this.userLeft -> this.onUserLeft, even in core and client
NotificationCenter.on('user/resetLevel', this.onResetLevel, this);
NotificationCenter.on('player/killed', this.spawnPlayer, this);
NotificationCenter.on('game/level/loaded', this.onLevelLoaded, this);
console.checkpoint('starting game controller for channel ' + channel.name);
var nextUid = this.getNextLevelUid();
this.loadLevel(nextUid);
}
GameController.prototype = Object.create(Parent.prototype);
@ -40,6 +42,10 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
}
}
GameController.prototype.onLevelLoaded = function() {
this.updateWorld();
};
GameController.prototype.userJoined = function (user) {
Parent.prototype.userJoined.call(this, user);
var player = this.players[user.id];
@ -137,6 +143,23 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
}
};
GameController.prototype.getNextLevelUid = function() {
if(!this.level) return this.channel.options.levelUids[0];
var levelCount = this.channel.options.levelUids.length;
for (var i = 0; i < levelCount; i++) {
var uid = this.channel.options.levelUids[i];
if(uid == this.level.uid) {
break;
}
};
var next = i + 1;
return this.channel.options.levelUids[next % levelCount];
};
return GameController;
});

View file

@ -1,23 +1,23 @@
define([
"Game/Core/Loader/Level",
"Game/Config/Settings"
"Game/Config/Settings",
"fs"
],
function (Parent, Fs) {
function (Parent, Settings, fs) {
function Level () {
Parent.call(this);
function Level (uid, engine, gameObjects) {
Parent.call(this, uid, engine, gameObjects);
}
Level.prototype = Object.create(Parent.prototype);
Level.prototype.loadLevelObjectFromPath = function (path, callback) {
Level.prototype.loadLevelDataFromPath = function (path, callback) {
// overwriting parent
fs.readFile( + path, function (err, data) {
fs.readFile(path, "utf8", function (err, data) {
if (err) throw err;
callback(data);
callback(JSON.parse(data));
});
}

View file

@ -11,7 +11,7 @@ function () {
NotificationCenter.prototype.trigger = function (topic /*, arguments*/) {
if (!this.topics[topic]) {
throw "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);

View file

@ -0,0 +1,46 @@
define([
"Lib/Utilities/Exception"
],
function (Exception) {
function Options() {
}
Options.prototype.merge = function(options, preset) {
if(!preset && !options) {
throw new Exception("Options requires objects");
}
if(preset.constructor !== Object && options.constructor !== Object) {
throw new Exception("Options requires objects");
}
if(!preset || preset.constructor !== Object) {
return options;
}
if(!options || options.constructor !== Object) {
return preset;
}
for (var key in options) {
if(!preset.hasOwnProperty(key)) {
preset[key] = options[key];
} else {
if(options[key].constructor !== Object) {
preset[key] = options[key];
} else {
preset[key] = mergeOptions(options[key], preset[key]);
}
}
}
return preset;
}
return new Options();
});