Javascript错误:无法读取带有画布标签的null属性'getContext'

时间:2018-12-18 06:38:43

标签: javascript html html5 canvas

我创建了一个画布,但是我不断收到错误消息,说它无法在init()函数中的第169行获得null的上下文。我在脚本的开头创建了变量“ canvas”,并使用“ canvas = document.getElementById(“ canvas”)”将其设置为我的canvas标记,但它仍然说它为null。这是给定于星期三进行的学校项目,我对用画布标签绘画很不好-请帮助:)

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8"/>

        <title>Emma Wood | Space Invaders II</title>

        <link href="https://fonts.googleapis.com/css?family=Unlock" rel="stylesheet">

        <link rel="icon" type="image/png" href="WebsiteImages/computer.png">

        <link rel="stylesheet" href="SI2_StyleSheet.css">

        <script type="text/javascript">
        //TO DO: health bar for alien doesn't work, show message for win or lose or forfeit @ end of game, create cool instructions (flash project(?)
            var canvas;
            var ctx;
            var WIDTH = 1000;
            var HEIGHT = 400;

            //variables for the avatar
            var dx = 5;
            var dy = 5;
            var x = 80;
            var xRight = 120;
            var y = 210;
            var yDown = 320;
            var OnOff = 1 * 1;
            var healthAvatar = 130;

            //variables for the invader
            var xCoord = 910;
            var xCoordRight = 950;
            var yCoord = 210;
            var yCoordDown = 320;
            var OnOff2 = 1 * 1;
            var healthInvader = 130;

            //variables for the bullets
            var bulletNumber = 0 * 1; // this is the number of the bullet that is being shot 
            var bulletX = new Array(100); // this is the x position of the bullet relative to its original position 
            var bulletY = new Array(100); // this is the y position of the bullet relative to its original position
            var bulletOnOff = new Array(100); // this determines whether or not the bullet is moving, 1 = up, 2 = left, 3 = down, 4 = right

            for (var z = 0; z < 100; z++)
            {
                bulletX[z] = 0; 
                bulletY[z] = 0; 
                bulletOnOff[z] = 0; 
            }

            init();

            function circle(x,y,r) 
                {
                    ctx.beginPath();
                    ctx.arc(x, y, r, 0, Math.PI*2, true);
                    ctx.closePath();
                    ctx.fill();
                }


            function rect(x,y,w,h) 
                {
                    ctx.beginPath();
                    ctx.rect(x,y,w,h);
                    ctx.closePath();
                    ctx.fill();
                    ctx.stroke();
                }

            function clear() 
                {
                    ctx.clearRect(0, 0, WIDTH, HEIGHT);
                }

            function startTimer()
                {
                    var buttonName = document.getElementById("move").value;

                    if (buttonName == "Begin")
                    {

                        timer = setInterval("moveInvader()", 200);
                        document.getElementById("move").value = "Quit";
                        window.addEventListener('keydown',doKeyDown,true);
                    }
                    else 
                    {
                        endGame();
                    }
                }

            function moveBullet()
                {
                    for (var f = 0; f < 100; f++)
                    {
                        if (bulletOnOff[f] == 1)
                        {
                            //this moves the bullet up
                            bulletY[f] += 10;
                        }
                        else if (bulletOnOff[f] == 2)
                        {
                            //this moves the bullet left
                            bulletX[f] -= 10;
                        }
                        else if (bulletOnOff[f] == 3)
                        {
                            //this moves the bullet down
                            bulletY[f] -= 10;
                        }
                        else if (bulletOnOff[f] == 4)
                        {
                            //this moves the bullet right
                            bulletX[f] += 10;
                        }

                        //checks to see if the bullet is going outside the boundaries
                        if (bulletX[f] < 0 || bulletX[f] > 1000 || bulletY[f] < 0 || bulletY[f] > 400)
                        {
                            bulletOnOff[f] = 0;
                        }
                    }
                    checkHealth();
                    draw();
                }

            function endGame()
                {
                    clear();
                    clearInterval(timer);
                    clearInterval(bulletTimer);
                    window.removeEventListener('keydown',doKeyDown,true);

                    //clearing the bullets
                    for (var z = 0; z < 100; z++)
                    {
                        bulletX[z] = 0; 
                        bulletY[z] = 0; 
                        bulletOnOff[z] = 0; 
                    }
                    bulletNumber = 0;

                    //variables for the avatar
                    x = 80;
                    xRight = 120;
                    y = 210;
                    yDown = 320;
                    OnOff = 1 * 1;
                    healthAvatar = 130;

                    //variables for the invader
                    xCoord = 910;
                    xCoordRight = 950;
                    yCoord = 210;
                    yCoordDown = 320;
                    OnOff2 = 1 * 1;
                    healthInvader = 130;

                    document.getElementById("move").value = "Begin";
                    init();
                }

            function init() 
                {
                    bulletTimer = setInterval("moveBullet()", 200);
                    canvas = document.getElementById("canvas");
                    ctx = canvas.getContext("2d");
                    draw();
                    return 
                }

            function doKeyDown(evt)
                {
                    switch (evt.which) 
                    {
                        case 38:  

                        y -= dy;
                        yDown -= dy;
                        checkHealth();  

                        break;
                        case 40: 

                        y += dy;
                        yDown += dy;
                        checkHealth();

                        break;
                        case 37:  

                        x -= dx;
                        xRight -= dx;
                        OnOff = 2 * 1;
                        checkHealth();

                        break;
                        case 39: 

                        x += dx;
                        xRight += dx;
                        OnOff = 1 * 1;
                        checkHealth();

                        break;
                        case 83:

                        //fires the bullet up
                        if (OnOff == 1)
                        {
                            bulletX[bulletNumber] = x + 45; 
                        }

                        else 
                        {
                            bulletX[bulletNumber] = x - 50;
                        }
                        bulletY[bulletNumber] = y - 20;

                        bulletOnOff[bulletNumber] = 1;

                        bulletNumber += 1;

                        if (bulletNumber == 100)
                        {
                            bulletNumber = 0;
                        }

                        break;
                        case 65:

                        //fires the bullet left
                        if (OnOff == 1)
                        {
                            bulletX[bulletNumber] = x + 45; 
                        }

                        else 
                        {
                            bulletX[bulletNumber] = x - 50;
                        }

                        bulletY[bulletNumber] = y - 20;

                        bulletOnOff[bulletNumber] = 2;

                        bulletNumber += 1;

                        if (bulletNumber == 100)
                        {
                            bulletNumber = 0;
                        }

                        break;
                        case 87:

                        //fires the bullet down
                        if (OnOff == 1)
                        {
                            bulletX[bulletNumber] = x + 45; 
                        }

                        else 
                        {
                            bulletX[bulletNumber] = x - 50;
                        }

                        bulletY[bulletNumber] = y - 20;

                        bulletOnOff[bulletNumber] = 3;

                        bulletNumber += 1;

                        if (bulletNumber == 100)
                        {
                            bulletNumber = 0;
                        }

                        break;
                        case 68:

                        //fires the bullet right
                        if (OnOff == 1)
                        {
                            bulletX[bulletNumber] = x + 45; 
                        }

                        else 
                        {
                            bulletX[bulletNumber] = x - 50;
                        }

                        bulletY[bulletNumber] = y - 20;

                        bulletOnOff[bulletNumber] = 4;

                        bulletNumber += 1;

                        if (bulletNumber == 100)
                        {
                            bulletNumber = 0;
                        }

                        break;
                    }
                    draw();
                }

            function checkHealth()
                {
                    //checks to see if the alien and avatar bump
                    if ( ( (x > xCoord && x < xCoordRight) || (xRight > xCoord && xRight < xCoordRight) ) && ( (y > yCoord && y < yCoordDown) || (yDown > yCoord && yDown < yCoordDown) ) )
                    {
                        healthAvatar -= 5;
                        if (healthAvatar == 0)
                        {
                            endGame();
                        }
                    }
                    //checks to see if the bullet hits the alien
                    for (var g = 0; g < 100; g++)
                    {
                        if ( ( (bulletX[g] > xCoord && bulletX[g] < xCoordRight) || ( (bulletX[g] + 5) > xCoord && (bulletX[g] + 5) < xCoordRight) ) && ( (bulletY[g] > yCoord && bulletY[g] < yCoordDown) || ((bulletY[g] + 5) > yCoord && (bulletY[g] + 5) < yCoordDown) ) )
                        {
                            healthInvader -= 5;
                            if (healthInvader == 0)
                            {
                                endGame();
                            }
                        }

                    }
                    draw();
                }

            function draw() 
                {
                    clear();
                    //canvas background color
                    ctx.fillStyle = "black";
                    //outline of canvas
                    ctx.strokeStyle = "white";
                    rect(0,0,WIDTH,HEIGHT);

                    //draws the bullets

                    for (var c = 0; c < 100; c++)
                    {
                        if (bulletOnOff[c] == 0)
                        {
                            //this makes the bullet follow the avatar
                            ctx.fillStyle = "#000CFF";
                            if (OnOff == 1)
                            {
                                ctx.fillRect((x + 45), (y - 20), 5, 5);
                            }
                            else 
                            {
                                ctx.fillRect((x - 50), (y - 20), 5, 5);
                            }
                        } 
                        else 
                        {
                            //this makes the bullet move 
                            ctx.fillStyle = "#000CFF";
                            ctx.fillRect(bulletX[c], bulletY[c], 5, 5);
                        }
                    }

                    //draws the health bars

                    //red
                    ctx.fillStyle = "#FF0000";
                    ctx.fillRect(20, 350, 130, 30);
                    ctx.fillRect(850, 350, 130, 30);
                    //green
                    ctx.fillStyle = "#42FF00";
                    ctx.fillRect(20, 350, healthAvatar, 30);
                    ctx.fillRect(850, 350, healthInvader, 30);

                    //making the person 

                    //making the person (right)
                    if (OnOff == 1)
                    {
                        //draw circle for the face
                        ctx.fillStyle = "#FFEFC9";
                        ctx.beginPath();
                        ctx.arc(x, y, 30, 0, Math.PI * 2, true); // x, y, radius, starting angle, ending angle, anticlockwise
                        ctx.closePath();
                        ctx.fill();

                        //draw circles for the eye
                        ctx.fillStyle= "#FFFFFF";
                        ctx.beginPath();
                        ctx.arc(x, (y - 10), 10, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(x, (y - 8), 5, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw an arc for the smile
                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(x, (y + 20), 10, 0, Math.PI, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw a rectangle for the body
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((x - 20), (y + 30), 40, 50);

                        //draw rectangles for the legs
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((x - 20), (y + 80), 10, 20);
                        ctx.fillRect((x + 10), (y + 80), 10, 20);

                        //draw rectangles for the arms
                        ctx.fillStyle = "#FFEFC9";
                        ctx.fillRect((x - 40), (y + 30), 20, 10);
                        ctx.fillRect((x + 20), (y + 30), 20, 10);

                        //draw rectangles for the feet
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((x - 30), (y + 100), 20, 10);
                        ctx.fillRect((x + 10), (y + 100), 20, 10);

                        //adding a lightsaber
                        ctx.fillStyle = "#000CFF";
                        ctx.fillRect((x + 40), (y - 20), 10, 50);

                        //lightsaber handle
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((x + 40), (y + 30), 10, 10);

                        //adding an eyebrow
                        ctx.fillStyle = "#000000";
                        ctx.fillRect((x - 10), (y - 20), 20, 2);
                    }
                    //making the person (left)
                    else
                    {
                        //draw circle for the face
                        ctx.fillStyle = "#FFEFC9";
                        ctx.beginPath();
                        ctx.arc(x, y, 30, 0, Math.PI * 2, true); // x, y, radius, starting angle, ending angle, anticlockwise
                        ctx.closePath();
                        ctx.fill();

                        //draw circles for the eye
                        ctx.fillStyle= "#FFFFFF";
                        ctx.beginPath();
                        ctx.arc(x, (y - 10), 10, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(x, (y - 8), 5, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw an arc for the smile
                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(x, (y + 20), 10, 0, Math.PI, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw a rectangle for the body
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((x - 20), (y + 30), 40, 50);

                        //draw rectangles for the legs
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((x - 20), (y + 80), 10, 20);
                        ctx.fillRect((x + 10), (y + 80), 10, 20);

                        //draw rectangles for the arms
                        ctx.fillStyle = "#FFEFC9";
                        ctx.fillRect((x - 40), (y + 30), 20, 10);
                        ctx.fillRect((x + 20), (y + 30), 20, 10);

                        //draw rectangles for the feet
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((x - 30), (y + 100), 20, 10);
                        ctx.fillRect((x + 10), (y + 100), 20, 10);

                        //adding a lightsaber
                        ctx.fillStyle = "#000CFF";
                        ctx.fillRect((x - 50), (y - 20), 10, 50);

                        //lightsaber handle
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((x - 50), (y + 30), 10, 10);

                        //adding an eyebrow
                        ctx.fillStyle = "#000000";
                        ctx.fillRect((x - 10), (y - 20), 20, 2);
                    }

                    //draws the invader

                    //making the invader (right)
                    if (OnOff2 == 1)
                    {
                        //draw circle for the face
                        ctx.fillStyle = "#83E25D";
                        ctx.beginPath();
                        ctx.arc(xCoord, yCoord, 30, 0, Math.PI * 2, true); // x, y, radius, starting angle, ending angle, anticlockwise
                        ctx.closePath();
                        ctx.fill();

                        //draw rectangles and circles for the ears
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord - 36), 5, 15);
                        ctx.fillRect((xCoord + 15), (yCoord - 36), 5, 15);

                        ctx.fillStyle = "#83E25D";
                        ctx.arc((xCoord - 18), (yCoord - 36), 5, 0, Math.PI * 2, true);
                        ctx.closePath();
                        ctx.arc((xCoord + 18), (yCoord - 36), 5, 0, Math.PI * 2, true);
                        ctx.closePath();
                        ctx.fill();

                        //draw circles for the eye
                        ctx.fillStyle= "#FFFFFF";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord - 10), 10, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord - 8), 5, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw an arc for the smile
                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord + 20), 10, 0, Math.PI, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw a rectangle for the body
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord + 30), 40, 50);

                        //draw rectangles for the legs
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord + 80), 10, 20);
                        ctx.fillRect((xCoord + 10), (yCoord + 80), 10, 20);

                        //draw rectangles for the arms
                        ctx.fillStyle = "#83E25D";
                        ctx.fillRect((xCoord - 40), (yCoord + 30), 20, 10);
                        ctx.fillRect((xCoord + 20), (yCoord + 30), 20, 10);

                        //draw rectangles for the feet
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((xCoord - 30), (yCoord + 100), 20, 10);
                        ctx.fillRect((xCoord + 10), (yCoord + 100), 20, 10);

                        //adding a lightsaber
                        ctx.fillStyle = "#FF0000";
                        ctx.fillRect((xCoord + 40), (yCoord - 20), 10, 50);

                        //lightsaber handle
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((xCoord + 40), (yCoord + 30), 10, 10);

                        //adding an eyebrow
                        ctx.fillStyle = "#000000";
                        ctx.fillRect((xCoord - 10), (yCoord - 20), 20, 2);
                    }
                    //making the invader (left)
                    else
                    {
                        //draw circle for the face
                        ctx.fillStyle = "#83E25D";
                        ctx.beginPath();
                        ctx.arc(xCoord, yCoord, 30, 0, Math.PI * 2, true); // x, y, radius, starting angle, ending angle, anticlockwise
                        ctx.closePath();
                        ctx.fill();

                        //draw rectangles and circles for the ears
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord - 36), 5, 15);
                        ctx.fillRect((xCoord + 15), (yCoord - 36), 5, 15);

                        ctx.fillStyle = "#83E25D";
                        ctx.arc((xCoord - 18), (yCoord - 36), 5, 0, Math.PI * 2, true);
                        ctx.closePath();
                        ctx.arc((xCoord + 18), (yCoord - 36), 5, 0, Math.PI * 2, true);
                        ctx.closePath();
                        ctx.fill();

                        //draw circles for the eye
                        ctx.fillStyle= "#FFFFFF";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord - 10), 10, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord - 8), 5, 0, Math.PI * 2, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw an arc for the smile
                        ctx.fillStyle= "#000000";
                        ctx.beginPath();
                        ctx.arc(xCoord, (yCoord + 20), 10, 0, Math.PI, true); 
                        ctx.closePath();
                        ctx.fill();

                        //draw a rectangle for the body
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord + 30), 40, 50);

                        //draw rectangles for the legs
                        ctx.fillStyle = "#5DD8E2";
                        ctx.fillRect((xCoord - 20), (yCoord + 80), 10, 20);
                        ctx.fillRect((xCoord + 10), (yCoord + 80), 10, 20);

                        //draw rectangles for the arms
                        ctx.fillStyle = "#83E25D";
                        ctx.fillRect((xCoord - 40), (yCoord + 30), 20, 10);
                        ctx.fillRect((xCoord + 20), (yCoord + 30), 20, 10);

                        //draw rectangles for the feet
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((xCoord - 30), (yCoord + 100), 20, 10);
                        ctx.fillRect((xCoord + 10), (yCoord + 100), 20, 10);

                        //adding a lightsaber
                        ctx.fillStyle = "#FF0000";
                        ctx.fillRect((xCoord - 50), (yCoord - 20), 10, 50);

                        //lightsaber handle
                        ctx.fillStyle = "#B4B2B2";
                        ctx.fillRect((xCoord - 50), (yCoord + 30), 10, 10);

                        //adding an eyebrow
                        ctx.fillStyle = "#000000";
                        ctx.fillRect((xCoord - 10), (yCoord - 20), 20, 2);
                    }
                }
            function moveInvader()
                {

                    if (x < xCoord)
                        {
                            xCoord -= 10;
                            xCoordRight -= 10;
                            OnOff2 = 2 * 1;
                        }
                    else 
                        {
                            xCoord += 10;
                            xCoordRight += 10;
                            OnOff2 = 1 * 1;
                        }
                    if (y < yCoord)
                        {
                            yCoord -= 10;
                            yCoordDown -= 10;
                        }
                    else 
                        {
                            yCoord += 10;
                            yCoordDown += 10;
                        }
                    draw();
                    checkHealth();
                }
        </script>
    </head>

    <body onload="init()" style="background-color: black; color: white; font-family: 'Unlock', cursive; font-size: 50px; text-align: center;">
        Space Invaders Returns
        </br>
        </br>
        <canvas id="canvas" width="1000" height="400">
        This text is displayed if your browser does not support HTML5 Canvas.
        </canvas>
        </br>
        </br>
        <input id="move" type="button" name="Move" value="Begin" onclick="startTimer()" style="color: black; font-family: 'Unlock', cursive; font-size: 50px;"/>
        </br>
        </br>
        <div id="thisDiv" class="hiddenContent">
            Game over. 
        </div>
    </body>
</html>

1 个答案:

答案 0 :(得分:0)

您遇到的问题是因为脚本位于html主体之前。因此,该脚本会在实际的html DOM加载之前加载并运行,并且由于画布元素尚不存在而无法找到它。

通过将脚本放在元素的末尾来更改html语法的顺序。

<body>
   ......
   <script>YOUR SCRIPT</script>
</body>