官术网_书友最值得收藏!

實驗10 瘋狂的大炮

簡介

水平拋出的物體的運動是平拋運動,與水平有一定仰角拋出的物體的運動是斜拋運動。這兩種運動都是曲線運動,統稱拋物運動。

平拋運動

物體以一定的初速度沿水平方向拋出,如果物體僅受重力作用,這樣的運動叫做平拋運動。平拋運動可視為水平方向的勻速直線運動以及豎直方向的自由落體運動的合運動。平拋運動的物體,由于所受的合外力為恒力,所以平拋運動是勻變速曲線運動,平拋物體的運動軌跡為一拋物線。平拋運動是曲線運動,平拋運動的時間僅與拋出點的豎直高度有關;物體落地的水平位移與時間(豎直高度)及水平初速度有關。平拋運動的實驗及頻閃照片如圖2-5所示。

圖2-5 平拋運動

如圖2-5(a)所示,小球A的運動是平拋運動,小球B的運動是自由落體運動,圖2-5(b)為兩個小球的運動軌跡圖。根據運動的獨立性,小球A和B應當是同時落地。現在開始在Canvas中模擬這個過程。

第一步,首先需要兩個小球,一個小球的速度為(x∶0,y∶0),另一個小球的速度為(x∶400,y∶0):

        var balls=[];
                balls.length=0;
        var ball1={
                  x: 70,
                  y: 50,
                  r: 10,
                  vx: 400,
                  vy: 0
                };
        var ball2={
                  x: 50,
                  y: 50,
                  r: 10,
                  vx: 0,
                  vy: 0
                };
                balls.push(ball1);
                balls.push(ball2);

第二步,利用Jscex循環,讓小球運動起來。

        var canvas=document.getElementById("myCanvas");
        var cxt=canvas.getContext("2d");
        var cyc=110;
        var a=80;
                cxt.fillStyle="#030303";
                cxt.fillRect(0, 0, canvas.width, canvas.height);
        var moveAsync=eval(Jscex.compile("async", function () {
        while (true) {
                      cxt.fillStyle="rgba(0, 0, 0, .3)";
                      cxt.fillRect(0, 0, canvas.width, canvas.height);
                      cxt.fillStyle="#fff";
        for (var i in balls) {
                        cxt.beginPath();    \注:根據速度,重繪所有小球的位置。\
                        cxt.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2, true);
                        cxt.closePath();
                        cxt.fill();
                        balls[i].y +=balls[i].vy * cyc / 1000;
                        balls[i].x +=balls[i].vx * cyc / 1000;
        if (balls[i].r+balls[i].y >=canvas.height) {
        if (balls[i].vy > 0) {
                              balls[i].vy *=-0.7;
                            }
                        }
        else {
                            balls[i].vy +=a;
                        }
                      }
                      $await(Jscex.Async.sleep(cyc));
                  }
                }))
                moveAsync().start();

其效果如圖2-6所示。

圖2-6 在Canvas中模擬平拋運動

斜拋運動之瘋狂的大炮

斜拋運動在很多游戲中都碰到過,如“憤怒的小鳥”,小鳥經過彈弓的作用與水平有一仰角拋出。下面制作一個無限開炮的大炮來模擬斜拋運動。

第一步,需要一張大炮的圖片,如圖2-7所示。

圖2-7 大炮素材

通過如下方式加載圖片:

        var img=new Image();
            img.src="image/artillery.png";
            img.onload=function () {
                cxt.drawImage(img, 0, 325);
            }

第二步,模擬炮彈。在每次循環時生成一個炮彈:

        var ball={
                      x: 185,
                      y: 470,
                      r: getRandomNumber(0, 20),
                      vx: getRandomNumber(190, 3000),
                      vy: getRandomNumber(-3000, 0)
                  };
                  balls.push(ball);
        if (balls.length > 100) {
                      balls.shift();
                  }

當炮彈射出數量大于100時,從balls中移除一個小球,以防止瀏覽器堆棧溢出。其中getRandomNumber方法是自定義方法,可以獲得一定范圍內的隨機數:

        function getRandomNumber(min, max) {
        return (min+Math.floor(Math.random() * (max-min+1)))
            }

第三步,Jscex循環實現大炮的猛烈轟炸:

        var fireAsync=eval(Jscex.compile("async", function () {
        while (true) {
        var ball={
                      x: 185,
                      y: 470,
                      r: getRandomNumber(0, 20),
                      vx: getRandomNumber(190, 3000),
                      vy: getRandomNumber(-3000, 0)
                  };
                  balls.push(ball);
        if (balls.length > 100) {
                      balls.shift();
                  }
                  cxt.fillStyle="rgba(0, 0, 0, .3)";
                  cxt.fillRect(0, 0, canvas.width, canvas.height);
                  cxt.fillStyle="#fff";
                  cxt.drawImage(img, 0, 425);
        for (i in balls) {
                      cxt.beginPath();
                      cxt.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2, true);
                      cxt.closePath();
                      cxt.fill();
                      balls[i].y +=balls[i].vy * cyc / 1000;
                      balls[i].x +=balls[i].vx * cyc / 1000;
        if (balls[i].r+balls[i].y >=canvas.height) {
        if (balls[i].vy > 0) {
                            balls[i].vy *=-0.7;
                        }
                      }
        else {
                        balls[i].vy +=a;
                      }
                  }
                  $await(Jscex.Async.sleep(cyc));
                }
            }))
            fireAsync().start();

以上代碼的運動效果如圖2-8所示。

圖2-8 大炮的猛烈轟炸

總結

通過這個實驗,可以更加深刻地理解運動的獨立性,了解Canvas中繪制圖片的基本方法。但是這還不夠,因為運動不僅僅在線性運動方面是獨立的,它與物體的轉動也是相互獨立的。繪制圖片時不建議直接使用drawImage,當圖片沒有加載完成,調用drawImage方法會在一些瀏覽器中拋異常。所以要在drawImage之前進行圖片的預加載。

主站蜘蛛池模板: 宜都市| 辉南县| 黔江区| 桐梓县| 阜城县| 珲春市| 霍林郭勒市| 长武县| 津市市| 丹阳市| 衢州市| 双辽市| 丁青县| 日照市| 三门峡市| 银川市| 百色市| 分宜县| 弥勒县| 石城县| 视频| 黄龙县| 盖州市| 南澳县| 女性| 泰和县| 乐山市| 平遥县| 万年县| 年辖:市辖区| 齐河县| 三原县| 密云县| 汤原县| 磴口县| 万山特区| 滦平县| 来安县| 惠安县| 内黄县| 大兴区|