javascript
JavaScript+ Canvas开发趣味小游戏《贪吃蛇》
一、效果展示
二、《貪吃蛇》基本實現思路
蛇頭部分+蛇身體部分:采用對象形式來存儲坐標,并將每個坐標對象放到一個snake數組中,方便使用。設置每個方格寬度30px,高度30px,畫布高度600px,寬度600px。
a.新蛇頭newHead等于舊蛇頭oldHead的x坐標或者y坐標+1
b.蛇的頭部+身體部分,每次更新(動起來)的規律:每次將蛇的身體部分的最后1個方塊(尾部)刪除,然后在蛇的頭部的前面增加1個方塊:該新增的方塊(newHead)的坐標與原來頭部方塊(oldHead)的坐標關系為 newHead等于舊蛇頭oldHead的x坐標或者y坐標+1
蛇吃食物
a.當蛇頭的坐標與食物的坐標重合的時候,表示食物被吃掉了。判斷標準為:蛇頭的x,y坐標都與食物的x,y坐標重合
此時,要做兩件事情:
1)isEated 變為 true,此時就會重新生成一個食物坐標
2)讓蛇增加一節長度。但是,前面的1.b里提到,關于蛇動起來的規律中,每次更新畫布都會把蛇的身體部分(尾巴)刪掉1個方塊,也就是當蛇沒有吃到食物時,刪除一節。所以,在這里蛇吃到食物時,只要不刪除最后一節,也就相當于蛇吃到食物增加了一節了。
繪制食物
a.食物有默認位置
b.食物沒有被吃掉之前,不會動
c.只有食物被吃掉后,才會隨機再生成一個
繪制貪吃蛇
a.貪吃蛇隨著畫布的 擦除->重繪的過程,會動起來(即改變貪吃蛇的坐標),這就是讓蛇能夠動起來的原理。這里需要配合定時器來實現動起來!
b.貪吃蛇默認移動方向為:水平向右
c.默認每次移動的距離為一個方格
以下的x,y都是指蛇頭的坐標,只要蛇頭的坐標發生改變,蛇的身體部分自然會跟著蛇頭來運動
水平往左 : x-1 , y不變
垂直向下 : x不變 , y+1
垂直向上 : x不變 , y-1
繪制網格:使用Canvas來實現
注意Canvas使用方法:
1)獲取畫布對象 var huabu = document.getElementById(‘huabu’)
2)獲取畫布對象中的工具箱 var tools = huabu.getContext(‘2d’)
3)從畫圖工具箱中取出要使用的工具 tools.moveTo(0, 30 * i + 0.5) 、 tools.lineTo(600, 30 * i + 0.5)
4)找坐標
5)繪制
注意:在使用Canvas繪制線條時坐標的設置,如果要設置的線條粗細為1px,則需要把tools.moveTo()、 tools.lineTo()里面的起點終點坐標設置成.5小數形式,否則畫出來的線條粗細為2px
游戲結束的判斷標準:
貪吃蛇超出上、下、左、右邊界時,游戲結束
即newHead.y < 0 || newHead.x < 0 || newHead.x * 30 >= 600 || newHead.y * 30 >= 600時,游戲結束。
三、技術要點
四、游戲功能:
五、代碼如下:
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>貪吃蛇游戲</title></head><style type="text/css">* {margin: 0;padding: 0;}a {text-decoration: none;}canvas {position: relative;display: block;margin: 0 auto;background-color: #33cc99;}.images {background: url(img/timg.jpg) no-repeat;width: 800px;height: 600px;position: absolute;top: 0;left: 50%;margin-left: -400px;}.start {width: 160px;height: 40px;border: 1px solid #33CC99;border-radius: 10px;color: #fff;background-color: orangered;font-size: 25px;text-align: center;line-height: 40px;position: absolute;bottom: 200px;left: 50%;margin-left: -80px;}.author {width: 160px;position: absolute;bottom: 150px;left: 50%;margin-left: -80px;text-align: center;font-weight: 600;font-size: 18px;}.over {background: url(img/over.jpg) no-repeat;width: 800px;height: 600px;position: absolute;top: 0;left: 50%;margin-left: -400px;}.black_overlay {display: none;position: absolute;top: 0%;left: 0%;width: 100%;height: 100%;background-color: black;z-index: 1001;-moz-opacity: 1;opacity: 1;filter: alpha(opacity=1);}.black_overlay>img {display: none;margin: 0 auto;margin-top: 190px;}.black_overlay>a {width: 160px;height: 40px;border: 1px solid #33CC99;border-radius: 10px;color: #fff;background-color: orangered;font-size: 25px;text-align: center;line-height: 40px;position: absolute;bottom: 230px;left: 50%;margin-left: -80px;}#score {margin-left: 500px; }#scores {margin-right: 200px;}</style><body><canvas id="huabu" width="600" height="600"></canvas><div class="images" id="images"><div class="start" id="start">開始游戲</div><div class="author">制作人:Zep</div></div><div id="fade" class="black_overlay"><img src="./img/over.jpg" id="over"><a href="index.html">重新開始</a></div><div id="score">分數:<span id="scores">0</span>游戲時長:<span id="time">00時00分00秒0000毫秒</span></div></body><script type="text/javascript">// 是否開始游戲var isStart = false// 點擊start按鈕,隱藏首頁圖片var startbtn = document.getElementById('start')var imagesDom = document.getElementById('images')var fadeDom = document.getElementById('fade')var overDom = document.getElementById('over')var score = 0.0var speed = 3var scoresDom = document.getElementById('scores')var timeDom = document.getElementById('time')var h = m = s = ms = 0; //定義時,分,秒,毫秒并初始化為0;function toDub(n) { //補0操作if (n < 10) {return "0" + n;} else {return "" + n;}}function toDubms(n) { //給毫秒補0操作if (n < 10) {return "00" + n;} else {return "0" + n;}}function timer() { //定義計時函數ms = ms + 50; //毫秒if (ms >= 1000) {ms = 0;s = s + 1; //秒}if (s >= 60) {s = 0;m = m + 1; //分鐘}if (m >= 60) {m = 0;h = h + 1; //小時}str = toDub(h) + "時" + toDub(m) + "分" + toDub(s) + "秒" + toDubms(ms) + "毫秒";timeDom.innerHTML = str;// document.getElementById('mytime').innerHTML=h+"時"+m+"分"+s+"秒"+ms+"毫秒";}startbtn.onclick = function() {imagesDom.style.display = 'none'isStart = true}var Game = setInterval(gameStart, 500)function gameStart() {if (isStart) {clearInterval(Game)var StopTime = setInterval(timer, 100)// console.log('111')// 1.獲取畫布對象var huabu = document.getElementById('huabu')// 2.獲取畫布對象中的工具箱var tools = huabu.getContext('2d')//注意:1.食物有默認位置// 2.食物沒有被吃掉之前,不會動// 3.只有食物被吃掉后,才會隨機再生成一個// 隨機生產x,y坐標// 食物的默認位置var x = Math.floor(Math.random() * 20) * 30var y = Math.floor(Math.random() * 20) * 30// 添加一個標記,記錄食物是否被吃掉了var isEated = false // 默認食物沒有被吃掉// 蛇的默認位置var snake = [{x: 3,y: 0}, {x: 2,y: 0}, {x: 1,y: 0}]// 蛇的默認方向:水平向右var directionX = 1var directionY = 0// 判斷游戲是否結束var isGameOver = false// 監聽鍵盤按下的行為document.addEventListener('keydown', function(event) {console.log('按鍵的鍵值', event.keyCode)// 上:38,下:40,左:37,右:39if (event.keyCode === 38) {//如果鍵值為38,就說明按下了 上鍵console.log("上")directionX = 0directionY = -1} else if (event.keyCode === 40) {//如果鍵值為40,就說明按下了 下鍵console.log("下")directionX = 0directionY = 1} else if (event.keyCode === 37) {//如果鍵值為37,就說明按下了 左鍵console.log("左")directionX = -1directionY = 0} else if (event.keyCode === 39) {//如果鍵值為39,就說明按下了 右鍵console.log("右")directionX = 1directionY = 0}})// 使用定時器,讓貪吃蛇動起來// 定時器每隔一段時間,就執行一遍“擦除畫布->重繪畫布”的過程// 以下代碼表示:1s執行三次 “擦除畫布->重繪畫布”的過程setInterval(function() {// 如果isGameOver = false 說明游戲結束了,執行return,就不執行下面的代碼了if (isGameOver) {fadeDom.style.display = 'block'overDom.style.display = 'block'clearInterval(StopTime)return}// 一、擦除畫布tools.clearRect(0, 0, 600, 600)// 二、以下代碼就是重繪畫布的代碼// -----------------------A.蛇頭部分開始---------------------------// A.蛇頭部分var oldHead = snake[0]var newHead = {x: oldHead.x + directionX,y: oldHead.y + directionY}//游戲結束的判定:// 1.蛇頭的y<0,貪吃蛇超出上邊界,游戲結束if (newHead.y < 0 || newHead.x < 0 || newHead.x * 30 >= 600 || newHead.y * 30 >= 600) {// 游戲結束isGameOver = true} else {// 在數組首部添加一節,結果為:(4,0)(3,0) (2,0)snake.unshift(newHead) //在數組第一個元素前面添加一個元素// -----------------------B.蛇吃食物開始---------------------------// 蛇吃食物的分析:// 當蛇頭的坐標與食物的坐標重合的時候,表示食物被吃掉了// 此時,要做兩件事情:// 1.isEated 變為 true,此時就會重新生成一個食物坐標if (snake[0].x * 30 === x && snake[0].y * 30 === y) {// 蛇頭的x,y坐標都與食物的x,y坐標重合isEated = true} else { // 2.讓蛇增加一節長度,也就是當蛇沒有吃到食物時,刪除一節,吃到食物時,就不刪除一節,也就相當于蛇吃到食物增加一節// 刪除最后一節,結果為:(3,0) (2,0)snake.pop() //刪除數組最后一個元素// 重新設置食物沒有被吃掉的標志isEated = false}// -----------------------蛇吃食物結束---------------------------}// -----------------------蛇頭部分結束---------------------------// -----------------------C.繪制食物開始---------------------------// 繪制矩形 tools.fillRect(x,y,width,height)//注意:1.食物有默認位置// 2.食物沒有被吃掉之前,不會動// 3.只有食物被吃掉后,才會隨機再生成一個if (isEated) {x = Math.floor(Math.random() * 20) * 30y = Math.floor(Math.random() * 20) * 30score += 1speed += 0.1}scoresDom.innerHTML = score// 設置填充顏色tools.fillStyle = '#cccc00'tools.fillRect(x, y, 30, 30)// -----------------------繪制食物結束---------------------------// -----------------------D.繪制貪吃蛇開始---------------------------// 說明:// 1.貪吃蛇隨著 擦除->重繪的過程,會動起來(即改變貪吃蛇的坐標)// 2.貪吃蛇默認移動方向為:水平向右// 3.默認每次移動的距離為一個方格// 問題:水平往左 : x-1 , y不變// 垂直向下 : x不變 , y+1// 垂直向上 : x不變 , y-1// // 刪除最后一節,結果為:(3,0) (2,0)// snake.pop() //刪除數組最后一個元素// 繪制蛇頭部,蛇的每一節都是一個矩形// // 設置蛇頭的顏色// tools.fillStyle = '#ff0033'// tools.fillRect(snake[0].x * 30,snake[0].y * 30,30,30)// // 繪制蛇的身體部分// tools.fillStyle = '#333399'// tools.fillRect(snake[1].x * 30,snake[1].y * 30,30,30)// tools.fillRect(snake[2].x * 30,snake[2].y * 30,30,30)for (var i = 0; i < snake.length; i++) {if (i === 0) {tools.fillStyle = '#ff0033'} else {tools.fillStyle = '#333399'}tools.fillRect(snake[i].x * 30, snake[i].y * 30, 30, 30)}// -----------------------繪制貪吃蛇結束---------------------------// -----------------------E.繪制網格開始---------------------------// 3.從畫圖工具箱中取出要使用的工具// 4.找坐標// 繪制水平線for (var i = 1; i < 20; i++) {tools.moveTo(0, 30 * i + 0.5)tools.lineTo(600, 30 * i + 0.5)}// 繪制垂直線for (var i = 1; i < 20; i++) {tools.moveTo(30 * i + 0.5, 0)tools.lineTo(30 * i + 0.5, 600)}// 設置繪制直線的顏色tools.strokeStyle = '#fff'// 5.繪制tools.stroke()// -----------------------繪制網格結束---------------------------}, 1000 / speed)}}</script> </html>總結
以上是生活随笔為你收集整理的JavaScript+ Canvas开发趣味小游戏《贪吃蛇》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git如何切换分支_拜托,不要再问我Gi
- 下一篇: 七、MySQL DDL数据定义语言 学习