[英]Javascript Canvas - Bouncing ball diagonally
因此,基本上,我正在嘗試向球添加彈跳,以更新x和y位置,而不是旋轉畫布。
這可能嗎?
這是我所擁有的,可以正確地上下左右移動。 但是對角線顯然需要更多的工作。
kick: function(fps, dir, settings){
var options = {
speed: 15,
gravity: .98,
friction: .99,
airDrag: .98,
elasticity: .8,
angle: 340,
radius: this.sWidth
}
options = deepExtend(options, settings);
var radians = options.angle * Math.PI/ 180,
vx = Math.sin(radians) * options.speed,
vy = Math.cos(radians) * options.speed;
this.ballStartPosX = this.ball.pos[0];
this.direc = dir;
this.vx = vx;
this.vy = vy;
this.friction = options.friction;
this.airDrag = options.airDrag;
this.elasticity = options.elasticity;
this.gravity = options.gravity;
this.shootBall = setInterval(this.shoot.bind(this), fps);
},
shoot: function () {
this.ball.pos[0] += this.vx;
switch(this.direc.toString()) {
case 'up': this.ball.pos[1] -= this.vy;
break;
case 'down': this.ball.pos[1] += this.vy;
break;
case 'left': this.ball.pos[0] -= this.vy;
break;
case 'right': this.ball.pos[0] += this.vy;
break;
case 'up,right': this.ball.pos[1] -= this.vy; this.ball.pos[0] += this.vy;
break;
case 'up,left': this.ball.pos[1] -= this.vy; this.ball.pos[0] -= this.vy;
break;
case 'down,right': this.ball.pos[1] += this.vy; this.ball.pos[0] += this.vy;
break;
case 'down,left': this.ball.pos[1] += this.vy; this.ball.pos[0] -= this.vy;
break;
}
if (this.ball.pos[0] > this.ballStartPosX) {
this.ball.pos[0] = this.ballStartPosX;
this.vx = -(this.vx)*this.elasticity;
}
this.vx += this.gravity;
if (this.ball.pos[0] >= this.ballStartPosX) {
this.vy *= this.friction;
}
var speed = Math.sqrt(this.vx*this.vx + this.vy*this.vy);
if (speed < this.friction) {
speed = 0;
clearInterval(this.shootBall);
}
}
這就是我想要實現的
我在想,如果我畫一條不可見的對角線並將其用作接觸點。 那行得通嗎?
最簡單的解決方案是使用旋轉的二次曲線。
順便說一句,您為什么不考慮這個最簡單的解決方案?
無論如何...
無需畫布旋轉的“手動”解決方案可以通過簡單的數學來完成,但需要許多小步驟。
解決方案包括計算二次曲線的3個控制點,然后沿二次曲線對球進行動畫處理。
這是帶注釋的示例代碼和演示: http : //jsfiddle.net/m1erickson/gQ8RC/
此代碼執行1次跳動,但可重復多次跳動。
// get references to the canvas and its context
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// save PI*2 to a variable since it's used often
var PI2=Math.PI*2;
// declare the starting and ending points of an imaginary line
var p1={x:20,y:250};
var p2={x:200,y:200};
// declare where a bounce will start & end along that line
// pct1==20%==bounce starts 20% of the way between p1 & p2
// pct2==60%==bounce ends 60% of the way between p1 & p2
var pct1=0.20;
var pct2=0.60;
// calculate deltaX & deltaY of an imaginary line
// containing starting point (p1) & ending point (p2)
var dx=p2.x-p1.x;
var dy=p2.y-p1.y;
// calculate starting point of bounce (20% from p1 towards p2)
var x1=p1.x+dx*pct1;
var y1=p1.y+dy*pct1;
// calculate ending point of bounce (60% from p1 towards p2)
var x2=p1.x+dx*pct2;
var y2=p1.y+dy*pct2;
// calculate mid point of bounce ((60-20)/2% from p1 towards p2)
var pctMidpoint=pct1+(pct2-pct1)/2;
var midX=p1.x+dx*pctMidpoint;
var midY=p1.y+dy*pctMidpoint;
// define a distance (d) for the control point of a quadratic curve
// d will indirectly determine how "high" the bounce will be
var d=75;
// calculate a quadratic curve control point on the tangent line at distance d
var ra=Math.atan2(dy,dx); // radian angle of the imaginary line
var ta=ra-Math.PI/2; // radian angle tangent to the imaginary line
var controlX=midX+d*Math.cos(ta);
var controlY=midY+d*Math.sin(ta);
// set up an animation that redraws a ball along
// the calculated quadratic curve
// T will be an interval used to determine where on the quadratic curve
// to calculate an x,y point
var T=0;
// just testing...tDirection will reverse the ball when it reaches the end of the curve
var tDirection=1;
// start the animation
requestAnimationFrame(animate);
// animate a ball along the quadratic curve
function animate(){
// request another animation frame
requestAnimationFrame(animate);
ctx.clearRect(0,0,canvas.width,canvas.height);
// calculate the balls next x,y along the curve
var point=getQuadraticBezierXYatT(
{x:x1,y:y1},
{x:controlX,y:controlY},
{x:x2,y:y2},
T/100
);
// draw the ball
ctx.beginPath();
ctx.arc(point.x,point.y,5,0,PI2);
ctx.closePath();
ctx.fillStyle="blue";
ctx.fill();
// Move the ball to the next interval on the curve
// Reverse direction when the ball reaches the start/end of the curve
T+=tDirection;
if(T<0 || T>100){
tDirection*=-1;
T+=tDirection;
}
}
// calculate an x,y point along a quadratic curve at interval T
function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x;
var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y;
return( {x:x,y:y} );
}
(只需提及沿斜坡上升的球的物理行為就不會像您所說明的那樣)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.