你可能在画布上球的移动路径,以及其他的想法? [英] Ball movement path in canvas, and other ideas you may have?

查看:116
本文介绍了你可能在画布上球的移动路径,以及其他的想法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创造了这个动画,我的项目,必须使用任何形式的物理。
我是一个总的初学者,太:)无论如何,这是我的项目现在:

I've created this animation for my project that had to use any form of physics. I am a total beginner, too :) Anyway, this is my project now :

弹弹球

您可以设置重力和力量,然后点击播放,只是拖放拍摄球。你可以改变这些值和命中更新也看到效果。

You can setup gravity and force, then click play, and just drag and drop to shoot the balls. You can change the values and hit update too see an effect.

我的问题是,我怎么可以创建一个效果,当我$(例如)p $ PSS比例按钮,我可以看到球使得路径?是否复杂?正如我说我是个初学者,所以没有复杂的code对我来说:)

My question is, how can I create an effect that when I press ratio button (for example) I can see the path that ball makes? Is it complicated? As I was saying I am a beginner, so no complex code for me :)

另外,你当有什么想法,使项目更好?任何额外的物理的效果?或者,也许你知道一个网站,显示的教程喻(请)在HTML5 / JS做,所以我可以添加额外的效果,我的项目的效果。

Also, doyou have any ideas to make the project better? Any additional "physics" effects? Or maybe you know a website that shows tutorials for simile (please) effects made in HTML5/js so I can add additional effects to my project.

推荐答案

一种可能性(因为您清空画布每一帧)将提请球道到辅助画布上,这不会每一帧被清除。然后,当你来到清第一帧,使第二帧清除后,和渲染球前。

One possibility (as you're clearing the canvas each frame) would be to draw ball paths onto a secondary canvas, which would not be cleared each frame. Then, when you come to clear the first frame, render the second frame after clearing, and before rendering the balls.

第二画布当然会需要成为相同的尺寸的第一,使所有的球点的正确排列。第二画布也应该有一个z索引低于第一,以便它仅示出当具体地说它呈现给第一画布(即当单选按钮被选中)。

The second canvas would of course have to be the same dimensions as the first, so that all of the ball points line up correctly. The second canvas should also have a z-index lower than the first, so that it is only shown when you specifically render it to the first canvas (i.e. when the radio button is checked).

要减少任何滞后,而没有被选中的收音机,你可以跳过绘制路径球到第二帆布,但我不认为你会看到任何性能上的大幅增加。

To decrease any lag while the radio is not checked, you could skip drawing the ball paths to the second canvas, although I don't think you would see any great increase in performance.

在每一帧更新,将标志着每个球的一个像素,或线(由previous位置设置为当前)第二画布上的位置。

On each frame update, you would mark the position of each ball with a pixel, or line (from the previous position to the current) on the second canvas.

看你的code,你似乎pretty胜任,所以我写跳过一个例子,因为我认为这将是对你很好的经验:)

Looking at your code, you seem pretty competent, so I've skipped writing an example as I think this would be good experience for you :)

修改的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;
    });
}

这篇关于你可能在画布上球的移动路径,以及其他的想法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