html5 - Ball movement path in canvas, and other ideas you may have? -
i've created animation project had use form of physics. total beginner, :) anyway, project :
you can setup gravity , force, click play, , drag , drop shoot balls. can change values , hit update see effect.
my question is, how can create effect when press ratio button (for example) can see path ball makes? complicated? saying beginner, no complex code me :)
also, doyou have ideas make project better? additional "physics" effects? or maybe know website shows tutorials simile (please) effects made in html5/js can add additional effects project.
one possibility (as you're clearing canvas each frame) draw ball paths onto secondary canvas, not cleared each frame. then, when come clear first frame, render second frame after clearing, , before rendering balls.
the second canvas of course have same dimensions first, of ball points line correctly. second canvas should have z-index lower first, shown when render first canvas (i.e. when radio button checked).
to decrease lag while radio not checked, skip drawing ball paths second canvas, although don't think see great increase in performance.
on each frame update, mark position of each ball pixel, or line (from previous position current) on second canvas.
looking @ code, seem pretty competent, i've skipped writing example think experience :)
modified 'script.js' source demonstrating solution
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 = * 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 context destination canvas //if path drawing enabled, first draw path canvas 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 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; }); }
Comments
Post a Comment