利用原生的JavaScript實(shí)現(xiàn)簡單拼圖游戲
前言
本篇主要講解,如何利用原生的 JavaScript
來實(shí)現(xiàn)一個(gè)簡單的拼圖小游戲。
一、游戲的基礎(chǔ)邏輯
想用一門語言來開發(fā)游戲,必須先了解如何使用這門語言來實(shí)現(xiàn)一些基礎(chǔ)邏輯,比如圖像的繪制、交互的處理、定時(shí)器等。
1、圖形繪制
圖形繪制是一切的基礎(chǔ),這里使用 JavaScript 在 canvas 上進(jìn)行繪制。即先在 html 中創(chuàng)建 canvas 元素,然后在 JavaScript 中,通過 id 拿到這個(gè)元素,并且通過 canvas 拿到對應(yīng)的上下文環(huán)境 context ,為后續(xù)的繪圖做好準(zhǔn)備。
<canvas id="background" width="450px" height="450px"></canvas>
var background = document.getElementById("background"); var context = background.getContext('2d');
通過 context 的 drawImage 方法可以繪制圖片,這里進(jìn)行了相應(yīng)的封裝:
注:這里要等圖片加載完畢后再進(jìn)行繪制,即在 onload 中去調(diào)用 drawImage 方法,否則會繪制失敗。
var drawImageItem = function(index, position) { var img = new Image(); img.src = './image/dog_0' + String(index+1) + '.jpg'; img.onload = () => { var rect = rectForPosition(position); context.drawImage(img, rect[0], rect[1], rect[2], rect[3]); } }
在繪制圖片之后,我們還需要去動態(tài)刷新視圖,否則 canvas 就只是一張靜態(tài)的圖片。如果是簡單的圖形刷新,只需在原來的位置重新繪制,進(jìn)行覆蓋即可。但有時(shí)候我們只需要將原來已存在的圖形清除掉,而不需要繪制新圖案。比如在拼圖游戲中,將一個(gè)方塊移動到另一個(gè)位置后,需要清空原來的位置。
通過 context 的 clearRect 方法可以達(dá)到清除的目的。以下是清除 canvas 的某個(gè)區(qū)域的代碼:
var originRect = rectForPosition(origin); context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]);
2、事件處理
有了圖形的繪制后,我們還需要處理玩家的輸入事件,然后根據(jù)輸入事件,來決定什么時(shí)候刷新視圖。輸入事件可以分為 3 種:在手機(jī)上有觸屏事件;在 PC 上,有鼠標(biāo)和鍵盤事件。
JavaScript 中對觸屏和鼠標(biāo)點(diǎn)擊的監(jiān)聽是一樣的,都是通過 canvas 的 onclick 事件進(jìn)行回調(diào),具體如下:
// 屏幕點(diǎn)擊 background.onclick = function(e) { };
我們可以通過 e.offsetX 、 e.offsetY 來獲取觸控點(diǎn)在 canvas 中的位置。
注: canvas 的坐標(biāo)原點(diǎn)在左上角,即左上角的坐標(biāo)是 (0, 0) 。
鍵盤的按鍵點(diǎn)擊則是通過 document 的 onkeyup 、 onkeydown 等事件進(jìn)行回調(diào)。 onkeyup 是指按鍵的抬起事件, onkeydown 是指按鍵的按下事件。我們可以通過 keyCode 知道當(dāng)前具體是哪一個(gè)按鍵,然后根據(jù)不同的按鍵去處理不同的邏輯,如下:
if (event.keyCode == '37') { // 左 // do something } else if (event.keyCode == '38') { // 上 // do something } else if (event.keyCode == '39') { // 右 // do something } else if (event.keyCode == '40') { // 下 // do something }
3、定時(shí)器
有時(shí)候,除了在玩家輸入的時(shí)候需要去刷新視圖,還需要每隔一段時(shí)間定時(shí)去刷新視圖。比如在一個(gè)貪吃蛇游戲中,就需要每隔一段時(shí)間就去刷新蛇的位置。
這個(gè)時(shí)候我們就需要一個(gè)定時(shí)器,讓它每隔一段時(shí)間去執(zhí)行一段刷新視圖的代碼。我們通過 setInterval 方法來實(shí)現(xiàn)定時(shí)器功能:
setInterval("run()", 100);
上面這段代碼表示每隔 100 毫秒,去執(zhí)行一次 run 方法。
二、拼圖的基礎(chǔ)邏輯
有了游戲的基礎(chǔ)邏輯,下面來看一下如何實(shí)現(xiàn)拼圖的邏輯。
1、生成隨機(jī)序列
因?yàn)椴皇侨我庑蛄卸伎梢酝ㄟ^平移的方式來還原,所以我們不能簡單地生成一個(gè)隨機(jī)序列。比如 1、0、2、3、4、5、6、7、8 這個(gè)序列,無論怎么平移,都不可能還原。
這里采取的做法是:預(yù)先設(shè)置了 4 個(gè)可還原的序列,先從這 4 個(gè)序列中隨機(jī)選取一個(gè),然后再對序列進(jìn)行模擬平移若干步驟。以此來盡可能地保證初始序列的多樣性,也保證了序列的可還原性。具體代碼如下:
var setupRandomPosition = function() { var list1 = [4, 3, 2, 8, 0, 7, 5, 6, 1]; var list2 = [2, 0, 5, 6, 8, 7, 3, 1, 4]; var list3 = [3, 7, 2, 4, 1, 6, 8, 0, 5]; var list4 = [3, 2, 4, 1, 7, 6, 5, 0, 8]; var lists = [list1, list2, list3, list4]; imageIndexForPosition = lists[parseInt(Math.random() * 4)]; // 獲取空位位置 var emptyPosition = 0; for (var i = imageIndexForPosition.length - 1; i >= 0; i--) { if (imageIndexForPosition[i] == lastIndex()) { emptyPosition = i; break; } } background.emptyPosition = emptyPosition; // 隨機(jī)移動次數(shù) var times = 10; while (times--) { // 獲取隨機(jī)數(shù),決定空位哪個(gè)位置進(jìn)行移動 var direction = parseInt(Math.random() * 4); var target = -1; if (direction == 0) { target = topOfPosition(emptyPosition); // 上 } else if (direction == 1) { target = leftOfPosition(emptyPosition); // 左 } else if (direction == 2) { target = rightOfPosition(emptyPosition); // 右 } else if (direction == 3) { target = bottomOfPosition(emptyPosition); // 下 } if (target < 0 || target > lastIndex()) { // 位置不合法,繼續(xù)下一次循環(huán) continue; } var result = moveImageIfCanAtPosition(target); if (result >= 0) { // 如果移動成功,更新空位的位置 emptyPosition = target; } } }
2、判斷是否可以移動方塊
在保存順序的時(shí)候,是用 0~8 這 9 個(gè)數(shù)字來保存,而空白的方塊是數(shù)字 8 的位置。所以判斷可以移動的唯一條件是,目標(biāo)位置的值是否為 8。代碼如下:
var isPositionEmpty = function(position) { if (position < 0 || position > lastIndex()) { return false; } if (imageIndexForPosition[position] == lastIndex()) { return true; } else { return false; } }
上面 lastIndex() 的值為 8。
3、實(shí)現(xiàn)方塊移動
方塊移動的實(shí)現(xiàn)很簡單,先將舊位置的圖形清除,然后在新的位置繪制。
var refreshImagePositions = function(origin, target) { var originRect = rectForPosition(origin); context.clearRect(originRect[0], originRect[1], originRect[2], originRect[3]); drawImageItem(imageIndexForPosition[target], target); }
4、檢查是否完成
檢查圖案是否已經(jīng)還原,只需要對數(shù)組進(jìn)行一次遍歷,看是否有序即可。
var checkIfFinish = function() { for (var index = 0; index < imageIndexForPosition.length; index++) { if (index != imageIndexForPosition[index]) { return false; } } return true; }
5、交互事件屏蔽
當(dāng)圖案還原之后,我們不希望玩家還能通過鍵盤或鼠標(biāo)來移動方塊,這個(gè)時(shí)候就需要對交互事件進(jìn)行屏蔽。
只需要一個(gè)標(biāo)志位就可以達(dá)到這個(gè)目的:
//
屏幕點(diǎn)擊 background.onclick = function(e) { if (isFinish) { return; } // do something }; // 鍵盤按鈕事件 document.onkeyup = function(event) { if (isFinish) { return; } // do something }
當(dāng)圖案還原之后,標(biāo)志位 isFinish 會被置為 true ,然后在屏幕點(diǎn)擊和鍵盤按鈕響應(yīng)事件的開始處添加判斷,如果已經(jīng)結(jié)束,則不繼續(xù)走方塊移動的邏輯。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
- JS快速實(shí)現(xiàn)移動端拼圖游戲
- JS 拼圖游戲 面向?qū)ο螅⑨屚暾?/a>
- js+html5實(shí)現(xiàn)可在手機(jī)上玩的拼圖游戲
- JS實(shí)現(xiàn)拼圖游戲
- jQuery+vue.js實(shí)現(xiàn)的九宮格拼圖游戲完整實(shí)例【附源碼下載】
- 基于javascript制作經(jīng)典傳統(tǒng)的拼圖游戲
- 基于Vue.js實(shí)現(xiàn)數(shù)字拼圖游戲
- javascript結(jié)合Flexbox簡單實(shí)現(xiàn)滑動拼圖游戲
- 基于JS實(shí)現(xiàn)簡單滑塊拼圖游戲
- 使用js編寫實(shí)現(xiàn)拼圖游戲
相關(guān)文章
12個(gè)非常有創(chuàng)意的JavaScript小游戲
JavaScript 在Web開發(fā)過程中已經(jīng)是必不可少的重要分子,他推動著Web的交互性往越來越高的層次發(fā)展,現(xiàn)在的很多Web游戲也基于這類語言開發(fā)。2010-03-03JavaScript中valueOf函數(shù)與toString方法深入理解
基本上,所有JS數(shù)據(jù)類型都擁有valueOf和toString這兩個(gè)方法,null除外。它們倆解決javascript值運(yùn)算與顯示的問題,本文將詳細(xì)介紹,有需要的朋友可以參考下2012-12-12JavaScript分析、壓縮工具JavaScript Analyser
這篇文章主要介紹了JavaScript分析、壓縮工具JavaScript Analyser,需要的朋友可以參考下2014-12-12javascript獲取和判斷瀏覽器窗口、屏幕、網(wǎng)頁的高度、寬度等
這篇文章主要介紹了javascript獲取和判斷瀏覽器窗口、屏幕、網(wǎng)頁的高度、寬度等,需要的朋友可以參考下2014-05-05新發(fā)現(xiàn)原來documenet.URL也可以實(shí)現(xiàn)頁面跳轉(zhuǎn)
新發(fā)現(xiàn)原來documenet.URL也可以實(shí)現(xiàn)頁面跳轉(zhuǎn)...2007-08-08小程序?qū)崿F(xiàn)多個(gè)選項(xiàng)卡切換
這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)多個(gè)選項(xiàng)卡切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06