Three.js: Why the shadow doesn't appear? - javascript

I keep studing Three.js. I charge a 3D model with the function JSONLoader and when I want to put it a shadow, it doesn't appear and I don't know why because I think I do all the steps:
1- Active the the ShadowMap.
2- I have lights.
3- The plane has recieveShadow = true;
4- The 3D model has castShadow = true;
The completily code (now it's working):
<html><head>
<title>Ejemplo 9 Three.js</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <!--320-->
<script type = 'text/javascript' src = "plugins/jquery/jquery.js"></script>
<script type = 'text/javascript' src = "plugins/bootstrap/bootstrap.js"></script>
<script type = 'text/javascript' src = "plugins/three.js-master/build/three.js"></script>
<script type = 'text/javascript' src = "plugins/dat.gui.js/dat.gui.js"></script>
<script type = 'text/javascript' src = "plugins/threex.windowresize-master/threex.windowresize.js"></script>
<script type = 'text/javascript' src = "plugins/threex.keyboardstate-master/threex.keyboardstate.js"></script>
<script type = 'text/javascript' src = "plugins/orbitcontrols/OrbitControls.js"></script>
<script type = 'text/javascript' src = "plugins/ColladaLoader/ColladaLoader.js"></script>
<link rel = "stylesheet" type = "text/css" href = "css/bootstrap.css">
<style>
body{
margin: 0;
padding: 0;
overflow: hidden;
}
#renderer{
overflow: hidden
}
.container-fluid{
margin: 0;
padding: 0;
}
.col-md-12{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="col-md-12">
<ul>
<li>Up, Down, Left, Right-> Move cube. </li>
<li>Z & X -> Rotate cube. </li>
<li>WASD -> Scale cube.</li>
</ul>
<div id="renderer">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
var renderer;
var controls;
var scene;
var keyboard;
var material;
var plane_texture;
var grass;
var geometry_cube;
var cube_material;
var cube_texture;
var cube;
//Modelo 3D .js
var model3D;
var materials_modelo3D; //materiales
var final_model; //vértices + materiales
//Modelo 3D .dae
var model3Ddae;
var final_modeldae;
var speed;
var space;
var time;
var width;
var height;
var fov;
var aspect;
var near;
var far;
var camera;
var light;
var ambient_light;
var solar_light;
start();
function start(){
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.shadowMap.enabled= true;
width = window.innerWidth-10;
height = window.innerHeight-10;
//alert("ancho: " + width + ", alto:" + height);
renderer.setSize(width, height);
$("#renderer").append(renderer.domElement);
scene = new THREE.Scene();
keyboard = new THREEx.KeyboardState();
model3D = new THREE.JSONLoader(); //vertices
model3Ddae = new THREE.ColladaLoader();
fov = 45; //angle
aspect = width/height;
near = 0.1;
far = 1000;
camera = new THREE.PerspectiveCamera (fov, aspect, near, far);
THREEx.WindowResize(renderer, camera);
var color = new THREE.Color("rgb(250, 250, 250)");
renderer.setClearColor(new THREE.Color(color));
camera.position.z= 20;
camera.position.y= 10;
scene.add(camera);
controls = new THREE.OrbitControls(camera, renderer.domElement);
plane_texture = new THREE.TextureLoader().load("texturas/cesped.jpg");
cube_texture = new THREE.TextureLoader().load("texturas/muro.jpg");
crear_plano();
model3D.load("models/layers260a.js", functionAddModel);
// model3Ddae.load("models/rifle.dae" , functionAddModelDae);
// cube();
makeLight();
var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo
scene.add(ejesAyuda);
renderer.render(scene, camera);
}
function crear_plano(){
geometria_plano = new THREE.PlaneGeometry(100, 100, 10, 10);
plane_texture.wrapS = plane_texture.wrapT = THREE.RepeatWrapping; // para repetir la textura a lo largo y a lo width
plane_texture.repeat.set(10, 10); // tablero de 10 x 10
//material y agregado de textura
material = new THREE.MeshLambertMaterial({map: plane_texture, side: THREE.DoubleSide});
grass = new THREE.Mesh(geometria_plano, material);
//grass.rotation.y=-0.5;
grass.rotation.x=Math.PI/2;
grass.receiveShadow=true;
scene.add(grass);
}
function functionAddModel(geometry){
imagen = new THREE.TextureLoader().load("models/mario.jpg");
materials_modelo3D = new THREE.MeshLambertMaterial({map: imagen});
final_model = new THREE.Mesh(geometry, materials_modelo3D);
scene.add(final_model);
final_model.scale.set(10, 10, 10);
final_model.position.set(10, 13, 10);
final_model.rotation.y = Math.PI;
final_model.castShadow = true;
final_model.receiveShadow = false;
animation();
}
function functionAddModelDae(infodae){
final_modeldae = infodae.scene;
final_modeldae.position.set(20, 5, 10);
final_modeldae.scale.x = final_modeldae.scale.y = final_modeldae.scale.z =.2;
// final_modeldae.rotation.y = Math.PI;
scene.add(final_modeldae);
}
function animation(){
requestAnimationFrame(animation);
render_modelo();
var objMov = final_model;
speed = 100;
time = 0.001;
space = speed * time;
if(keyboard.pressed("up")){ //tecla flecha arriba
objMov.position.z+=space;
}else if(keyboard.pressed("down")){
objMov.position.z-=space;
}else if(keyboard.pressed("right")){
objMov.position.x+=space;
}else if(keyboard.pressed("left")){
objMov.position.x-=space;
}else if(keyboard.pressed("z")){
objMov.rotation.x+=space;
}else if(keyboard.pressed("x")){
objMov.rotation.y+=space;
}else if(keyboard.pressed("w")){
objMov.scale.y+=space;
}else if(keyboard.pressed("a")){
objMov.scale.x-=space;
}else if(keyboard.pressed("s")){
objMov.scale.y-=space;
}else if(keyboard.pressed("d")){
objMov.scale.x+=space;
}
controls.target.set(objMov.position.x, objMov.position.y, objMov.position.z);
}
function render_modelo(){
controls.update();
renderer.render(scene, camera);
}
function cube(){
geometry_cube = new THREE.CubeGeometry(10, 10, 10);
cube_material = new THREE.MeshLambertMaterial({map:cube_texture, side:THREE.DoubleSide, wireframe: false});
cube = new THREE.Mesh(geometry_cube, cube_material);
cube.position.x= -4;
cube.position.y = 6;
cube.position.z = 0;
cube.castShadow = true;
scene.add(cube);
}
function makeLight(){
light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
ambient_light = new THREE.AmbientLight(0x000000);
scene.add(ambient_light);
solar_light = new THREE.DirectionalLight();
solar_light.position.set(500, 500, -500);
solar_light.castShadow = true;
solar_light.intensity = 1.3;
solar_light.shadow.mapSize.width = 1024;
solar_light.shadow.mapSize.height = 1024;
solar_light.shadow.camera.near = 250;
solar_light.shadow.camera.far = 1000;
intensidad=50;
solar_light.shadowCameraLeft = -intensidad;
solar_light.shadowCameraRight = intensidad;
solar_light.shadowCameraTop = intensidad;
solar_light.shadowCameraBottom = -intensidad;
scene.add(solar_light);
var helper = new THREE.CameraHelper( light.shadow.camera );
var helper2 = new THREE.CameraHelper(solar_light.shadow.camera);
scene.add(helper);
scene.add(helper2);
}
});
</script>
</body>
</html>
The scene:
Thanks for you help, as always :)

