2015-08-21 93 views
7

我正在建造一個需要物理引擎的站點。 與許多SPA應用程序合作後,我感到非常自信。着名的發動機物理碰撞

不幸的是,我無法將碰撞檢測&牆應用到着名的物理模擬中。

你可以在這裏看到可編輯的例子。

https://staging.famous.org/examples/index.html?block=gravity3d&detail=false&header=false 

我想知道是否有可能將碰撞添加到粒子?我已經嘗試過,但似乎碰撞沒有正確設置。我希望有人成功地做到了。

謝謝!

var FamousEngine = famous.core.FamousEngine; 
 

 
var Camera = famous.components.Camera; 
 

 
var DOMElement = famous.domRenderables.DOMElement; 
 
var Gravity3D = famous.physics.Gravity3D; 
 
var Gravity1D = famous.physics.Gravity1D; 
 
var MountPoint = famous.components.MountPoint; 
 
var PhysicsEngine = famous.physics.PhysicsEngine; 
 
var Physics = famous.physics; 
 
var Wall = famous.physics.Wall; 
 
var Position = famous.components.Position; 
 
var Size = famous.components.Size; 
 
var Sphere = famous.physics.Sphere; 
 
var Vec3 = famous.math.Vec3; 
 
var Collision = famous.physics.Collision; 
 

 
function Demo() { 
 
    this.scene = FamousEngine.createScene('#socialInteractive'); 
 

 
    this.camera = new Camera(this.scene); 
 
    this.camera.setDepth(1000); 
 

 
    this.simulation = new PhysicsEngine(); 
 
    this.items = []; 
 

 
    this.collision = new Collision(); 
 

 
    var Wall = famous.physics.Wall; 
 
    var rightWall = new Wall({ 
 
    direction: Wall.LEFT 
 
    }); // bodies coming from the left will collide with the wall 
 
    rightWall.setPosition(1000, 0, 0); 
 

 
    var ceiling = new Wall({ 
 
    normal: [0, 1, 0], 
 
    distance: 300, 
 
    restitution: 0 
 
    }); 
 
    var floor = new Wall({ 
 
    normal: [0, -1, 0], 
 
    distance: 300, 
 
    restitution: 0 
 
    }); 
 
    var left = new Wall({ 
 
    normal: [1, 0, 0], 
 
    distance: 350, 
 
    restitution: 0 
 
    }); 
 
    var right = new Wall({ 
 
    normal: [-1, 0, 0], 
 
    distance: 350, 
 
    restitution: 0 
 
    }); 
 
    var node = this.scene.addChild(); 
 
    var position = new Position(node); 
 
    // this.simulation.attach([right, left, floor, ceiling]) 
 
    // this.items.push([ceiling,position]); 
 

 

 
    for (var i = 0; i < 10; i++) { 
 
    var node = this.scene.addChild(); 
 
    var size = new Size(node).setMode(1, 1); 
 
    var position = new Position(node); 
 
    if (i === 0) { 
 
     createLogo.call(this, node, size, position); 
 
    } 
 
    if (i !== 0) { 
 
     node.id = i; 
 
     createSatellites.call(this, node, size, position); 
 
    } 
 
    } 
 
    FamousEngine.requestUpdateOnNextTick(this); 
 
    console.log(this.collision) 
 
    for (var i = 0; i < this.collision.length; i++) { 
 
    this.simulation.attach(collision, balls, balls[i]); 
 
    } 
 
    this.simulation.addConstraint(this.collision); 
 
} 
 

 
Demo.prototype.onUpdate = function(time) { 
 
    this.simulation.update(time); 
 
    this.collision.update(time, 60); 
 
    if (this.items.length > 0) { 
 
    for (var i = 0; i < this.items.length; i++) { 
 
     var itemPosition = this.simulation.getTransform(this.items[i][0]).position; 
 
     this.items[i][1].set(itemPosition[0], itemPosition[1], 0); 
 
    } 
 
    } 
 
    FamousEngine.requestUpdateOnNextTick(this); 
 
}; 
 

 
function createLogo(node, size, position) { 
 
    size.setAbsolute(50, 50); 
 
    var mp = new MountPoint(node).set(0.5, 0.5); 
 
    var el = new DOMElement(node, { 
 
    tagName: 'img', 
 
    attributes: { 
 
     src: './images/famous-logo.svg' 
 
    } 
 
    }); 
 
    var sphere = new Sphere({ 
 
    radius: 100, 
 
    mass: 10000, 
 
    restrictions: ['xy'], 
 
    position: new Vec3(window.innerWidth/2, window.innerHeight/2, 5) 
 
    }); 
 

 
    this.gravity = new Gravity3D(sphere); 
 
    this.simulation.add(sphere, this.gravity); 
 
    this.items.push([sphere, position]); 
 

 
} 
 

 
function createSatellites(node, size, position, i) { 
 
    size.setAbsolute(20, 20); 
 
    var radius = 200; 
 
    var x = Math.floor(Math.random() * radius * 2) - radius; 
 
    var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x); 
 
    var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')'; 
 
    var el = new DOMElement(node, { 
 
    properties: { 
 
     'background-color': color, 
 
     'border-radius': '50%' 
 
    } 
 
    }); 
 
    var satellite = new Sphere({ 
 
    radius: 20, 
 
    mass: 5, 
 
    position: new Vec3(x + window.innerWidth/2, y + window.innerHeight/2, 0) 
 
    }); 
 
    satellite.setVelocity(-y/Math.PI, -x/Math.PI/2, y/2); 
 
    this.gravity.addTarget(satellite); 
 
    this.simulation.add(satellite); 
 
    this.items.push([satellite, position]); 
 
    this.collision.addTarget(satellite); 
 

 
} 
 

 
// Boilerplate 
 
FamousEngine.init(); 
 

 
// App Code 
 
var demo = new Demo();

回答

-1

感謝您的幫助Talves,我想我發現,物理學春天,而不是gravity3d有效的解決方案。這也包括4個牆壁,似乎運作良好。

var famous = famous; 
 
var FamousEngine = famous.core.FamousEngine; 
 

 
var Camera = famous.components.Camera; 
 

 

 
var DOMElement = famous.domRenderables.DOMElement; 
 
var Gravity3D = famous.physics.Gravity3D; 
 
var MountPoint = famous.components.MountPoint; 
 
var PhysicsEngine = famous.physics.PhysicsEngine; 
 
var Position = famous.components.Position; 
 
var Size = famous.components.Size; 
 
var Wall = famous.physics.Wall; 
 
var Sphere = famous.physics.Sphere; 
 
var Vec3 = famous.math.Vec3; 
 
var math = famous.math; 
 
var physics = famous.physics; 
 
var collision = famous.physics.Collision; 
 
var gestures = famous.components.GestureHandler; 
 
var Spring = famous.physics.Spring; 
 
console.log(famous) 
 
var anchor = new Vec3(window.innerWidth/2, window.innerHeight/2, 0); 
 

 
//Create Walls 
 
var rightWall = new Wall({ 
 
    direction: Wall.LEFT 
 
}).setPosition(window.innerWidth - 20, 0, 0); 
 
var leftWall = new Wall({ 
 
    direction: Wall.RIGHT 
 
}).setPosition(window.innerWidth + 20, 0, 0); 
 
var topWall = new Wall({ 
 
    direction: Wall.DOWN 
 
}).setPosition(0, 20, 0); 
 
var bottomWall = new Wall({ 
 
    direction: Wall.UP 
 
}).setPosition(0, window.innerHeight - 20, 0); 
 

 
function Demo() { 
 
    this.scene = FamousEngine.createScene('body'); 
 

 
    this.camera = new Camera(this.scene); 
 
    this.camera.setDepth(1000); 
 

 
    this.collision = new collision([rightWall, leftWall, topWall, bottomWall]); 
 

 
    this.simulation = new PhysicsEngine(); 
 
    this.simulation.setOrigin(0.5, 0.5); 
 
    this.simulation.addConstraint(this.collision); 
 

 
    this.items = []; 
 
    this.walls = []; 
 

 

 
    //Create Items 
 
    for (var i = 0; i < 30; i++) { 
 
    var node = this.scene.addChild(); 
 
    node.setMountPoint(0.5, 0.5); 
 
    var size = new Size(node).setMode(1, 1); 
 
    var position = new Position(node); 
 
    if (i === 0) { 
 
     createLogo.call(this, node, size, position); 
 
    } 
 
    if (i !== 0) { 
 
     node.id = i; 
 
     createSatellites.call(this, node, size, position); 
 
    } 
 
    } 
 

 
    //Create Walls 
 
    var node = this.scene.addChild(); 
 
    createWalls(node); 
 

 
    FamousEngine.requestUpdateOnNextTick(this); 
 

 
    Demo.prototype.onUpdate = function(time) { 
 
    this.simulation.update(time); 
 

 
    //Postition walls 
 
    var wallPosition = topWall.getPosition(); 
 
    node.setPosition(wallPosition.x, wallPosition.y); 
 

 
    //Position elements 
 
    if (this.items.length > 0) { 
 
     for (var i = 0; i < this.items.length; i++) { 
 
     var itemPosition = this.simulation.getTransform(this.items[i][0]).position; 
 
     this.items[i][1].set(itemPosition[0], itemPosition[1], 0); 
 
     } 
 
    } 
 

 
    FamousEngine.requestUpdateOnNextTick(this); 
 
    }; 
 
} 
 

 
function createWalls(wallNode) { 
 
    wallNode.setSizeMode('absolute', 'absolute', 'absolute').setAbsoluteSize(window.innerWidth, 10, 0); 
 
    var wallDOMElement = new DOMElement(wallNode, { 
 
    tagName: 'div' 
 
    }).setProperty('background-color', 'lightblue'); 
 
} 
 

 
function createLogo(node, size, position) { 
 
    size.setAbsolute(50, 50); 
 
    var mp = new MountPoint(node).set(0.5, 0.5); 
 
    var el = new DOMElement(node, { 
 
    tagName: 'img', 
 
    attributes: { 
 
     src: './images/famous_logo.png' 
 
    } 
 
    }); 
 
    var sphere = new Sphere({ 
 
    radius: 100, 
 
    mass: 10000, 
 
    restrictions: ['xy'], 
 
    position: new Vec3(window.innerWidth/2, window.innerHeight/2, 5) 
 
    }); 
 

 
    // this.gravity = new Gravity3D(sphere); 
 
    // this.simulation.add(sphere, this.gravity); 
 
    this.simulation.add(sphere); 
 
    this.items.push([sphere, position]); 
 
} 
 

 
function createSatellites(node, size, position, i) { 
 
    size.setAbsolute(50, 50); 
 
    var radius = 100; 
 
    var x = Math.floor(Math.random() * radius * 2) - radius; 
 
    var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x); 
 
    var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')'; 
 
    var el = new DOMElement(node, { 
 
    properties: { 
 
     'background-color': color, 
 
     'border-radius': '50%' 
 
    } 
 
    }); 
 
    var satellite = new Sphere({ 
 
    radius: 25, 
 
    mass: 10, 
 
    position: new Vec3(x + window.innerWidth/2, y + window.innerHeight/2, 0) 
 
    }); 
 

 
    // Attach the box to the anchor with a `Spring` force 
 
    var spring = new Spring(null, satellite, { 
 
    stiffness: 95, 
 
    period: 0.6, 
 
    dampingRatio: 1.0, 
 
    anchor: anchor 
 
    }); 
 

 
    //console.log(color); 
 
    // satellite.setVelocity(-y/Math.PI, -x/Math.PI/2, y/2); 
 
    satellite.setVelocity(0.5, 0.5, 0); 
 
    // this.gravity.addTarget(satellite); 
 
    this.simulation.add(satellite, spring); 
 
    this.items.push([satellite, position]); 
 
    this.collision.addTarget(satellite); 
 

 
} 
 

 
// Boilerplate 
 
FamousEngine.init(); 
 

 
// App Code 
 
var demo = new Demo();
<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
     <meta charset="utf-8"> 
 
     <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
 
     <title>Famous :: Seed Project</title> 
 
     <link rel="icon" href="favicon.ico?v=1" type="image/x-icon"> 
 
     <meta name="description" content=""> 
 
     <meta name="viewport" content="width=device-width, initial-scale=1"> 
 
     <style> 
 
      html, body { 
 
       width: 100%; 
 
       height: 100%; 
 
       margin: 0px; 
 
       padding: 0px; 
 
      } 
 
      body { 
 
       position: absolute; 
 
       -webkit-transform-style: preserve-3d; 
 
       transform-style: preserve-3d; 
 
       -webkit-font-smoothing: antialiased; 
 
       -webkit-tap-highlight-color: transparent; 
 
       -webkit-perspective: 0; 
 
       perspective: none; 
 
       overflow: hidden; 
 
      } 
 
     </style> 
 
    </head> 
 
    <body> 
 
     <script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script> 
 
    </body> 
 
</html>