简体   繁体   中英

Projectile Motion Simulation in HTML5 JavaScript canvas

I'm looking to simulate projectile motion (off the ground with a certain velocity, continuing until the ball lands on the ground again) ignoring air resistance. I'm using the canvas feature of HTML5 and JavaScript to do it. I'm a novice with JavaScript, so any help is appreciated.

This is my code so far. I'm running into the same error again and again: unexpected end of input. I'm also trying to include start, stop, and reset buttons, as well as the option for the user to input their own angle, so they can see the final horizontal distance change.

I've tried many different ways to get rid of this error; what am I missing?

<html>

<head>
    <title>
    Projectile Motion
    </title>
</head>

<body>

<button onclick=settimer()>Start</button><br>
<button onclick=reset()>Reset</button><br>
<button onclick=cleartimer()>Stop</button><br>
Angle=<input type="text" id="Angle in Degrees" value=45></input>
<canvas id="mycanvas" height="600" width="600"></canvas>

<script>

function rectang() {
co.beginPath();
co.rect(0,0,600,600);
co.stroke();
}

var gravity
var Angle
var velocity
var velocityx
var velocityy
var distance
var co
var inc
var time
var x
var y
var radius



//list variables

function init() {
    var can;
    can = document.getElementById("mycanvas");
    co = can.getContext("2d");
    reset();
}

function reset() {
    gravity = 5;
    Angle = (45*(Math.PI)/180);
    velocity = 10;
    velocityx = velocity*Math.cos(Angle);
    velocityy = velocity*Math.sin(Angle);
    time = 0;
    distance = velocityx*time;
    inc = 0.5;
    x = 0;
    y = 600;
    radius = 10;
}

function draw() {
    co.clearRect(0,0,600,600);
    circle(co,x,y,radius,"yellow",false)

    time = time + inc;
    x = x + velocityx*time;
    y = y + velocityy*time;
    velocityx = velocityx;
    velocityy = velocityy + velocityy*time;
}


function settimer() {
    if (timer == null) timer = setInterval(draw,time);
    Angle = document.getElementById("Angle").value;
}
function cleartimer(){
    clearInterval(timer);
    timer = null;
}

init();


function circle(context,x,y,r,color,fill) {
    if (fill == true) {
        //if fill is true, fill the circle
        var temp = context.fillStyle;
        context.fillStyle = color;
        context.beginPath();
        context.arc(x,y,r,0,2*Math.PI);
        context.fill();
        context.fillStyle = temp;
    }
    else {
        //if fill is false, don't fill the circle
        var temp = context.strokeStyle;
        context.strokeStyle = color;
        context.beginPath();
        context.arc(x,y,r,0,2*Math.PI);
        context.stroke();
        context.strokeStyle = temp;
    }


</script>

</body>

</html>

There are some issues, mainly some kind of double-incrementing, where "time" was getting larger each loop, and x/y values were incrementing itself too. Also, for "velocityy" you should rather use negative value at start (bullet getting higher) and then add something based on gravity. And yellow isn't very readable here.

 function rectang() { co.beginPath(); co.rect(0,0,600,600); co.stroke(); } var gravity var Angle var velocity var velocityx var velocityy var distance var co var inc var time var x var y var radius //list variables function init() { var can; can = document.getElementById("mycanvas"); co = can.getContext("2d"); reset(); } function reset() { gravity = 5; Angle = (45*(Math.PI)/180); velocity = 10; velocityx = velocity*Math.cos(Angle); velocityy = velocity*Math.sin(Angle)*-1; time = 0; distance = velocityx*time; inc = 0.5; x = 0; y = 300; radius = 10; } function draw() { //console.log(x,y) co.clearRect(0,0,600,300); circle(co,x,y,radius,"yellow",false) time = time + inc; x = x + velocityx*inc; y = y + velocityy*inc; velocityx = velocityx; velocityy = velocityy + gravity*inc*0.1; } var timer = null; function settimer() { if (timer == null) timer = setInterval(draw,time); Angle = document.getElementById("Angle").value; } function cleartimer(){ clearInterval(timer); timer = null; } init(); function circle(context,x,y,r,color,fill) { x = Math.round(x) y = Math.round(y) //console.log(x,y,r,color,fill) if (fill == true) { //if fill is true, fill the circle var temp = context.fillStyle; context.fillStyle = color; context.beginPath(); context.arc(x,y,r,0,2*Math.PI); context.fill(); context.fillStyle = temp; } else { //if fill is false, don't fill the circle var temp = context.strokeStyle; context.beginPath(); context.arc(x,y,r,0,2*Math.PI); context.strokeStyle = color; context.lineWidth = 4; context.stroke(); context.strokeStyle = temp; } } 
 <button onclick=settimer()>Start</button><br> <button onclick=reset()>Reset</button><br> <button onclick=cleartimer()>Stop</button><br> Angle=<input type="text" id="Angle" value=45></input> <canvas id="mycanvas" height="300" width="600"></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