Javascript 错误:无法使用画布标记读取空的属性"getContext"



我创建了一个画布,但我一直收到一个错误,说它无法在我的init((函数中的第169行获取null的上下文。我在脚本开始时创建了var"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>

您遇到的问题是因为脚本在html的正文之前。因此,脚本在实际的htmlDOM加载之前加载和运行,并且它找不到画布元素,因为它还不存在。

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

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

最新更新