HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。画布是一个矩形区域,您可以控制其每一像素。canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
內容來源:http://www.w3school.com.cn/html5/html_5_canvas.asp
是的,這次要帶給大家的是 Canvas 標籤的基礎教學,它就像一塊畫布,能讓你在 HTML 標籤當中繪圖、動畫、遊戲,那我們就來個簡單的範例吧,就是做出一款經典的打磚塊遊戲!那我們首先要建立一個畫布,這個畫布大小是 480 * 320 的大小,並且在下方會有個開始遊戲的按鈕,按下去後,才開始執行遊戲:
HTML
1 2 3 4 5 6 7
| <canvas id="canvas_1" width="480" height="320"> 您的瀏覽器必須支援 HTML5 標籤語法,才能遊玩該遊戲。 </canvas> <br /> <button>開始遊戲</button>
|
實例
既然是經典的打磚塊遊戲,那麼應該要會有顆球在畫布當中跑來跑去嘛!所以我們要在 button 標籤當中加入 onclikc 事件,去啟動 JavaScript 的方法:
HTML
1 2 3 4 5 6
| <canvas id="canvas_2" width="480" height="320"> 您的瀏覽器必須支援 HTML5 標籤語法,才能遊玩該遊戲。 </canvas> <button onclick="canvasGameStart_canvas_2()">開始遊戲</button>
|
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| function canvasGameStart_canvas_2() { var canvas = document.getElementById("canvas_2"); var ctx = canvas.getContext("2d");
var ballPositionX = canvas.width / 2; var ballPositionY = canvas.height / 2; var ballMoveX = 2; var ballMoveY = 2;
function drawBall() { ctx.beginPath(); ctx.arc(ballPositionX, ballPositionY, 10, 0, Math.PI * 2); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); }
function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawBall();
ballPositionX += ballMoveX; ballPositionY += ballMoveY; }
setInterval(draw, 10); }
|
這邊要稍微特別解釋一下 arc()
這方法,可以參考下圖:
1 2 3 4 5 6 7
|
context.arc(x, y, r, sAngle, eAngle, counterclockwise);
|
實例
然後那顆球就這麼的直直掉下去了,這並不是我們想要的!我們希望他碰到牆壁的時候,能夠反彈,如果更白話一點來講的話,如果球體碰到畫框的邊界,就讓球體以反方向彈回去,那麼我們會修改到 JavaScript 的一些 function:
#JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var ballRadius = 10; var ballMoveX = 2; var ballMoveY = 2;
function draw() {
var ballNextPositionX = ballPositionX + ballMoveX; if(ballNextPositionX > canvas.width-ballRadius || ballNextPositionX < ballRadius) ballMoveX *= -1;
var ballNextPositionY = ballPositionY + ballMoveY; if(ballNextPositionY > canvas.height-ballRadius || ballNextPositionY < ballRadius) ballMoveY *= -1;
}
|
實例
接下來我們要來繪製出給使用者操縱的板子,並且放置於底部:
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| var paddleHeight = 10; var paddleWidth = 75;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false; var leftPressed = false;
document.addEventListener("keydown", keyDownHandler, false); document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) { switch(e.keyCode) { case 39: rightPressed = true; break; case 37: leftPressed = true; break; } }
function keyUpHandler(e) { switch(e.keyCode) { case 39: rightPressed = false; break; case 37: leftPressed = false; break; } }
function drawPaddle() { ctx.beginPath(); ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); }
function draw() {
if(rightPressed && paddleX < canvas.width-paddleWidth) paddleX += 7;
if(leftPressed && paddleX > 0) paddleX -= 7; }
|
實例
到目前為止都還蠻正常的,但還是有些許小缺點,我們接下來希望球體碰到底下時,代表我們的板子並沒有接到球體,遊戲必須重新開始,而球體碰到我們的板子時,才執行反彈球體的動作,所以我們必須修改 draw()
的一些寫法:
JavaScript
1 2 3 4 5 6 7 8 9 10
| function draw() {
var ballNextPositionY = ballPositionY + ballMoveY; if(ballNextPositionY > canvas.height-ballRadius || ballNextPositionY < ballRadius) ballMoveY *= -1; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function draw() {
var ballNextPositionY = ballPositionY + ballMoveY; if(ballNextPositionY < ballRadius) ballMoveY *= -1; if(ballNextPositionY > canvas.height-ballRadius) if(ballPositionX > paddleX && ballPositionX < paddleX + paddleWidth) ballMoveY *= -1;
}
|
實例
是的!球體如果沒有碰到我們的板子,那球體將會直直的掉下去了,球體如果碰到我們的板子,那球體將會反彈,基本物件都做好了,那我們接下來必須開始做我們的磚塊了!
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| var brickRowCount = 3; var brickColumnCount = 5; var brickWidth = 75; var brickHeight = 20; var brickPadding = 10; var brickOffsetTop = 30; var brickOffsetLeft = 30;
var bricks = [];
for(column = 0; column < brickColumnCount; column++) { bricks[column] = []; for(row = 0; row < brickRowCount; row++) bricks[column][row] = { x: 0, y: 0 }; }
function drawBricks() { for(column = 0; column < brickColumnCount; column++) { for(row = 0; row < brickRowCount; row++) { var brickX = (column * (brickWidth + brickPadding)) + brickOffsetLeft; var brickY = (row * (brickHeight + brickPadding)) + brickOffsetTop;
bricks[column][row].x = brickX; bricks[column][row].y = brickY;
ctx.beginPath(); ctx.rect(brickX, brickY, brickWidth, brickHeight); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); } } }
function draw() {
drawBricks();
}
|
實例
參考資料