我必须在碰撞时创建具有反向路径的坠落物体。所以有 x 球的数量随机下降,当它在他的路径上遇到另一个球时,它必须改变方向。他们无法强加自己。我已经创建了该代码:
var flakePositions = [[]];
var temp = 0;
var move = 1;
// snowflake proto
function Snowflake() {
this.pos = new Physics();
// snowflake guid
this.id = '';
this.collisionCount = 0;
// inits
this.MAX_X_START_POS = 250;
this.X_START_OFFSET = 200;
this.MAX_Y_START_POS = 50;
this.Y_START_OFFSET = 50;
this.MAX_X_SPEED = 4;
this.MAX_Y_SPEED = 1.2;
// use to get sin && cos
this.animationStepsCounter = 0
this.fallFactor = 10;
// snowflake html
this.getId = function () {
if (this.id == '') {
this.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function (c) {
var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
return this.id;
}
this.initalize = function () {
temp++;
//var size = 5 + Math.random() * 20;
var size = 20;
this.flakeDOM.innerHTML = temp;
this.flakeDOM.style.width = size + "px";
this.flakeDOM.style.height = size + "px";
this.flakeDOM.style.opacity = Math.random();
this.pos.x = (Math.random() * this.MAX_X_START_POS);
this.pos.y = this.Y_START_OFFSET + (Math.random() * this.MAX_Y_START_POS);
this.pos.xSpeed = Math.random() * this.MAX_X_SPEED * Math.sign(-0.5 + Math.random());
this.pos.ySpeed = Math.random() * this.MAX_Y_SPEED;
//create array
this.serial = temp;
flakePositions[temp] = [];
flakePositions[temp]['id'] = this.id;
flakePositions[temp]['x'] = this.flakeDOM.style.top;
flakePositions[temp]['y'] = this.flakeDOM.style.left;
flakePositions[temp]['radius'] = this.flakeDOM.style.width;
flakePositions[temp]['xspeed'] = this.pos.xSpeed;
flakePositions[temp]['yspeed'] = this.pos.ySpeed
}
this.move = function () {
this.flakeDOM.style.top = (this.pos.y += this.pos.ySpeed) + "px";
this.flakeDOM.style.left = (this.pos.x += Math.sin(this.animationStepsCounter / this.fallFactor) * this.pos.xSpeed) + "px";
this.animationStepsCounter += this.pos.ySpeed;
//update array
flakePositions[this.serial]['x'] = this.flakeDOM.style.top;
flakePositions[this.serial]['y'] = this.flakeDOM.style.left;
//check position with rest
var rect1 = flakePositions[this.serial];
var rect1d = rect1['id'];
var firstBall_radius = parseInt(rect1['radius']) / 2;
var firstBall_x = parseInt(rect1['x']) + firstBall_radius;
var firstBall_y = parseInt(rect1['y']) + firstBall_radius;
var firstBall_Ax = firstBall_x + firstBall_radius;
var firstBall_Ay = firstBall_y + firstBall_radius;
for (var j = 1, len = flakePositions.length; j < len; j++) {
if (rect1 !== flakePositions[j]) {
var rect2 = flakePositions[j];
var rect2d = rect2['id'];
var sflake = document.getElementById(rect2d);
var secondBall_radius = parseInt(rect2['radius']) / 2;
var secondBall_x = parseInt(rect2['x']) + secondBall_radius;
var secondBall_y = parseInt(rect2['y']) + secondBall_radius;
var secondBall_Ax = secondBall_x + secondBall_radius;
var secondBall_Ay = secondBall_y + secondBall_radius;
if (firstBall_x + firstBall_radius + secondBall_radius > secondBall_x
&& firstBall_x < secondBall_x + firstBall_radius + secondBall_radius
&& firstBall_y + firstBall_radius + secondBall_radius > secondBall_y
&& firstBall_y < secondBall_y + firstBall_radius + secondBall_radius) {
distance = Math.sqrt(
((firstBall_x - secondBall_x) * (firstBall_x - secondBall_x))
+ ((firstBall_y - secondBall_y) * (firstBall_y - secondBall_y))
);
if (distance < firstBall_radius + secondBall_radius) {
console.log('%c balls have collided', 'color: #0000FF');
sflake.style.left *= -1;
}
}
}
}
}
}
function Physics() {
// pos
this.x = 0;
this.y = 0;
this.z = 0;
// speed
this.xSpeed = 0;
this.ySpeed = 0;
this.zSpeed = 0;
// acceleration
this.xAccel = 1;
this.yAccel = 1;
this.zAccel = 1;
}
snowflakes = new Array();
var interval = 0;
function makeThisBoom() {
// snowflakes container
snowfield = document.getElementById('snow');
// snowflakes count
snoflakesCount = 4;
for (var i = 0; i < snoflakesCount; i++) {
snowflakes[i] = new Snowflake();
var flake = document.createElement('div');
snowflakes[i].flakeDOM = flake;
flake.id = snowflakes[i].getId();
flake.classList.add('sf');
snow.appendChild(flake);
snowflakes[i].initalize();
snowflakes[i].move();
}
interval = setInterval(anime, 50);
}
function anime() {
for (var flake of snowflakes) {
flake.move();
}
}
function setInterface() {
document.getElementById('startstop').onclick = function () {
if (interval != 0) {
clearInterval(interval);
interval = 0;
} else interval = setInterval(anime, 50);
}
}
document.addEventListener("DOMContentLoaded", makeThisBoom);
document.addEventListener("DOMContentLoaded", setInterface);
&#13;
.sf{
position:absolute;
z-index:9999999;
display:block;
width:20px; height:20px;
/* FOR DEV ONLY */
background:#FFF;
opacity:1!important;
border-radius: 50%;
}
body{
background:#222;
overflow:hidden;
}
#snow {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
#startstop{
width:100px;
height:30px;
border:0;
background:rgb(61, 95, 123);
color:#FFF;
outline:none;
}
&#13;
<button id="startstop">Start/stop</button>
<div id="snow"> </div>
&#13;
它检测到碰撞,但我已经准备好不知道如何在碰撞时反弹。我试图反转它(* -1)但没有。有人有什么想法吗?感谢所有答案
答案 0 :(得分:0)
你建议的解决方案只是改变碰撞时的方向,只是在碰撞时将速度乘以-1。
请参阅https://jsfiddle.net/f1z9ak6c/
this.pos.xSpeed *= -1;
然而,如果球在彼此的顶部会遇到问题,它们将永远地一起移动,但是只要它们不能在彼此的顶部开始,它就会起作用。你需要编写额外的代码来阻止这种行为,最简单的方法就是确保它们不会在彼此之上产生。
答案 1 :(得分:0)
似乎是台球物理学的一个例子。 我查了一下,页面上有一些有趣的方程式 real world physics problems
我还发现了另一个问题: Ball to Ball Collision - Detection and Handling