著名的引擎物理碰撞
Famous Engine Physics Collisions
我正在构建一个需要物理引擎的站点。
在使用过许多 SPA 应用程序后,我感到非常有信心。
不幸的是,我无法将碰撞检测和墙壁应用于 famous 创建的物理模拟。
您可以在此处查看可编辑示例。
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();
感谢 Talves 的帮助,我想我找到了一个适用于物理 Spring 而不是 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>
我正在构建一个需要物理引擎的站点。 在使用过许多 SPA 应用程序后,我感到非常有信心。
不幸的是,我无法将碰撞检测和墙壁应用于 famous 创建的物理模拟。
您可以在此处查看可编辑示例。
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();
感谢 Talves 的帮助,我想我找到了一个适用于物理 Spring 而不是 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>