簡體   English   中英

Javascript畫布-對角彈跳球

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM