游戲控制器
按下按鈕可移動紅色方塊:
掌控一切
現在我們要控制紅色方塊。
添加四個按鈕:上、下、左、右。
為每個按鈕編寫一個函數,以沿選定方向移動組件。
在 component
構造函數中創建兩個新屬性,并將它們命名為 speedX
和 speedY
。這些屬性被用作速度指示器。
在 component
構造函數中添加一個名為 newPos()
的函數,該函數使用 speedX
和 speedY
屬性來更改組件的位置。
在繪制組件之前,從 updateGameArea
函數調用 newPos
函數:
實例
<script> function component(width, height, color, x, y) { this.width = width; this.height = height; this.speedX = 0; this.speedY = 0; this.x = x; this.y = y; this.update = function() { ctx = myGameArea.context; ctx.fillStyle = color; ctx.fillRect(this.x, this.y, this.width, this.height); } this.newPos = function() { this.x += this.speedX; this.y += this.speedY; } } function updateGameArea() { myGameArea.clear(); myGamePiece.newPos(); myGamePiece.update(); } function moveup() { myGamePiece.speedY -= 1; } function movedown() { myGamePiece.speedY += 1; } function moveleft() { myGamePiece.speedX -= 1; } function moveright() { myGamePiece.speedX += 1; } </script> <button onclick="moveup()">UP</button> <button onclick="movedown()">DOWN</button> <button onclick="moveleft()">LEFT</button> <button onclick="moveright()">RIGHT</button>
停止移動
如果需要,您可以在釋放按鈕時使紅色方塊停止。
添加一個將速度指示器設置為 0 的函數。
為了應對普通屏幕和觸摸屏,我們將為這兩種設備添加代碼:
實例
function stopMove() { myGamePiece.speedX = 0; myGamePiece.speedY = 0; } </script> <button onmousedown="moveup()" onmouseup="stopMove()" ontouchstart="moveup()">UP</button> <button onmousedown="movedown()" onmouseup="stopMove()" ontouchstart="movedown()">DOWN</button> <button onmousedown="moveleft()" onmouseup="stopMove()" ontouchstart="moveleft()">LEFT</button> <button onmousedown="moveright()" onmouseup="stopMove()" ontouchstart="moveright()">RIGHT</button>
鍵盤作為控制器
我們還可以通過鍵盤上的方向鍵來控制紅色方塊。
創建一個方法來檢查是否按下了某個鍵,并將 myGameArea
對象的 key
屬性設置為鍵代碼。當松開按鍵時,將 key
屬性設置為 false
:
實例
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('keydown', function (e) { myGameArea.key = e.keyCode; }) window.addEventListener('keyup', function (e) { myGameArea.key = false; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } }
這樣,如果按下方向鍵之一,我們就可以移動紅色方塊:
實例
function updateGameArea() { myGameArea.clear(); myGamePiece.speedX = 0; myGamePiece.speedY = 0; if (myGameArea.key && myGameArea.key == 37) {myGamePiece.speedX = -1; } if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 1; } if (myGameArea.key && myGameArea.key == 38) {myGamePiece.speedY = -1; } if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 1; } myGamePiece.newPos(); myGamePiece.update(); }
按下多個鍵
如果同時按下多個鍵怎么辦?
在上面的例子中,組件只能水平或垂直移動。現在我們希望組件也可以沿對角線移動。
為 myGameArea
對象創建一個 keys
數組,并為每個按下的鍵插入一個元素,并為其賦值 true
,該值保持 true ,直到不再按下該鍵,該值在 keyup
事件監聽函數中變為 false
:
實例
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('keydown', function (e) { myGameArea.keys = (myGameArea.keys || []); myGameArea.keys[e.keyCode] = true; }) window.addEventListener('keyup', function (e) { myGameArea.keys[e.keyCode] = false; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } } function updateGameArea() { myGameArea.clear(); myGamePiece.speedX = 0; myGamePiece.speedY = 0; if (myGameArea.keys && myGameArea.keys[37]) {myGamePiece.speedX = -1; } if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.speedX = 1; } if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speedY = -1; } if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speedY = 1; } myGamePiece.newPos(); myGamePiece.update(); }
使用鼠標光標作為控制器
如果您想使用鼠標光標控制紅色方塊,請在 myGameArea
對象中添加一個方法來更新鼠標光標的 x 和 y 坐標:
實例
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.canvas.style.cursor = "none"; //hide the original cursor this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('mousemove', function (e) { myGameArea.x = e.pageX; myGameArea.y = e.pageY; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } }
然后我們就可以使用鼠標光標移動紅色方塊了:
實例
function updateGameArea() { myGameArea.clear(); if (myGameArea.x && myGameArea.y) { myGamePiece.x = myGameArea.x; myGamePiece.y = myGameArea.y; } myGamePiece.update(); }
觸摸屏幕來控制游戲
我們還可以在觸摸屏上控制紅色方塊。
在 myGameArea
對象中添加一個方法,該方法使用屏幕觸摸位置的 x 和 y 坐標:
實例
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('touchmove', function (e) { myGameArea.x = e.touches[0].screenX; myGameArea.y = e.touches[0].screenY; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } }
然后,當用戶觸摸屏幕時,我們可以使用與鼠標光標相同的代碼來移動紅色方塊了:
實例
function updateGameArea() { myGameArea.clear(); if (myGameArea.x && myGameArea.y) { myGamePiece.x = myGameArea.x; myGamePiece.y = myGameArea.y; } myGamePiece.update(); }
畫布上的控制器
我們還可以在畫布上繪制自己的按鈕,并將它們用作控制器:
實例
function startGame() { myGamePiece = new component(30, 30, "red", 10, 120); myUpBtn = new component(30, 30, "blue", 50, 10); myDownBtn = new component(30, 30, "blue", 50, 70); myLeftBtn = new component(30, 30, "blue", 20, 40); myRightBtn = new component(30, 30, "blue", 80, 40); myGameArea.start(); }
添加一個新函數,用于確定某個組件(在本例中是一個按鈕)是否被單擊。
首先添加事件偵聽器來檢查是否單擊了鼠標按鈕(mousedown
和 mouseup
)。如需應對觸摸屏,還需要添加事件偵聽器來檢查屏幕是否被單擊(touchstart
和 touchend
):
實例
var myGameArea = { canvas : document.createElement("canvas"), start : function() { this.canvas.width = 480; this.canvas.height = 270; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.interval = setInterval(updateGameArea, 20); window.addEventListener('mousedown', function (e) { myGameArea.x = e.pageX; myGameArea.y = e.pageY; }) window.addEventListener('mouseup', function (e) { myGameArea.x = false; myGameArea.y = false; }) window.addEventListener('touchstart', function (e) { myGameArea.x = e.pageX; myGameArea.y = e.pageY; }) window.addEventListener('touchend', function (e) { myGameArea.x = false; myGameArea.y = false; }) }, clear : function(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } }
現在 myGameArea
對象有了能夠告訴我們單擊的 x 和 y 坐標的屬性。我們使用這些屬性來檢查是否在我們的其中一個藍色按鈕上執行了單擊。
這個新方法稱為 clicked
,它是 component
構造函數的一個方法,它檢查組件是否被單擊。
在 updateGameArea
函數中,如果單擊藍色按鈕之一,我們將執行必要的操作:
實例
function component(width, height, color, x, y) { this.width = width; this.height = height; this.speedX = 0; this.speedY = 0; this.x = x; this.y = y; this.update = function() { ctx = myGameArea.context; ctx.fillStyle = color; ctx.fillRect(this.x, this.y, this.width, this.height); } this.clicked = function() { var myleft = this.x; var myright = this.x + (this.width); var mytop = this.y; var mybottom = this.y + (this.height); var clicked = true; if ((mybottom < myGameArea.y) || (mytop > myGameArea.y) || (myright < myGameArea.x) || (myleft > myGameArea.x)) { clicked = false; } return clicked; } } function updateGameArea() { myGameArea.clear(); if (myGameArea.x && myGameArea.y) { if (myUpBtn.clicked()) { myGamePiece.y -= 1; } if (myDownBtn.clicked()) { myGamePiece.y += 1; } if (myLeftBtn.clicked()) { myGamePiece.x += -1; } if (myRightBtn.clicked()) { myGamePiece.x += 1; } } myUpBtn.update(); myDownBtn.update(); myLeftBtn.update(); myRightBtn.update(); myGamePiece.update(); }