0

我为我的项目创建了这个动画,该动画必须使用任何形式的物理。我也是一个初学者:)无论如何,这是我现在的项目:

弹跳球

您可以设置重力和力,然后单击播放,然后只需拖放即可射球。您可以更改值并点击更新也可以看到效果。

我的问题是,如何创建一种效果,当我按下比率按钮(例如)时,我可以看到球的路径?复杂吗?正如我所说,我是初学者,所以对我来说没有复杂的代码:)

另外,您有什么想法可以使项目变得更好吗?任何额外的“物理”效应?或者,也许您知道一个网站,其中显示了用 HTML5/js 制作的明喻(请)效果教程,这样我就可以为我的项目添加额外的效果。

4

1 回答 1

1

一种可能性(当您每帧清除画布时)是将球路径绘制到辅助画布上,该画布不会每帧都被清除。然后,当您要清除第一帧时,在清除后渲染第二帧,然后再渲染球。

第二个画布当然必须与第一个画布的尺寸相同,以便所有球点正确排列。第二个画布的 z-index 也应该低于第一个,以便仅在您专门将其渲染到第一个画布时(即选中单选按钮时)才显示它。

要减少未检查无线电时的任何延迟,您可以跳过将球路径绘制到第二个画布,尽管我认为您不会看到性能有任何显着提高。

在每次更新帧时,您将在第二个画布上用像素或线(从前一个位置到当前位置)标记每个球的位置。

看看你的代码,你似乎很能干,所以我跳过了写一个例子,因为我认为这对你来说是很好的体验:)

修改后的“script.js”源代码演示解决方案

