作者热门文章
- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我有以下代码,它利用物理原理和木星引力除以 10 使多个球沿屏幕弹跳以进行测试。
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext('2d');
//jupiter's gravity divided by 10 for testing purposes
g = 24.79/10;
canvas.width = window.innerWidth - 50;
canvas.height = window.innerHeight - 22.5;
bounciness = (1/2)
var spawnrate = 16;
var inertia = 0.00075;
var gravity = g/25;
players = []
then = new Date()/1000;
moved = false;
function getPosition(event){
mouseX = event.clientX;
mouseY = event.clientY;
if(moved == false){
update();
moved = true;
}
}
function addCircle(){
players.push({x: mouseX, y: mouseY, color: '#000000', radius: 10, velY: 0, velX: 2, jumped: false, jump: 0.02, max: 0});
}
first = new Date();
function update(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
t = new Date() - first;
now = new Date() / 1000;
if(now-then >= 1/spawnrate){
then = now;
addCircle();
}
for(var c = 0; c < players.length; c++){
circle = players[c];
circle.y+=circle.velY;
circle.x+=circle.velX;
circle.velX-=inertia;
circle.velY+=gravity;
if(Math.abs(circle.velY) > Math.abs(circle.max)){
circle.max = circle.velY;
}
if(circle.y + circle.radius/2 > canvas.height){
circle.velY*=-Math.sqrt(bounciness);
}
updateCircle(circle);
if(circle.x > canvas.width){
players.splice(c, 1);
}
}
setTimeout(update, 10);
}
function drawLine(x1, y1, x2, y2){
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
function updateCircle(player){
ctx.fillStyle = player.color;
ctx.beginPath();
ctx.arc(player.x, player.y, player.radius, 0, Math.PI * 2);
ctx.fill();
}
window.addEventListener("mousemove", getPosition, false);
if(moved == true){
update();
}
#canvas{
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title>Bounce</title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
但是,在我四处移动鼠标后,我注意到有些球似乎粘在了屏幕底部。
在过去的 8 个小时里,我一直在研究这个,结果却傻眼了。代码比较简单,所以我认为没有什么明显的错误。
最佳答案
你的问题是碰撞检测:
if (circle.y + circle.radius/2 > canvas.height) {
circle.velY*=-Math.sqrt(bounciness);
}
这只是反转速度,但不会调整位置。这意味着当您从特定高度掉落球时,它们可能会 卡在地面中 - 它们已经进入地面一定深度,但在下一帧中它们降低的速度不足以 em>将它们带出地面,然后再次向右倒转,使它们在地下更深一点……
你可以很容易地解决这个问题,方法是确保他们的垂直位置永远不会变成“负值”,甚至不会将球完全弹离地面:
var inGround = circle.y + circle.radius - canvas.height;
if (inGround >= 0) {
circle.velY *= -Math.sqrt(bounciness);
circle.y -= 2*inGround;
}
尝试更新的片段演示:
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext('2d');
//jupiter's gravity divided by 10 for testing purposes
g = 24.79/10;
canvas.width = window.innerWidth - 50;
canvas.height = window.innerHeight - 22.5;
bounciness = (1/2)
var spawnrate = 16;
var inertia = 0.00075;
var gravity = g/25;
players = []
then = new Date()/1000;
moved = false;
function getPosition(event){
mouseX = event.clientX;
mouseY = event.clientY;
if(moved == false){
update();
moved = true;
}
}
function addCircle(){
players.push({x: mouseX, y: mouseY, color: '#000000', radius: 10, velY: 0, velX: 2, jumped: false, jump: 0.02, max: 0});
}
first = new Date();
function update(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
t = new Date() - first;
now = new Date() / 1000;
if(now-then >= 1/spawnrate){
then = now;
addCircle();
}
for(var c = 0; c < players.length; c++){
circle = players[c];
circle.y+=circle.velY;
circle.x+=circle.velX;
circle.velX-=inertia;
circle.velY+=gravity;
if(Math.abs(circle.velY) > Math.abs(circle.max)){
circle.max = circle.velY;
}
var inGround = circle.y + circle.radius - canvas.height;
if(inGround >= 0){
circle.velY *= -Math.sqrt(bounciness);
circle.y -= 2*inGround;
}
updateCircle(circle);
if(circle.x > canvas.width){
players.splice(c, 1);
}
}
setTimeout(update, 10);
}
function drawLine(x1, y1, x2, y2){
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
function updateCircle(player){
ctx.fillStyle = player.color;
ctx.beginPath();
ctx.arc(player.x, player.y, player.radius, 0, Math.PI * 2);
ctx.fill();
}
window.addEventListener("mousemove", getPosition, false);
if(moved == true){
update();
}
#canvas{
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title>Bounce</title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
关于javascript - 为什么球会在任意时间后粘在地上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30294049/
查看此页面:http://jsbin.com/itufix使用 IE(页面自动启用 IE7 模式)。 在这里您将找到如何使用显示 block 呈现内联元素(输入和跨度)的示例。所有元素的边距和填充都设
我有一个自定义的 UITabvleViewCell,其中有一个 UIImageView。当在 cellForRowAtIndexPath 中设置单元格时,我可以很好地设置图像(尽管我没有),但是在某些
我是一名优秀的程序员,十分优秀!