如何在 Famous Engine 中将球体从墙上弹开?
How to bounce a sphere off of a wall in Famous Engine?
我创建了一个球体和一个墙并将其添加到物理引擎中。球体也被赋予了起始速度。
然后我创建了一个圆和墙节点,添加了 DOMElement 组件,并设置了一些尺寸和颜色。
在更新循环中,节点将它们的位置与它们的物理对应物——球体和墙同步。
我预计球体会与墙碰撞,但动画显示球体只是继续穿过墙。我想知道发生这种情况的代码有什么问题。
'use strict';
var famous = require('famous');
var DOMElement = famous.domRenderables.DOMElement;
var FamousEngine = famous.core.FamousEngine;
var Node = famous.core.Node;
var math = famous.math;
var physics = famous.physics;
var Particle = physics.Particle;
var Sphere = physics.Sphere;
var Vec3 = math.Vec3;
var Box = physics.Box;
var Wall = physics.Wall;
// Create Simulation.
var simulation = new physics.PhysicsEngine();
// Create Scene.
var scene = FamousEngine.createScene();
/***************************************
* Add Bodies
***************************************/
// Create Sphere.
var mySphere = new Sphere({ mass: 10, radius: 50 });
// Give the sphere some velocity.
mySphere.setVelocity(100, 0)
.setPosition(0, 250, 0);
// Create Wall.
var rightWall = new Wall({
direction: Wall.LEFT,
size: [10, 500, 100]
});
rightWall.setPosition(500, 0, 0);
simulation.addBody(rightWall);
simulation.addBody(mySphere);
/***************************************
* Add Nodes + Components
***************************************/
// Create circleNode, which updates its position based on mySphere's position.
var circleNode = scene.addChild();
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 250, 0)
.setMountPoint(0, 0);
// Add DOMElement component to circleNode.
var circleDOMElement = new DOMElement(circleNode, { tagName: 'div' })
.setProperty('background-color', 'pink')
.setProperty('border-radius', '50px');
// Create a wallNode, which will update its position based on rightWall's position.
var wallNode = scene.addChild();
wallNode
.setSizeMode('absolute', 'absolute', 'absolute')
.setAbsoluteSize(10, 500, 100);
var wallDOMElement = new DOMElement(wallNode, { tagName: 'div' })
.setProperty('background-color', 'lightblue');
/***************************************
* Create an Update Loop
***************************************/
var updateLoop = scene.addComponent({
onUpdate: function (time) {
// During update, sync cirlceNode position with sphere,
// and wallNode position with wall.
var spherePosition = mySphere.getPosition();
var wallPosition = rightWall.getPosition();
circleNode.setPosition(spherePosition.x, spherePosition.y);
wallNode.setPosition(wallPosition.x, wallPosition.y);
simulation.update(time);
scene.requestUpdateOnNextTick(updateLoop);
}
});
// Kick off loop.
scene.requestUpdate(updateLoop);
FamousEngine.init();
需要将约束应用于墙和球体。在这种情况下,您可以使用 Collision
var Collision = physics.Collision;
替换
rightWall.setPosition(500, 0, 0);
simulation.addBody(rightWall);
simulation.addBody(mySphere);
与
rightWall.setPosition(500, 0, 0);
simulation.addBody(mySphere);
var collision = new Collision([mySphere,rightWall]);
simulation.addConstraint(collision);
另外,将圆的挂载点固定在圆心
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 250, 0)
.setMountPoint(0.5, 0.5);
奖励:添加左墙以使粒子保持在屏幕上
// Create Walls.
var rightWall = new Wall({
direction: Wall.LEFT
});
var leftWall = new Wall({
direction: Wall.RIGHT
});
leftWall.setPosition(0, 0, 0);
rightWall.setPosition(500, 0, 0);
simulation.addBody(mySphere);
var collision = new Collision([mySphere,rightWall,leftWall]);
simulation.addConstraint(collision);
示例工作代码段
var FamousEngine = famous.core.FamousEngine;
var DOMElement = famous.domRenderables.DOMElement;
var Node = famous.core.Node;
var math = famous.math;
var physics = famous.physics;
var Sphere = physics.Sphere;
var Wall = physics.Wall;
var Collision = physics.Collision;
// Create Scene.
var scene = FamousEngine.createScene();
var rootNode = scene.addChild();
// Create Simulation.
var simulation = new physics.PhysicsEngine();
/***************************************
* Add Bodies
***************************************/
// Create Sphere.
var mySphere = new Sphere({
mass: 100,
radius: 50
});
// Give the sphere some velocity.
mySphere.setVelocity(500, 0)
.setPosition(0, 70, 0);
// Create Wall.
var rightWall = new Wall({
direction: Wall.LEFT
});
var leftWall = new Wall({
direction: Wall.RIGHT
});
leftWall.setPosition(0, 0, 0);
rightWall.setPosition(300, 0, 0);
//simulation.addBody(rightWall);
simulation.addBody(mySphere);
var collision = new Collision([mySphere, rightWall, leftWall]);
simulation.addConstraint(collision);
/***************************************
* Add Nodes + Components
***************************************/
// Create circleNode, which updates its position based on mySphere's position.
var circleNode = scene.addChild();
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 70, 0)
.setMountPoint(0.5, 0.5);
circleNode.addUIEvent('click');
circleNode.addComponent({
onReceive: function(type, event) {
if (type === 'click') {
console.log('setting velocity');
mySphere.setVelocity(1000, 0);
}
},
});
// Add DOMElement component to circleNode.
var circleDOMElement = new DOMElement(circleNode, {
tagName: 'div'
})
.setProperty('background-color', 'lightblue')
.setProperty('text-align', 'center')
.setProperty('line-height', '100px')
.setProperty('border-radius', '50px');
circleDOMElement.setContent('click');
// Create a wallNode, which will update its position based on rightWall's position.
var wallNode = scene.addChild();
wallNode
.setSizeMode('absolute', 'absolute', 'absolute')
.setAbsoluteSize(10, 130, 0);
var wallDOMElement = new DOMElement(wallNode, {
tagName: 'div'
})
.setProperty('background-color', 'lightblue');
/***************************************
* Create an Update Loop
***************************************/
var updateLoop = rootNode.addComponent({
onUpdate: function(time) {
// During update, sync cirlceNode position with sphere,
// and wallNode position with wall.
var spherePosition = mySphere.getPosition();
var wallPosition = rightWall.getPosition();
circleNode.setPosition(spherePosition.x, spherePosition.y);
wallNode.setPosition(wallPosition.x, wallPosition.y);
simulation.update(time);
rootNode.requestUpdateOnNextTick(updateLoop);
}
});
// Kick off loop.
rootNode.requestUpdate(updateLoop);
FamousEngine.init();
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;
background-color: black;
-webkit-perspective: 0;
perspective: none;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Physics Famous0.6.2</title>
<link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
<style>
</style>
</head>
<body>
</body>
</html>
我创建了一个球体和一个墙并将其添加到物理引擎中。球体也被赋予了起始速度。
然后我创建了一个圆和墙节点,添加了 DOMElement 组件,并设置了一些尺寸和颜色。
在更新循环中,节点将它们的位置与它们的物理对应物——球体和墙同步。
我预计球体会与墙碰撞,但动画显示球体只是继续穿过墙。我想知道发生这种情况的代码有什么问题。
'use strict';
var famous = require('famous');
var DOMElement = famous.domRenderables.DOMElement;
var FamousEngine = famous.core.FamousEngine;
var Node = famous.core.Node;
var math = famous.math;
var physics = famous.physics;
var Particle = physics.Particle;
var Sphere = physics.Sphere;
var Vec3 = math.Vec3;
var Box = physics.Box;
var Wall = physics.Wall;
// Create Simulation.
var simulation = new physics.PhysicsEngine();
// Create Scene.
var scene = FamousEngine.createScene();
/***************************************
* Add Bodies
***************************************/
// Create Sphere.
var mySphere = new Sphere({ mass: 10, radius: 50 });
// Give the sphere some velocity.
mySphere.setVelocity(100, 0)
.setPosition(0, 250, 0);
// Create Wall.
var rightWall = new Wall({
direction: Wall.LEFT,
size: [10, 500, 100]
});
rightWall.setPosition(500, 0, 0);
simulation.addBody(rightWall);
simulation.addBody(mySphere);
/***************************************
* Add Nodes + Components
***************************************/
// Create circleNode, which updates its position based on mySphere's position.
var circleNode = scene.addChild();
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 250, 0)
.setMountPoint(0, 0);
// Add DOMElement component to circleNode.
var circleDOMElement = new DOMElement(circleNode, { tagName: 'div' })
.setProperty('background-color', 'pink')
.setProperty('border-radius', '50px');
// Create a wallNode, which will update its position based on rightWall's position.
var wallNode = scene.addChild();
wallNode
.setSizeMode('absolute', 'absolute', 'absolute')
.setAbsoluteSize(10, 500, 100);
var wallDOMElement = new DOMElement(wallNode, { tagName: 'div' })
.setProperty('background-color', 'lightblue');
/***************************************
* Create an Update Loop
***************************************/
var updateLoop = scene.addComponent({
onUpdate: function (time) {
// During update, sync cirlceNode position with sphere,
// and wallNode position with wall.
var spherePosition = mySphere.getPosition();
var wallPosition = rightWall.getPosition();
circleNode.setPosition(spherePosition.x, spherePosition.y);
wallNode.setPosition(wallPosition.x, wallPosition.y);
simulation.update(time);
scene.requestUpdateOnNextTick(updateLoop);
}
});
// Kick off loop.
scene.requestUpdate(updateLoop);
FamousEngine.init();
需要将约束应用于墙和球体。在这种情况下,您可以使用 Collision
var Collision = physics.Collision;
替换
rightWall.setPosition(500, 0, 0);
simulation.addBody(rightWall);
simulation.addBody(mySphere);
与
rightWall.setPosition(500, 0, 0);
simulation.addBody(mySphere);
var collision = new Collision([mySphere,rightWall]);
simulation.addConstraint(collision);
另外,将圆的挂载点固定在圆心
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 250, 0)
.setMountPoint(0.5, 0.5);
奖励:添加左墙以使粒子保持在屏幕上
// Create Walls.
var rightWall = new Wall({
direction: Wall.LEFT
});
var leftWall = new Wall({
direction: Wall.RIGHT
});
leftWall.setPosition(0, 0, 0);
rightWall.setPosition(500, 0, 0);
simulation.addBody(mySphere);
var collision = new Collision([mySphere,rightWall,leftWall]);
simulation.addConstraint(collision);
示例工作代码段
var FamousEngine = famous.core.FamousEngine;
var DOMElement = famous.domRenderables.DOMElement;
var Node = famous.core.Node;
var math = famous.math;
var physics = famous.physics;
var Sphere = physics.Sphere;
var Wall = physics.Wall;
var Collision = physics.Collision;
// Create Scene.
var scene = FamousEngine.createScene();
var rootNode = scene.addChild();
// Create Simulation.
var simulation = new physics.PhysicsEngine();
/***************************************
* Add Bodies
***************************************/
// Create Sphere.
var mySphere = new Sphere({
mass: 100,
radius: 50
});
// Give the sphere some velocity.
mySphere.setVelocity(500, 0)
.setPosition(0, 70, 0);
// Create Wall.
var rightWall = new Wall({
direction: Wall.LEFT
});
var leftWall = new Wall({
direction: Wall.RIGHT
});
leftWall.setPosition(0, 0, 0);
rightWall.setPosition(300, 0, 0);
//simulation.addBody(rightWall);
simulation.addBody(mySphere);
var collision = new Collision([mySphere, rightWall, leftWall]);
simulation.addConstraint(collision);
/***************************************
* Add Nodes + Components
***************************************/
// Create circleNode, which updates its position based on mySphere's position.
var circleNode = scene.addChild();
circleNode
.setSizeMode('absolute', 'absolute', 'absolute')
// Match size of sphere
.setAbsoluteSize(100, 100)
.setPosition(0, 70, 0)
.setMountPoint(0.5, 0.5);
circleNode.addUIEvent('click');
circleNode.addComponent({
onReceive: function(type, event) {
if (type === 'click') {
console.log('setting velocity');
mySphere.setVelocity(1000, 0);
}
},
});
// Add DOMElement component to circleNode.
var circleDOMElement = new DOMElement(circleNode, {
tagName: 'div'
})
.setProperty('background-color', 'lightblue')
.setProperty('text-align', 'center')
.setProperty('line-height', '100px')
.setProperty('border-radius', '50px');
circleDOMElement.setContent('click');
// Create a wallNode, which will update its position based on rightWall's position.
var wallNode = scene.addChild();
wallNode
.setSizeMode('absolute', 'absolute', 'absolute')
.setAbsoluteSize(10, 130, 0);
var wallDOMElement = new DOMElement(wallNode, {
tagName: 'div'
})
.setProperty('background-color', 'lightblue');
/***************************************
* Create an Update Loop
***************************************/
var updateLoop = rootNode.addComponent({
onUpdate: function(time) {
// During update, sync cirlceNode position with sphere,
// and wallNode position with wall.
var spherePosition = mySphere.getPosition();
var wallPosition = rightWall.getPosition();
circleNode.setPosition(spherePosition.x, spherePosition.y);
wallNode.setPosition(wallPosition.x, wallPosition.y);
simulation.update(time);
rootNode.requestUpdateOnNextTick(updateLoop);
}
});
// Kick off loop.
rootNode.requestUpdate(updateLoop);
FamousEngine.init();
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;
background-color: black;
-webkit-perspective: 0;
perspective: none;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Physics Famous0.6.2</title>
<link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
<style>
</style>
</head>
<body>
</body>
</html>