window.onload = function(){
    $("#canvas").hide();

    var howManyPaths = 0;   
    var showPath=false;

    // SLIDERS
    var gravitySlider = document.getElementById('gravitySlider');
    var gravityVal = document.getElementById('gravityValue');

    gravitySlider.onchange = function(){
        gravityVal.value = gravitySlider.value;
    }

    gravityVal.onkeyup = function(){
          gravitySlider.value = gravityVal.value;      
    } 

    var forceSlider = document.getElementById('forceSlider');
    var forceValue = document.getElementById('forceValue');

    forceSlider.onchange = function(){
        forceValue.value = forceSlider.value;
    }

    forceValue.onkeyup = function(){
          forceSlider.value = forceValue.value;      
    } 

    // GLOBAL VARIABLES
    var test = false;
    var gravityCount = $("#gravity").val();
    var forceCount = $("#rectangles").val();    

    // CSS :
    var playCSS = document.getElementById("play");
    var restartCSS = document.getElementById("restart");
    var clickableCSS = document.getElementById("setup");
    var clickableBG = document.getElementById("img");

    //restartCSS.style.visibility="hidden";

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    var canvas2 = document.getElementById("canvas2");
    var ctx2 = canvas2.getContext("2d");


    //var ctx;
    var gravity = 9.86;
    var forceFactor = 0.5;
    var mouseDown = false;
    var balls = new Array();
    var mousePos = new Array();

    // EVENT HANDLER
    function onMouseDown(evt){
        mouseDown = true;
        mousePos['downX'] = evt.pageX;
        mousePos['downY'] = evt.pageY;
    }

    function onMouseUp(evt){
        mouseDown = false;


        setup.style.visibility="visible";


        if(test == true && !( mousePos['downX'] < 200 && mousePos['downY'] < 150) ){

        restartCSS.style.visibility="visible";

        forceFactor = forceCount;



        balls.push(new ball(mousePos["downX"],
                            mousePos["downY"],
                            (evt.pageX - mousePos["downX"]) * forceFactor,
                            (evt.pageY - mousePos["downY"]) * forceFactor,
                            10 + (Math.random() * 10),
                            0.8,
                            randomColor()
                    ));
        }
        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
    }

    function onMouseMove(evt){
        mousePos['currentX'] = evt.pageX;
        mousePos['currentY'] = evt.pageY;   
    }

    function resizeWindow(evt){
        //canvas.height = 960;
        //canvas.width = 720;
        canvas.height = $(window).height()-6;
        canvas.width = $(window).width();

        canvas2.height = $(window).height()-6;
        canvas2.width = $(window).width();
    }

    $(document).mousedown(onMouseDown);
    $(document).mouseup(onMouseUp);
    $(document).mousemove(onMouseMove);

    $(window).bind("resize", resizeWindow);

    // GRAPHICS CODE
        function circle(x, y, r, col){
            ctx.beginPath();
            ctx.arc(x, y, r, 0, Math.PI*2, true);
            ctx.closePath;

            // fill         
            ctx.fillStyle = col;
            ctx.fill();

            // stroke
            ctx.lineWidth = r * 0.1;
            ctx.strokeStyle = "#000000";
            ctx.stroke();   
}




function circlePath(x, y)
{
    ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
    ctx2.fillStyle = '#3f4043';
    ctx2.fillRect(x, y, 5, 5);
    ctx2.strokeStyle = "black";
    ctx2.strokeRect(x, y, 5, 5);
}





        function randomColor(){
            var letter = "0123456789ABCDEF".split("");
            var color = "#";

            for(var i=0; i<6; i++){
                color += letter[Math.round(Math.random()*15)];  
            }

            return color;
            }

        function arrow(fromX, fromY, toX, toY, color){
            // path
            ctx.beginPath();
            var headLen = 10;
            var angle = Math.atan2(toY - fromY, toX - fromX);
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);

            ctx.lineTo(toX - headLen * Math.cos(angle - Math.PI/6), toY - headLen * Math.sin(angle - Math.PI/6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLen * Math.cos(angle + Math.PI/6), toY - headLen * Math.sin(angle + Math.PI/6));

            // style
            ctx.lineWith = 1;
            ctx.strokeStyle = color;
            ctx.lineCap = "butt";
            ctx.stroke();
        }


        function drawBall(){

            // Gravity
            gravity = gravityCount;

            this.speedY += gravity * 0.5; // v = a * t
            this.x += this.speedX * 0.05; // s = v * t
            this.y += this.speedY * 0.05;

            // prawa ściana
            if(this.x + this.r > canvas.width){
                this.x = canvas.width - this.r;
                this.speedX *= -1 * this.bounce;    
            }

            // lewa ściana
            if(this.x - this.r < 0){
                this.x = this.r;
                this.speedX *= -1 * this.bounce;    
            }

            // dolna ściana
            if(this.y + this.r > canvas.height){
                this.y = canvas.height - this.r;
                this.speedY *= -1 * this.bounce;

            }

            // górna ściana
            if(this.y - this.r < 0){
                this.y = this.r;
                this.speedY *= -1 * this.bounce;
            }

                        // zwalnianie na ziemi
            if (this.speedX > 0.25){
                this.speedX -= 0.25;
                    if (this.speedY > 0.25)
                        this.speedY -= 0.25;
            }

            if (this.speedX < -0.25){
                this.speedX += 0.25;
                    //if (this.speedY < -0.25)
                    //  this.speedY += 0.25;
            }

            circle(this.x, this.y, this.r, this.col);;

        }

    // OBJECTS
        function ball(positionX, positionY, sX, sY, radius, b, color){
            this.x = positionX;
            this.y = positionY;
            this.speedX = sX;
            this.speedY = sY;
            this.r = radius;
            this.bounce = b;    
            this.col = color;

            this.draw = drawBall;
        }

    //GAME LOOP
        function gameLoop(){
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            //grab the context from your destination canvas

            //if path drawing is enabled, first draw the path canvas to the display canvas
            if (showPath) ctx.drawImage(canvas2,0,0);

            if(mouseDown == true){
                 // ctx.clearRect(0, 0, canvas.width, canvas.height); /* !important !!!!!!!!!!!!!!! */
                 arrow(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY'], "red");
            }

            for(var i=0; i<balls.length; i++){
                balls[i].draw();
                if (i==balls.length-1) {
                    //draw path
                    ctx2.fillStyle = '#3f4043';
                    ctx2.fillRect(balls[i].x, balls[i].y, 5, 5);
                    ctx2.strokeStyle = "black";
                    ctx2.strokeRect(balls[i].x, balls[i].y, 5, 5);     
                }
            }

            ctx.fillStyle = "#000000";
            ctx.font = "15px Arial";
            ctx.fillText("Balls: " + balls.length + " " + gravityCount + " " + forceCount + " " + howManyPaths, 10, canvas.height -10);

        }
    // START THE GAME
    function init(){
        //$("#setup").hide();
        $("#canvas").show();
        $("#canvas2").hide();
        ctx = $('canvas')[0].getContext("2d");      
        canvas.height = $(window).height()-6;
        canvas.width = $(window).width();
        //canvas.width = 960;
        //canvas.height = 720;
        canvas2.height = $(window).height()-6;
        canvas2.width = $(window).width();
        return setInterval(gameLoop, 10);
    }

    $("#play").click(function() {   
        test = true;
        playCSS.style.visibility="hidden";
        gravityCount = $("#gravitySlider").val();
        forceCount = $("#forceSlider").val();
        init();

    });

    $("#restart").click(function() {    
        window.location.href="index.html";
    });

    $("#refresh").click(function() {    
        gravityCount = $("#gravitySlider").val();
        forceCount = $("#forceSlider").val();
    }); 

    $("#showPath").click(function() {   
        showPath=true;
    }); 

    $("#hidePath").click(function() {   
        showPath=false;
    });
}
于 2013-05-10T10:06:30.627 回答