HTML5实验室
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

实验2 台球

简介

台球源于英国,它是一项在国际上广泛流行的高雅的室内体育运动,是一种用球杆在台上击球,依靠计算得分确定比赛胜负的室内娱乐体育项目。台球也称为桌球(中国港、澳地区的称法)、撞球(中国台湾地区的称法)。在没有开球之前,每个球的摆放位置如图1-8所示。

图1-8 桌球

这次,要绘制的就是类似图1-8的效果。在绘制之前,先来绘制实心圆。

实心圆

CanvasRenderingContext2D提供了fill函数,为一个封闭的区域内填充颜色,如圆形、矩形等。实心圆和空心圆的区别在于:

● 设置实心圆颜色:CanvasRenderingContext2D.fillStyle;

● 设置空心圆路径颜色:CanvasRenderingContext2D.strokeStyle;

● 填充实心圆:CanvasRenderingContext2D.fill;

● 连接空心圆路径:CanvasRenderingContext2D.stroke。

掌握了这些,可以轻松地在Canvas中画一个实心圆:

        <canvasid="myCanvas"width="200"height="100"style="border:1px solid #c3c3c3;">
        Your browser does not support the canvas element.
        </canvas>
        <scripttype="text/javascript">
        var c=document.getElementById("myCanvas");
        var cxt=c.getContext("2d");
            cxt.fillStyle="#FF7F00";
            cxt.beginPath();
            cxt.arc(70, 18, 15, 0, Math.PI * 2, true);
            cxt.closePath();
            cxt.fill();
        </script>

效果如图1-9所示。

图1-9画圆

实心圆

掌握了画实心圆,就可以开始绘制台球桌面上的16个小球(包括母球)了。在绘制之前,先复习一下初等几何知识,一个直角三角形,如果有一个角为30°,那么三角形的三个边的比例如图1-10所示。

图1-10 三角形各边比例

再回到要绘制的台球,如图1-11所示。最外层的圆心连成的三角形是等边三角形,然后被分成两个直角三角形,等边三角形的3个角都是60°,所以被分成的直角三角形的三个边的比例是

图1-11 桌球布局分析

假设母球和离母球最近的顶部的球的位置分别如下:

        var parentBall={
              position: { x: 200, y: 200 },
              r: r,
              color: "#fff"
            };
        var firstBall={
              position: { x: 550, y: 200 },
              r: r,
              color: "#fff"
            };

这里用了面向对象的思想分别定义了小球的位置、半径和颜色。知道了顶部小球的位置,加上上面的分析,可以生成后面一系列小球的坐标:

         for (var j=1; j < 5; j++) {
        for (var k=0; k < j+1; k++) {
        var ball={
                      position: { x: firstBall.position.x+j * Math.sqrt(3) * r, y: firstBall.position.y -
                      j * r+2 * k * r },
                      r: r,
                      color: "#fff"
                  };
                  balls.push(ball);
              }
            }

把所有生成的球放入一个balls的数组当中,然后调用CanvasRenderingContext2DAPI,根据小球的坐标、颜色和半径,把所有小球绘制出来:

            cxt.fillStyle="#fff";
        for (i in balls) {
              cxt.beginPath();
              cxt.arc(balls[i].position.x, balls[i].position.y, balls[i].r, 0, Math.PI * 2, true);
              cxt.closePath();
              cxt.fill();
            }

完整的代码如下:

        <canvasid="myCanvas"width="847"height="440"style="background-color:#000000">
        Your browser does not support the canvas element.
        </canvas>
        <script>
        var canvas=document.getElementById("myCanvas");
        var cxt=canvas.getContext("2d");
        var r=10;
        var balls=[];
        function initBall() {    \注:initBall方法生成所有的小球\
        var parentBall={
                  position: { x: 200, y: 200 },
                  r: r,
                  color: "#fff"
              };
        var firstBall={
                  position: { x: 550, y: 200 },
                  r: r,
                  color: "#fff"
              };
        for (var j=1; j < 5; j++) {
        for (var k=0; k < j+1; k++) {    \注:根据 firstBall的坐标,通过两个嵌套的for循环生成所有小球坐标\
        var ball={
                        position: { x: firstBall.position.x+j * Math.sqrt(3) * r, y: firstBall.position.y -
                        j * r+2 * k * r },
                        r: r,
                        color: "#fff"
                      };
                      balls.push(ball);
                  }
              }
              balls.push(firstBall);
              balls.push(parentBall);
            }
        function draw() {
              cxt.fillStyle="#fff";
        for (i in balls) {
                  cxt.beginPath();
                  cxt.arc(balls[i].position.x, balls[i].position.y, balls[i].r, 0, Math.PI * 2, true);
                  cxt.closePath();
                  cxt.fill();
              }
            }
            initBall();
            draw();
        </script>

运行效果如图1-12所示。

图1-12 在Canvas上模拟绘制

当然,也可以在初始化小球时让每个小球产生一个随机颜色,利用下面这种方法产生随机颜色。

        function randomColor() {
        var arrHex=["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]; var strHex="#";
        var index;
        for (var i=0; i < 6; i++) {
                  index=Math.round(Math.random() * 15);
                  strHex +=arrHex[index];
              }
        return strHex;
            }

在初始化小球时调用该方法。

        var firstBall={
              position: { x: 550, y: 200 },
              r: r,
              color: randomColor()    \注:产生随机颜色\
            };
        for (var j=1; j < 5; j++) {
        for (var k=0; k < j+1; k++) {
        var ball={
                      position: { x: firstBall.position.x+j * Math.sqrt(3) * r, y: firstBall.position.y -
                      j * r+2 * k * r },
                      r: r,
                      color: randomColor()    \注:产生随机颜色\
                  };
                  balls.push(ball);
              }
            }

在画球时直接使用小球的color属性即可。

        function draw() {
        for (i in balls) {
                  cxt.fillStyle=balls[i].color;    \注:在这里使用\
                  cxt.beginPath();
                  cxt.arc(balls[i].position.x, balls[i].position.y, balls[i].r, 0, Math.PI * 2, true);
                  cxt.closePath();
                  cxt.fill();
              }
            }

效果如图1-13所示。

图1-13 彩色桌球

通过这个实验,学习了基本的绘制实心圆的方法,并通过不同颜色的小球模拟出桌球的初始摆放。在真实的游戏开发当中,会让美工画好具有反光和立体感的小球,然后把对应的位置填上相应的小球图片,就可以达到最终想要的效果。