gpt4 book ai didi

javascript - 找到反弹的峰值

转载 作者:行者123 更新时间:2023-11-28 18:39:30 24 4
gpt4 key购买 nike

我想捕捉反弹的峰值 Y 位置。因此,每次球弹跳时,我都想捕获该弹跳时达到的最高 Y 轴值。

所以我知道第一个值是球的起始 Y 位置。但是我不确定如何捕获后续值。

*** 请全屏运行示例

'use strict';

// Todo
// - Make the ball spin
// - Make the ball squish
// - Add speed lines
// - Clear only the ball not the whole canvas


(function () {

const canvas = document.getElementsByClassName('canvas')[0],
c = canvas.getContext('2d');


// -----------------------------------
// Resize the canvas to be full screen
// -----------------------------------

window.addEventListener('resize', resizeCanvas, false);

function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// ---------
// Variables
// ---------

var circleRadius = 40,
circleHeight = circleRadius * 2,
x = (canvas.width/2) - circleRadius, // inital x position of the ball
y = (canvas.height/2) - circleRadius, // inital y position of the ball
fallHeight = y,
vx = 0, // velocity
vy = 0, // velocity
groundHeight = circleHeight,
bouncePoints = [],
gravity = 0.8,
dampening = 0.5,
pullStrength = 0.04,
segments = 4,
bezieCircleFormula = (4/3)*Math.tan(Math.PI/(2*segments)), // http://stackoverflow.com/a/27863181/2040509
pointOffset = {
positive: bezieCircleFormula*circleRadius,
negative: circleRadius-(bezieCircleFormula*circleRadius)
},
// Each side has 3 points, bezier 1, circle point, bezier 2
// These are listed below in clockwise order.
// So top has: left bezier, circle point, right bezier
// Right has: top bezier, circle point, bottom bezier
circlePoints = {
top: [
[x+pointOffset.negative, y],
[x+circleRadius, y],
[x+pointOffset.positive+circleRadius, y]
],
right: [
[x+circleHeight, y+pointOffset.negative],
[x+circleHeight, y+circleRadius],
[x+circleHeight, y+pointOffset.positive+circleRadius]
],
bottom: [
[x+pointOffset.positive+circleRadius, y+circleHeight],
[x+circleRadius, y+circleHeight],
[x+pointOffset.negative, y+circleHeight]
],
left: [
[x, y+pointOffset.positive+circleRadius],
[x, y+circleRadius],
[x, y+pointOffset.negative]
]
};



// --------------------
// Ball squish function
// --------------------
// For `side` you can pass `top`, `right`, `bottom`, `left`
// For `amount` use an interger

function squish (side, squishAmount) {
for (let i = 0; i < circlePoints[side].length; i++) {
if (side === 'top') {
circlePoints[side][i][1] += squishAmount;
} else if (side === 'right') {
circlePoints[side][i][0] -= squishAmount;
} else if (side === 'bottom') {
circlePoints[side][i][1] -= squishAmount;
} else if (side === 'left') {
circlePoints[side][i][0] += squishAmount;
}
}
}

var drop = 1;

console.log('drop ' + drop + ': ' + y);


// ------------------
// Animation Function
// ------------------

function render () {

// Clear the canvas
c.clearRect(0, 0, canvas.width, canvas.height);



// -----------------
// Draw the elements
// -----------------

// Ground
c.beginPath();
c.fillStyle = '#9cccc8';
c.fillRect(0, canvas.height - groundHeight, canvas.width, groundHeight);
c.closePath();

// Shadow
let distanceFromGround = parseFloat(((y - canvas.height/2) + circleHeight) / (canvas.height/2 - groundHeight/2)).toFixed(4),
shadowWidth = circleRadius * (1-distanceFromGround+1),
shadowHeight = circleRadius/6 * (1-distanceFromGround+1),
shadowX = (x + circleRadius) - shadowWidth/2,
shadowY = canvas.height - groundHeight/2,
shadowOpacity = 0.15 * distanceFromGround; // The first value here represents the opacity that will be used when the ball is touching the ground

c.beginPath();
c.fillStyle = 'rgba(0,0,0, ' + shadowOpacity + ')';
c.moveTo(shadowX, shadowY);
c.bezierCurveTo(shadowX, shadowY - shadowHeight, shadowX + shadowWidth, shadowY - shadowHeight, shadowX + shadowWidth, shadowY);
c.bezierCurveTo(shadowX + shadowWidth, shadowY + shadowHeight, shadowX, shadowY + shadowHeight, shadowX, shadowY);
c.fill();
c.closePath();

// Bezier circle
c.beginPath();
c.fillStyle = '#cf2264';
c.moveTo(circlePoints.left[1][0], circlePoints.left[1][1]);
c.bezierCurveTo(circlePoints.left[2][0], circlePoints.left[2][1], circlePoints.top[0][0], circlePoints.top[0][1], circlePoints.top[1][0], circlePoints.top[1][1]);
c.bezierCurveTo(circlePoints.top[2][0], circlePoints.top[2][1], circlePoints.right[0][0], circlePoints.right[0][1], circlePoints.right[1][0], circlePoints.right[1][1]);
c.bezierCurveTo(circlePoints.right[2][0], circlePoints.right[2][1], circlePoints.bottom[0][0], circlePoints.bottom[0][1], circlePoints.bottom[1][0], circlePoints.bottom[1][1]);
c.bezierCurveTo(circlePoints.bottom[2][0], circlePoints.bottom[2][1], circlePoints.left[0][0], circlePoints.left[0][1], circlePoints.left[1][0], circlePoints.left[1][1]);
c.stroke();
c.closePath();



// -------------------------------
// Recalculate circle co-ordinates
// -------------------------------

circlePoints = {
top: [
[x+pointOffset.negative, y],
[x+circleRadius, y],
[x+pointOffset.positive+circleRadius, y]
],
right: [
[x+circleHeight, y+pointOffset.negative],
[x+circleHeight, y+circleRadius],
[x+circleHeight, y+pointOffset.positive+circleRadius]
],
bottom: [
[x+pointOffset.positive+circleRadius, y+circleHeight],
[x+circleRadius, y+circleHeight],
[x+pointOffset.negative, y+circleHeight]
],
left: [
[x, y+pointOffset.positive+circleRadius],
[x, y+circleRadius],
[x, y+pointOffset.negative]
]
};



// -----------------
// Animation Gravity
// -----------------


// Increment gravity
vy += gravity;

// Increment velocity
y += vy;
x += vx;



// ----------
// Boundaries
// ----------

// Bottom boundary
if (y + circleHeight > canvas.height - groundHeight/2) {
y = canvas.height - groundHeight/2 - circleHeight;
vy *= -1;

// Dampening
vy *= dampening;
vx *= dampening;

// If the Y velocity is less than the value below, stop the ball
if (vy > -2.4) {
dampening = 0;
}

fallHeight = fallHeight*dampening;

if (drop < 5) {
drop++;
console.log('drop ' + drop + ': ' + y);
}
}

// Right boundary
if (x + circleHeight > canvas.width) {
x = canvas.width - circleHeight;
vx *= -1;

// Dampening
vy *= dampening;
vx *= dampening;
}

// Left boundary
if (x + circleHeight < 0 + circleHeight) {
x = 0;
vx *= -1;

// Dampening
vy *= dampening;
vx *= dampening;
}

// Top boundary
if (y < 0) {
y = 0;
vy *= -1;

// Dampening
vy *= dampening;
vx *= dampening;
}

requestAnimationFrame(render);
}



// -----------
// Click event
// -----------

canvas.addEventListener('mousedown', function (e) {
let dx = e.pageX - x,
dy = e.pageY - y;

if (dampening === 0) {
dampening = 0.5;
}

vx += dx * pullStrength;
vy += dy * pullStrength;

});

render();

}
resizeCanvas();

})();
body{
margin: 0;
}

canvas {
background: #ddf6f5;
display: block;
}
<canvas class="canvas"></canvas>

最佳答案

伪代码:

// begin with an overly large seed for the minimum Y value
var minY=1000000;

// whenever the circle changes position, save the minimum of minY & currentY
minY=Math.min(minY,currentY);

如果您想要圆的圆周的顶部,请减去circleRadius

关于javascript - 找到反弹的峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36361600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com