I did some experiments with WebGL during the development of my current semester project, a litte browsergame. As Engine I used the Copperlicht Engine which comes with a Editor. Using this editor one can easily build a scene and export it in a format that can be loaded by the WebGL engine. At this occasion I also wrote my first Javascript class!
What i wrote is a configurator. This means the user sees a 3D model of the unit he selected and then he can equip it with different weapons and armors. In this experiments i used no cool models, only primitives and some things i found on my hard disk. Here is a Video of the result. Sometimes I had to use configurator.something instead of this.something. I think this is wrong and I will soon check out some tutorials on Javascript Classes
var configurator = {
engine: null,
armor: null,
active_unit_name: null,
active_unit_index: null,
is_initialized: false,
units: {},
unit_count: 0,
onLoad_conf: {},
scene: null,
// changes the weapon. (sets the selected one visible)
weapon: function(i) {
var unit = this.activeUnit();
if(unit.active_weapon)
unit.active_weapon.Visible = false;
if(typeof(i) == "undefined")
return;
unit.active_weapon = this.scene.getSceneNodeFromName(unit.weapons[i]);
unit.active_weapon.Visible = true;
},
// changes armor
armor: function(i) {
var unit = this.activeUnit();
if(unit.active_armor)
unit.active_armor.Visible = false;
if(typeof(i) == "undefined")
return;
unit.active_armor = this.scene.getSceneNodeFromName(unit.armors[i]);
unit.active_armor.Visible = true;
},
// switch to next unit in left direction
left: function() {
this.active_unit_index--;
if(this.active_unit_index < 0)
this.active_unit_index = this.unit_count-1;
this.reload();
},
// switch in right direction
right: function() {
this.active_unit_index++;
if(this.active_unit_index > this.unit_count-1)
this.active_unit_index = 0;
this.reload();
},
// displayes unit with index active_unit_index
reload: function() {
var counter=0;
for(var key in this.units) {
if(counter == this.active_unit_index) {
this.showUnit(key);
break;
}
counter++;
}
},
// shows unit by name
showUnit: function(unitname) {
if (!this.is_initialized) {
this.initialize(unitname);
return;
}
this.scene.getSceneNodeFromName(this.active_unit_name).Visible = false;
this.weapon();
this.armor();
this.active_unit_name = unitname;
this.scene.getSceneNodeFromName(this.active_unit_name).Visible = true;
this.weapon(this.activeUnit().weapon_index);
this.armor(this.activeUnit().armor_index);
},
// returns the unit that is currently displayed
activeUnit: function() {
return this.units[this.active_unit_name];
},
// initialize scene
onLoaded: function()
{
configurator.scene = configurator.engine.getScene();
if (configurator.scene)
{
// initialize active_unit
var unit = configurator.scene.getSceneNodeFromName(configurator.active_unit_name);
unit.Visible = true;
// also, force the 3d engine to update the scene every frame
configurator.scene.setRedrawMode(Scene.REDRAW_WHEN_SCENE_CHANGED);
// rotate scene
configurator.scene.getSceneNodeFromName('root').addAnimator(new AnimatorRotation(new Vect3d(0, 0.2, 0)));
// load first weapon
configurator.weapon(configurator.activeUnit().weapon_index);
configurator.armor(configurator.activeUnit().armor_index);
}
},
// preinitialize. create canvas to draw in and load scene
initialize: function(default_unit) {
this.is_initialized = true;
jQuery("#canvasContainer").prepend('<canvas id="3darea" width="730" height="450" style="background-color:#ffffff"></canvas>');
jQuery("#configurator").fadeIn();
this.active_unit_name = default_unit;
var index=0;
for(var key in this.units) {
if(key == default_unit) break;
index++;
}
this.active_unit_index = index;
this.engine = startCopperLichtFromFile('3darea', 'copperlichtdata/configurator.ccbjs');
this.engine.OnLoadingComplete = this.onLoaded;
},
// add a unit and its preconfiguartion to the configurator.
// the last two arguments specify which items should be displayed initially
// nodenames are the names to reference the corresponding nodes in the scene. (same as in coppercube editor)
addUnit: function(nodeName, weaponNodeNames, armorNodeNames, weapon_index, armor_index) {
this.units[nodeName] = {
weapons: weaponNodeNames,
armors: armorNodeNames,
weapon_index: weapon_index,
armor_index: armor_index
};
this.unit_count++;
},
destroy: function() {
jQuery("#configurator").fadeOut();
jQuery("#3darea").remove();
this.is_initialized = false;
}
};
jQuery(document).ready(function(){
// add units to configurator
configurator.addUnit("bird",["weapon","weapon2"],["armor1","armor2"],1,0);
configurator.addUnit("ghoul",["ghoul_weapon1","ghoul_weapon2"],["ghoul_armor1","ghoul_armor2"],0,0);
});
engine: null,
armor: null,
active_unit_name: null,
active_unit_index: null,
is_initialized: false,
units: {},
unit_count: 0,
onLoad_conf: {},
scene: null,
weapon: function(i) {
var unit = this.activeUnit();
if(unit.active_weapon)
unit.active_weapon.Visible = false;
if(typeof(i) == “undefined”)
return;
unit.active_weapon = this.scene.getSceneNodeFromName(unit.weapons[i]);
unit.active_weapon.Visible = true;
},
armor: function(i) {
var unit = this.activeUnit();
if(unit.active_armor)
unit.active_armor.Visible = false;
if(typeof(i) == “undefined”)
return;
unit.active_armor = this.scene.getSceneNodeFromName(unit.armors[i]);
unit.active_armor.Visible = true;
},
left: function() {
this.active_unit_index–;
if(this.active_unit_index < 0)
this.active_unit_index = this.unit_count-1;
this.reload();
},
right: function() {
this.active_unit_index++;
if(this.active_unit_index > this.unit_count-1)
this.active_unit_index = 0;
this.reload();
},
reload: function() {
var counter=0;
for(var key in this.units) {
if(counter == this.active_unit_index) {
this.showUnit(key);
break;
}
counter++;
}
},
showUnit: function(unitname) {
if (!this.is_initialized) {
this.initialize(unitname);
return;
}
this.scene.getSceneNodeFromName(this.active_unit_name).Visible = false;
this.weapon();
this.armor();
this.active_unit_name = unitname;
this.scene.getSceneNodeFromName(this.active_unit_name).Visible = true;
this.weapon(this.activeUnit().weapon_index);
this.armor(this.activeUnit().armor_index);
},
activeUnit: function() {
return this.units[this.active_unit_name];
},
onLoaded: function()
{
configurator.scene = configurator.engine.getScene();
if (configurator.scene)
{
// initialize active_unit
var unit = configurator.scene.getSceneNodeFromName(configurator.active_unit_name);
unit.Visible = true;
// also, force the 3d engine to update the scene every frame
configurator.scene.setRedrawMode(Scene.REDRAW_WHEN_SCENE_CHANGED);
// rotate scene
configurator.scene.getSceneNodeFromName(’root’).addAnimator(new AnimatorRotation(new Vect3d(0, 0.2, 0)));
// load first weapon
configurator.weapon(configurator.activeUnit().weapon_index);
configurator.armor(configurator.activeUnit().armor_index);
}
},
initialize: function(default_unit) {
this.is_initialized = true;
jQuery(”#canvasContainer”).prepend(’<canvas id=”3darea” width=”730″ height=”450″ style=”background-color:#ffffff”></canvas>’);
jQuery(”#configurator”).fadeIn();
this.active_unit_name = default_unit;
var index=0;
for(var key in this.units) {
if(key == default_unit) break;
index++;
}
this.active_unit_index = index;
this.engine = startCopperLichtFromFile(’3darea’, ‘copperlichtdata/configurator.ccbjs’);
this.engine.OnLoadingComplete = this.onLoaded;
},
addUnit: function(nodeName, weaponNodeNames, armorNodeNames, weapon_index, armor_index) {
this.units[nodeName] = {
weapons: weaponNodeNames,
armors: armorNodeNames,
weapon_index: weapon_index,
armor_index: armor_index
};
this.unit_count++;
},
destroy: function() {
jQuery(”#configurator”).fadeOut();
jQuery(”#3darea”).remove();
this.is_initialized = false;
}
};
jQuery(document).ready(function(){
// add units to configurator
configurator.addUnit(”bird”,["weapon","weapon2"],["armor1","armor2"],1,0);
configurator.addUnit(”ghoul”,["ghoul_weapon1","ghoul_weapon2"],["ghoul_armor1","ghoul_armor2"],0,0);
});
coole sache,
ich werd mich im sommer auch mal mit webGL spielen
ziemlich geil was da alles geht
nice post . very cool post
Nice pal..
We are working on a serious project using CopperCube and CopperLicht-Engine. Maybe you want to join in regarding some references. Once you deliver good work we´d be happy to pay you.
Write to: nyce-design@gmx.net for some further information