Your "grass" material is a MeshBasicMaterial. As the name implies, it is purely basic, and does not respond to light sources.
Interestingly, MeshBsicMaterial can cast shadows,
but cannot receive them.
(https://github.com/mrdoob/three.js/issues/8116#issuecomment-183459078).
Change your grass material to MeshLambertMaterial, and the shadows will appear.

Related

Adding a button to change mesh in babylon.js

I'm having a terrible time trying to show/hide a mesh in my babylon.js scene with a button. I assumed I could create a function that would show/hide meshes and then call said button from my page to affect my scene and wrote the following:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="assets/js/babylon.js"></script>
<script src="assets/js/hand-1.3.8.js"></script>
<script src="assets/js/cannon.js"></script> <!-- optional physics engine -->
</head>
<body>
<div id="container">
<!-- Page Content -->
<div id="content">
<div id="tableBuilder">
<div id='cssmenu'>
<ul id="tops">
<button type="button" onclick="showTop('T115')">Round</button>
<button type="button" onclick="showTop('T345')">Rectangular</button>
</ul>
</div>
<canvas id="renderCanvas"></canvas>
</div>
</div>
</div>
<script>
if (BABYLON.Engine.isSupported()) {
var myNewScene = null;
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
BABYLON.SceneLoader.Load("", "test.babylon", engine, function (newScene) {
myNewScene = newScene;
var meshT115 = newScene.getMeshByName("T115").visibility = 0;
var mesh510 = newScene.getMeshByName("510").visibility = 1;
var meshT345 = newScene.getMeshByName("T345").visibility = 1;
var mesh350 = newScene.getMeshByName("350").visibility = 0;
var myBaseMesh = newScene.getMeshByName("510");
var materialMyMesh = new BABYLON.StandardMaterial("texture1", newScene);
materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);
materialMyMesh.specularPower = 50;
myBaseMesh.material = materialMyMesh;
var myTopMesh = newScene.getMeshByName("T345");
var materialMyMesh = new BABYLON.StandardMaterial("texture2", newScene);
materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);
materialMyMesh.specularPower = 50;
myTopMesh.material = materialMyMesh;
// Wait for textures and shaders to be ready
newScene.executeWhenReady(function () {
// Attach camera to canvas inputs
var myCamera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1.2, 1.2, 5, new BABYLON.Vector3(0, 0.1, 0.1), newScene);
myCamera.wheelPrecision = 10;
var light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 50, 0), newScene);
light0.diffuse = new BABYLON.Color3(1, 1, 1);
light0.specular = new BABYLON.Color3(1, 1, 1);
light0.groundColor = new BABYLON.Color3(.5, .5, .5);
newScene.activeCamera = myCamera;
newScene.activeCamera.attachControl(canvas);
// Once the scene is loaded, just register a render loop to render it
engine.runRenderLoop(function() {
newScene.render();
});
});
}, function (progress) {
// To do: give progress feedback to user
});
}
function showTop (x) {
myNewScene.getMeshById("myTopMesh").visibility = 0;
myNewScene.getMeshById(x).visibility = 1;
}
</script>
</body>
</html>
However, all I get is an Error.
Uncaught TypeError: undefined is not a function
showTop 3d.php::88
onclick 3d.php::88
Line 88 is:
myNewScene.getMeshById(x).visibility = 1;
My question is, if I am declaring myNewScene as a global variable and then assigning it within my scene creation why does my browser think it should be a function?
Thanks.
change this:
if (BABYLON.Engine.isSupported()) {
var myNewScene = null;
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
to something like this:
var myNewScene, canvas, engine;
if (BABYLON.Engine.isSupported()) {
myNewScene = null;
canvas = document.getElementById("renderCanvas");
engine = new BABYLON.Engine(canvas, true);

Setting new body position on BeginContact event

I want to set a new position of body on BeginContact event but it's still not functional. It's writed in JavaSript with drawing to canvas but it doesn't matter for Box2d. In HTML file in body is only empty canvas, nothing else. Here is my code:
In the beginning of JS file are only declarated some variables.
Vec2 = Box2D.Common.Math.b2Vec2;
BodyDef = Box2D.Dynamics.b2BodyDef;
Body = Box2D.Dynamics.b2Body;
FixtureDef = Box2D.Dynamics.b2FixtureDef;
Fixture = Box2D.Dynamics.b2Fixture;
World = Box2D.Dynamics.b2World;
PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
DebugDraw = Box2D.Dynamics.b2DebugDraw;
var player;
It's followed by a setup function which is called in the beginning.
function setup()
{
canvas = document.getElementById("collisionCanvas");
context = canvas.getContext('2d');
document.getElementsByTagName('body')[0].style.backgroundColor = "black";
canvas.style.backgroundColor = "white";
canvas.width = 320;
canvas.height = 320;
world = new World(new Vec2(0, 10), false);
//Point of the problem!!!
//setting contact listener
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact)
{
var body1 = contact.GetFixtureA().GetBody();
var body2 = contact.GetFixtureB().GetBody();
if(body1.GetUserData().type == "player")
{
body1.SetPosition({x:5, y:5});
}
else
{
body2.SetPosition({x:5, y:5});
}
}
world.SetContactListener(listener);
var fixDef = new FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
var bodyDef = new BodyDef;
//creating ground
bodyDef.type = Body.b2_staticBody;
bodyDef.position.x = convertPixelsToMeters(160);
bodyDef.position.y = convertPixelsToMeters(320-32/2);
bodyDef.userData = {type: "static"};
fixDef.shape = new PolygonShape;
fixDef.shape.SetAsBox(convertPixelsToMeters(canvas.width/2), convertPixelsToMeters(32/2));
world.CreateBody(bodyDef).CreateFixture(fixDef);
//creating player
bodyDef.type = Body.b2_dynamicBody;
bodyDef.fixedRotation = true;
bodyDef.position.x = convertPixelsToMeters(160);
bodyDef.position.y = convertPixelsToMeters(160);
bodyDef.userData = {type: "player"};
fixDef.shape = new PolygonShape;
fixDef.shape.SetAsBox(convertPixelsToMeters(16), convertPixelsToMeters(16));
player = world.CreateBody(bodyDef);
player.CreateFixture(fixDef);
//setup debug draw
var debugDraw = new DebugDraw();
debugDraw.SetSprite(document.getElementById("collisionCanvas").getContext("2d"));
debugDraw.SetDrawScale(32.0);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(DebugDraw.e_shapeBit | DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
window.setInterval(update, 1000 / 60);
}
And in the end are only update function, one helping function and that's it.
function update()
{
world.Step(
1 / 60 //frame-rate
, 10 //velocity iterations
, 10 //position iterations
);
world.DrawDebugData();
world.ClearForces();
}
function convertPixelsToMeters(x)
{
return x*0.03125;
}
$(function(){
setup();
})
Important is only the middle code where is BeginContact event where is calling the SetPosition function which doesn't work.
I tried change position in other places, for example on KeyDown event and there it was correct, so it's for me understandable why it doesn't work.
In the b2Contactlistner method we can not change any prperty or position.
You can take any boolean variable and make it true when in beign contact and if change the position of body according to boolean variable.
as in your code.......
var bodyyy;
var boolennn
listener.BeginContact = function(contact)
{
var body1 = contact.GetFixtureA().GetBody();
var body2 = contact.GetFixtureB().GetBody();
if(body1.GetUserData().type == "player")
{
//body1.SetPosition({x:5, y:5});
bodyyy = body1;
booleannn = true;
}
else
{
// body2.SetPosition({x:5, y:5});
bodyyy = body2;
boolennn = true;
}
}
Now In your Update method
if(booleann)
{
bodyyy.SetPosition({x:5, y:5})
}
SORRY I Donot know syntax of java script

Thingiview and Three.js script conflict

I have a problem with Three.js and Thingiview.js (that come from Three.js).
I have a conflict with those two libraries/scripts. (I think the three.js and three.min.js files).
Here I can only have 50% of my scripts :s
What I want to do is showing my scene with thingiview and calculate the boundingbox with three.js.
I hope you know a solution for this kind of conflict. I have passed all the day on it :(
Here is the code that I call:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script src="thingview/javascripts/Three.js"></script>
<script src="thingview/javascripts/thingiview.js"></script>
<script>
var modele = document.getElementById('modele3d').value;
window.onload = function() {
// You may want to place these lines inside an onload handler
CFInstall.check({
mode: "inline", // the default
node: "prompt"
});
thingiurlbase = "";
thingiview = new Thingiview("viewer");
thingiview.setObjectColor('#e4e5e6');
thingiview.initScene();
thingiview.loadSTL('../../images/'+modele);
log(thingiview.objectColor);
}
</script>
<div id="viewer" style="width:400px;height:300px;margin:auto;position:relative;border:5px solid white;border-radius:5px;"></div>
<script src="scripts/three.min.js"></script>
<script src="three/js/loaders/STLLoader.js"></script>
<script src="three/js/Detector.js"></script>
<script>
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
var material = new THREE.MeshLambertMaterial( { color: 0xd0d1d2, shininess: 5 } );
var mesh = new THREE.Mesh(geometry, material );
// Recherche et envoi des tailles //
geometry.computeBoundingBox();
var largeur = (mesh.geometry.boundingBox.max.x)- (mesh.geometry.boundingBox.min.x);
var hauteur = (mesh.geometry.boundingBox.max.y)-(mesh.geometry.boundingBox.min.y);
var profondeur = (mesh.geometry.boundingBox.max.z)-(mesh.geometry.boundingBox.min.z);
var tailles = largeur + " " + hauteur + " " + profondeur;
var prix = document.getElementById('prototype_prix').value;
if(prix==0){
document.getElementById('prototype_taille1').value = (Math.round(largeur*100))/100;
document.getElementById('prototype_taille2').value = (Math.round(hauteur*100))/100;
document.getElementById('prototype_taille3').value = (Math.round(profondeur*100))/100;
document.getElementById('prototype_taille1_base').value = largeur;
document.getElementById('prototype_taille2_base').value = hauteur;
document.getElementById('prototype_taille3_base').value = profondeur;
}
} );
loader.load( 'images/'+modele);
</script>

select easeljs mouse events not working

not sure what I'm doing wrong here but some select mouse events (drag/drop, onclick and onpress) do not work. onDoubleClick works however. This is what I'm doing.
.js file
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Body = Box2D.Dynamics.b2Body;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2World = Box2D.Dynamics.b2World;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var b2AABB = Box2D.Collision.b2AABB;
var b2ContactListener = Box2D.Dynamics.b2ContactListener;
window.onblur = function(){ Ticker.setPaused(true); PAUSED = true; console.log("paused"); }
window.onfocus = function(){ Ticker.setPaused(false); PAUSED = false; console.log("unpaused"); }
var PAUSED = false;
var Type = {
WALL : 1,
BOULDER : 2
};
var CategoryBits = {
WALL : 0x0001,
BOULDER : 0x0002
};
function Boundary(density, restitution, friction, angularDamping, linearDamping, position, size, scale, categoryBits, maskBits, type, world){
var boundaryFixture = new b2FixtureDef;
boundaryFixture.density = density;
boundaryFixture.restitution = restitution;
boundaryFixture.friction = friction;
boundaryFixture.filter.categoryBits = categoryBits;
boundaryFixture.filter.maskBits = maskBits;
boundaryFixture.shape = new b2PolygonShape;
boundaryFixture.shape.SetAsBox(size.length/scale, size.height/scale);
var boundaryBodyDef = new b2BodyDef;
boundaryBodyDef.type = b2Body.b2_staticBody;
boundaryBodyDef.angularDamping = angularDamping;
boundaryBodyDef.linearDamping = linearDamping;
boundaryBodyDef.position.x = position.x/ scale;
boundaryBodyDef.position.y = position.y/scale;
this.boundary = world.CreateBody(boundaryBodyDef);
this.boundary.CreateFixture(boundaryFixture);
this.boundary.SetUserData(this);
this.type = type;
};
function Position(x, y){
this.x = x;
this.y = y;
};
function Size(length, height){
this.length = length;
this.height = height;
};
function Noir(size, scale, step, debug){
this.GRAVITY = new b2Vec2(0, 10/(scale/5));
this.FPS = 30;
this.SCALE = scale;
this.STEP = step;
this.TIMESTEP = 1/this.STEP;
this.DEBUG = debug;
this.LENGTH = size.length;
this.LENGTH_OFFSET = 20;
this.HEIGHT = size.height;
this.HEIGHT_OFFSET = 10;
this.BOUNDARY_WIDTH = 2;
this.VELOCITY_ITERATIONS = 10;
this.POSITION_ITERATIONS = 10;
this.world;
this.contactListener;
this.canvas;
this.debugCanvas;
this.debugDraw;
this.context;
this.debugContext;
this.stage;
this.previousTime = Date.now();
this.game;
};
Noir.prototype.initCanvas = function(){
this.canvas = document.getElementById('canvas');
this.context = canvas.getContext('2d');
this.stage = new Stage(canvas);
this.stage.snapPixelsEnabled = true;
this.stage.mouseEventsEnabled = true;
//this.stage.onDoubleClick = function(event){ console.log("moving.."); }
this.stage.enableMouseOver();
if(this.DEBUG){
this.debugCanvas = document.getElementById('debugCanvas');
this.debugContext = debugCanvas.getContext('2d');
console.log('Debug on');
}
};
Noir.prototype.initDebug = function(){
this.debugDraw = new b2DebugDraw();
this.debugDraw.SetSprite(this.debugContext);
this.debugDraw.SetDrawScale(this.SCALE);
this.debugDraw.SetFillAlpha(0.7);
this.debugDraw.SetLineThickness(1.0);
this.debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
this.world.SetDebugDraw(this.debugDraw);
};
Noir.prototype.setContactListener = function(){
this.contactListener = new b2ContactListener;
this.contactListener.events = this;
this.contactListener.BeginContact = function(contact, manifold){
var bodyAUser = contact.GetFixtureA().GetBody().GetUserData();
var bodyBUser = contact.GetFixtureB().GetBody().GetUserData();
/* console.log(bodyAUser.type + " , " + bodyBUser.type); */
if((bodyAUser.type == Type.BOULDER) && (bodyBUser.type == Type.WALL)){ this.events.boulderWallContact(bodyAUser, bodyBUser); }
else if((bodyAUser.type == Type.WALL) && (bodyBUser.type == Type.BOULDER)){ this.events.boulderWallContact(bodyBUser, bodyAUser); }
}
this.world.SetContactListener(this.contactListener);
};
Noir.prototype.boulderWallContact = function(boulder, wall){ boulder.flagToDestroy(); };
Noir.prototype.initPhysics = function(){
this.lastTimestamp = Date.now();
this.world = new b2World(this.GRAVITY, true);
this.setContactListener();
if(this.DEBUG){ this.initDebug(); console.log('Debug initialized'); }
var floor = new Boundary(1, 1, 0.6, 0.6, 0.6, new Position(-(this.LENGTH_OFFSET/2), (this.HEIGHT+ (this.HEIGHT_OFFSET - (this.HEIGHT_OFFSET - 1)))),
new Size((this.LENGTH + this.LENGTH_OFFSET), this.BOUNDARY_WIDTH), this.SCALE, CategoryBits.WALL, CategoryBits.BOULDER, Type.WALL, this.world);
/* var ceiling = new Boundary(1, 1, 0.6, 0.6, 0.6, new Position(-(this.LENGTH_OFFSET/2), (this.HEIGHT_OFFSET - (this.HEIGHT_OFFSET - 1))),
new Size((this.LENGTH + this.LENGTH_OFFSET), this.BOUNDARY_WIDTH), this.SCALE, CategoryBits.WALL, CategoryBits.BOULDER, Type.WALL, this.world); */
var leftFixture = new Boundary(1,1, 0.6, 0.6, 0.6, new Position(-(this.BOUNDARY_WIDTH - (this.BOUNDARY_WIDTH - 1)), -(this.LENGTH_OFFSET/2)),
new Size(this.BOUNDARY_WIDTH, (this.HEIGHT + this.HEIGHT_OFFSET)), this. SCALE, CategoryBits.WALL, CategoryBits.BOULDER, Type.WALL, this.world);
var rightFixture = new Boundary(1,1, 0.6, 0.6, 0.6, new Position((this.LENGTH + (this.LENGTH_OFFSET - (this.LENGTH_OFFSET - 1))), -(this.LENGTH_OFFSET/2)),
new Size(this.BOUNDARY_WIDTH, (this.HEIGHT+ this.HEIGHT_OFFSET)), this.SCALE, CategoryBits.WALL, CategoryBits.BOULDER, Type.WALL, this.world);
};
Noir.prototype.tick = function(){
this.updatePhysics();
this.stage.update();
};
Noir.prototype.initTicker = function(){
Ticker.setFPS(this.FPS);
Ticker.useRAF = true;
Ticker.addListener(this, true);
};
Noir.prototype.init = function(){
this.initCanvas();
this.initTicker();
this.initPhysics();
this.initGame(this.stage, this.world);
var debug = document.getElementById('debug');
};
Noir.prototype.initOnLoadDocument = function(){
console.log('running');
if(document.loaded){ this.init(); }
else{
if(window.addEventListener){ window.addEventListener('load', this.init(), false); }
else { window.attachEvent('onLoad', this.init); }
}
}
Noir.prototype.updatePhysics = function(){
/* remove flagged objects for destruction */
/* update non-flagged objects */
if(!PAUSED){
this.updateGame();
this.world.Step(this.TIMESTEP, this.VELOCITY_ITERATIONS, this.POSITION_ITERATIONS);
this.world.ClearForces();
if(this.DEBUG){
this.world.m_debugDraw.m_sprite.graphics.clear();
this.world.DrawDebugData();
}
}
};
Noir.prototype.initGame = function(){
this.game = new Game(this.stage, this.SCALE, this.world);
this.game.start();
};
Noir.prototype.updateGame = function(){ this.game.update(); }
function Actor(density, restitution, friction, angularDamping, linearDamping, path, position, size, stage, scale, categoryBits, maskBits, type, world){
this.skin = new Bitmap(path);
this.skin.x = position.x;
this.skin.y = position.y;
this.skin.regX = (size.length/2);
this.skin.regY = (size.height/2);
this.skin.snapToPixel = true;
this.skin.mouseEnabled = false;
stage.addChild(this.skin);
var actorFixture = new b2FixtureDef;
actorFixture.density = density;
actorFixture.restitution = restitution;
actorFixture.friction = friction;
actorFixture.filter.categoryBits = categoryBits;
actorFixture.filter.maskBits = maskBits;
actorFixture.shape = new b2PolygonShape;
actorFixture.shape.SetAsBox((size.length/2)/scale, (size.height/2)/scale);
var actorBodyDef = new b2BodyDef;
actorBodyDef.type = b2Body.b2_dynamicBody;
actorBodyDef.angularDamping = angularDamping;
actorBodyDef.linearDamping = linearDamping;
actorBodyDef.position.x = this.skin.x/scale;
actorBodyDef.position.y = this.skin.y/scale;
this.body = world.CreateBody(actorBodyDef);
this.body.CreateFixture(actorFixture);
this.body.SetUserData(this);
this.type = type;
this.destroy = false;
};
Actor.prototype.flagToDestroy = function(){ this.destroy = true; };
Actor.prototype.remove = function(game){
game.stage.removeChild(this.skin);
game.world.DestroyBody(this.body);
game.actors.splice(game.actors.indexOf(this),1);
};
Actor.prototype.update = function(scale){
this.skin.rotation = this.body.GetAngle() * (180/Math.PI);
this.skin.x = this.body.GetWorldCenter().x * scale;
this.skin.y = this.body.GetWorldCenter().y * scale;
};
function Icon(path, position, size, stage){
this.skin = new Bitmap(path);
this.skin.x = position.x;
this.skin.y = position.y;
this.skin.regX = (size.length/2);
this.skin.regY = (size.height/2);
stage.addChild(this.skin);
//this.skin.onDoubleClick = function(event){ alert("click click"); }
this.skin.onClick = function(event){ alert("click"); }
this.skin.onPress = function(event){ console.log("pressing"); }
};
function Game(stage, scale, world){
this.scale = scale;
this.stage = stage;
this.world = world;
this.boulderSpawnDelayCounter = 0;
this.actors = [];
this.icon;
};
Game.prototype.start = function(){
var position = new Position(400, 200);
var size = new Size(50, 50);
console.log(this);
this.icon = new Icon("images/bird.png", position, size, this.stage);
};
Game.prototype.controlledSpawn = function(stage, scale, world){
var spawnInterval = (50 + Math.round(Math.random() * 10));
this.boulderSpawnDelayCounter++;
if(this.boulderSpawnDelayCounter % spawnInterval === 0){
this.boulderSpawnDelayCounter = 0;
this.boulderSpawn();
}
};
Game.prototype.boulderSpawn = function(stage, scale, world){
var position = new Position((100 + Math.round(Math.random() * 250)), -20);
var size = new Size(50, 50);
this.actors.push(new Actor(0.2, 0.6, 0.3, 0.3, 0.3, "images/bird.png", position, size, this.stage, this.scale, CategoryBits.BOULDER, CategoryBits.WALL, Type.BOULDER, this.world));
};
Game.prototype.update = function(){
this.controlledSpawn();
for(idx = 0; idx < this.actors.length; ++idx){
if(this.actors[idx].destroy == true){ this.actors[idx].remove(this); }}
for(idx = 0; idx < this.actors.length; ++idx){ this.actors[idx].update(this.scale); }
};
.html file
<!doctype html>
<html xmlns:og="http://ogp.me/ns#">
<head>
<meta charset="utf-8">
<title>Noir test</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<canvas width="500" height="500" id="canvas"></canvas>
<canvas width="500" height="500" id="debugCanvas"></canvas>
<script> var createjs = window </script>
<script type="text/javascript" src="libs/easeljs-0.5.0.min.js"></script>
<script type="text/javascript" src="libs/Box2dWeb-2.1.a.3.min.js"></script>
<script type="text/javascript" src="js/noir.js"></script>
<script> var noir = new Noir(new Size(500, 500), 30, 20, false); noir.initOnLoadDocument()</script>
</body>
</html>
I'm working with this on a local server so the server security issue triggering this similar behaviour for remote servers doesn't apply (I think). Guys, I'm stumped here. Your help will be very much appreciated. Thanks.
Without seeing your CSS, I would guess that your debug canvas is layered overtop of your main canvas. If this is the case, the debug canvas will be the target for any mouse events, preventing your main canvas (and the related Stage) from receiving them.
Due to a bug (recently fixed in the NEXT version), EaselJS subscribes to double click events on the window, instead of on the canvas, which is likely why onDoubleClick is working for you.
Also, it might be worth checking out the newer version of EaselJS. v0.7.0 includes a great new event model, and v0.7.1 will be out shortly with the fix for double click.

Box2DWeb - Adding and Removing Body in the world

I have the following code in Box2D, I want to move my dynamic body to the point where the mouse is click. Also in the future i want to be able to remove the dynamic body, I am not able to find anything equivalent to world.DeleteBody(...). Please Help.
var world;
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2World = Box2D.Dynamics.b2World
, b2MassData = Box2D.Collision.Shapes.b2MassData
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
;
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var mouseX, mouseY, isMouseDown;
var bBallBody, bBallbodyDef;
function init() {
world = new b2World(
new b2Vec2(0, 10) //gravity
, true //allow sleep
);
setupWorld() ;
//setup debug draw
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
debugDraw.SetDrawScale(1.0);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
window.setInterval(update, 1000 / 60);
};
function setupWorld() {
setupGround();
addBouncingBall();
}
function setupGround() {
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
var bodyDef = new b2BodyDef;
//create ground
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = 300;
bodyDef.position.y = 400;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(290, 10);
world.CreateBody(bodyDef).CreateFixture(fixDef);
}
function addBouncingBall() {
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 1.0;
fixDef.restitution = 0.1;
var bBallbodyDef = new b2BodyDef;
bBallbodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2CircleShape(Math.random() + 30);
bBallbodyDef.position.x = Math.random() * 300;
bBallbodyDef.position.y = Math.random() * 300;
bBallBody = world.CreateBody(bBallbodyDef).CreateFixture(fixDef);
console.log(bBallBody.m_body.GetPosition().x);
};
document.addEventListener("mousedown", handleMouseMove, true);
function handleMouseMove(e) {
isMouseDown = true;
mouseX = e.clientX;
mouseY = e.clientY;
};
function update() {
if(isMouseDown)
{
for (b = world.GetBodyList() ; b; b = b.GetNext()) {
if (b.GetType() == b2Body.b2_dynamicBody) {
console.log(b.x, b.y);
b.x = 100;
b.y = 100;
}
}
isMouseDown = false;
}
world.Step(1 / 60, 10, 10);
world.DrawDebugData();
world.ClearForces();
};
Update:
Deletion of an object from the world is done as follows,
Create a Timer to Schdule the deletion of the object.
window.setInterval(removeObjScheduledForRemoval, 1000/90);
Collect the objects to be deleted in a Array.
var bricksScheduledForRemoval = Array();
var index = -1;
function removeObjScheduledForRemoval()
{
for(var i = 0; i <= index; i++){
world.DestroyBody(bricksScheduledForRemoval[i]);
bricksScheduledForRemoval[i] = null;
}
bricksScheduledForRemoval = Array();
index = -1;
}
The complete code is available here,
http://box2dinabox.blogspot.in/2012/07/the-completed-bananamonkey-game.html
The documentation for box2dweb is nowhere near as comprehensive as it is for the original C version, so consider searching for "box2d" instead of "box2dweb". Also, looking into the source and searching for the spelling of certain methods could be helpful. Or just look into the box2d flash documentation. Basically, box2dweb has the methods DestroyJoint and DestroyBody.
For more considerations, this could be helpful: http://www.iforce2d.net/b2dtut/removing-bodies
You can remove the body or change the static body to dynamic as this game example does.
http://pixsansar.com/box2dweb-jumping-and-puzzle-ball-level4
Box2dweb has removebody or changeBodyType option, see the source code of it.

Categories