简体   繁体   中英

Circle Following Mouse HTML5 Canvas jQuery

I am trying to make a circle follow the mouse in HTML Canvas which I am using in a game. I am trying to make the circle move 5px per iteration, but it goes slower when traveling horizontal and faster when it goes vertical. Here's the math that I used:

x=distance between mouse and circle on the x-axis
y=distance between mouse and circle on the y-axis
z=shortest distance between mouse and circle
a=number of units circle should move along the x-axis
b=number of units circle should move along the y axis


x^2 + y^2=z^2
Want the total distance traveled every iteration to be five pixels
a^2 + b^2 = 25
b/a=y/x
b=ay/x
a=sqrt(25-ay/x^2)
a^2+ay/x-25=0
Use Quadratic formula to find both answers
a=(-y/x+-sqrt(y/x)^2+100)/2

I replicated the problem in the code below

 $(function(){ let canvas = $("canvas")[0]; let ctx = canvas.getContext("2d"); //Gets position of mouse and stores the value in variables mouseX and mouseY let mouseX = mouseY = 0; $("canvas").mousemove(function(e){ mouseX = e.pageX; mouseY = e.pageY; }).trigger("mousemove"); let circleX = 0; let circleY = 0; function loop(t){ //Background ctx.fillStyle="blue"; ctx.fillRect(0, 0, canvas.width, canvas.height); let xFromMouse = mouseX-circleX; let yFromMouse = mouseY-circleY; let yxRatio = yFromMouse/xFromMouse; let xyRatio = xFromMouse/yFromMouse; let speed = 25; let possibleXValues = [(-yxRatio+Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2,(-yxRatio-Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2]; //I use this code as a temporary fix to stop the circle from completely disappearing if(xFromMouse === 0 || isNaN(yxRatio) || isNaN(possibleXValues[0]) || isNaN(possibleXValues[1])){ possibleXValues = [0,0]; yxRatio = 0; } //Uses b=ay/x to calculate for y values let possibleYValues = [possibleXValues[0]*yxRatio,possibleXValues[1]*yxRatio]; if(xFromMouse >= 0){ circleX += possibleXValues[0]; circleY += possibleYValues[0]; } else { circleX += possibleXValues[1]; circleY += possibleYValues[1]; } ctx.beginPath(); ctx.arc(circleX, circleY, 25, 0, 2 * Math.PI,false); ctx.fillStyle = "red"; ctx.lineWidth = 0; ctx.fill(); window.requestAnimationFrame(loop); } window.requestAnimationFrame(loop); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <canvas width="450" height="250"></canvas>

I think you may be better using a cartesian to polar conversion. Here's an example from something I made previously. This will allow you to have a consistent step per iteration "speed".

 //Canvas, context, mouse. let c, a, m = { x:0, y:0}; //onload. window.onload = function(){ let circle = {}, w, h, speed = 5; //step speed = 5 "pixels" (this will be fractional in any one direction depending on direction of travel). //setup c = document.getElementById('canvas'); a = c.getContext('2d'); w = c.width = window.innerWidth; h = c.height = window.innerHeight; function move(){ //get distance and angle from mouse to circle. let v1m = circle.x - mx, v2m = circle.y - my, vDm = Math.sqrt(v1m*v1m + v2m*v2m), vAm = Math.atan2(v2m, v1m); //if distance is above some threshold, to stop jittering, move the circle by 'speed' towards mouse. if(vDm > speed) { circle.x -= Math.cos(vAm) * speed; circle.y -= Math.sin(vAm) * speed; } } function draw(){ //draw it all. a.fillStyle = "blue"; a.fillRect(0,0,w,h); a.fillStyle = "red"; a.beginPath(); a.arc(circle.x, circle.y, circle.r, Math.PI * 2, false); a.closePath(); a.fill(); } circle = {x:w/2, y:h/2, r:25}; function animate(){ requestAnimationFrame(animate); move(); draw(); } c.onmousemove = function(e){ mx = e.pageX; my = e.pageY; }; animate(); }
 <canvas id="canvas" width="450" height="250"></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM