Canvas貪吃蛇

来源:http://www.cnblogs.com/leitong/archive/2017/09/08/7493499.html
-Advertisement-
Play Games

創建畫布,驗證瀏覽器相容性我就省去了,也很簡單網上有代碼。 然就是蛇對象 食物 移動 控制方向 吃到食物 吃到自己 基本功能大概就是這樣。可能還不算完美,後面有時間繼續優化一下! ...


創建畫布,驗證瀏覽器相容性我就省去了,也很簡單網上有代碼。

 var canctx = document.getElementById("can");
 var ctx =canctx.getContext("2d");

然就是蛇對象

 var snake={
        arrx:[100,110,120],//預設橫坐標和長度(數組長度就是蛇的預設長度)
        arry:[200,200,200],//預設縱坐標
        movedirection:2,//上下左右方向(0是左,1是上,2是右,3是下。預設往右)
        behavior:function () {
            ctx.fillStyle="red";
            for(var i=0;i<this.arrx.length;i++) {
                ctx.fillRect(this.arrx[i], this.arry[i], 10, 10);
            }
        }
    }

食物

var food={
        x:10, y:10,
        show:function () {
            //隨機在畫布中生成食物
           var getx=Math.floor(Math.random()*391),gety=Math.floor(Math.random()*391);
           this.x = getx%10==0?getx:Math.floor(getx/10)*10;
           this.y = gety%10==0?gety:Math.floor(gety/10)*10;
           chack(this.x,this.y);
           ctx.fillStyle="#fff";
           ctx.fillRect(this.x,this.y,10,10);
        }
    }

移動

 //繪製移動的蛇
    function DrawSnake() {
        if(snake.movedirection==2){//往右跑
            if(snake.arrx[snake.arrx.length-1]==canctx.width-10){//最後一個蛇身體(蛇是由一個一個的10*10的正方形構成)的x坐標等於畫布寬度減10就說明撞牆了
                died();
            }else{
                snake.arrx.push(snake.arrx[snake.arrx.length - 1] + 10);//x坐標累加10(數組裡添加新的坐標,蛇的移動就是添加新的坐標在最後一位刪除第一個坐標)
                snake.arry.push(snake.arry[snake.arry.length - 1]);//y坐標不變
            }
        }else if(snake.movedirection==0){//往左跑
            if(snake.arrx[snake.arrx.length-1]==0){
                died();
            }else{
                snake.arrx.push(snake.arrx[snake.arrx.length - 1] - 10);
                snake.arry.push(snake.arry[snake.arry.length - 1]);
            }
        }else if(snake.movedirection==1){//往上跑
            if(snake.arry[snake.arry.length-1]==0){
                died();
            }else{
                snake.arrx.push(snake.arrx[snake.arrx.length - 1]);
                snake.arry.push(snake.arry[snake.arry.length - 1] - 10);
            }
        }else {//往下跑
            if(snake.arry[snake.arry.length - 1] == canctx.height-10) {
                died();
            } else {
                snake.arrx.push(snake.arrx[snake.arrx.length - 1]);
                snake.arry.push(snake.arry[snake.arry.length - 1] + 10);
            }
        }
        EatFood();
        ctx.fillStyle="red";
        for(var i=0;i<snake.arrx.length;i++) {
            ctx.fillRect(snake.arrx[i], snake.arry[i], 10, 10);
        }
        EatSelf(snake.arrx[snake.arrx.length - 1],snake.arry[snake.arry.length - 1]);
        ctx.clearRect(snake.arrx[0],snake.arry[0],10,10);
        snake.arrx.splice(0,1);
        snake.arry.splice(0,1);
    }

控制方向

 //控制方向
    function Controldirection(e) {
       switch(e.keyCode){
           case 37://
               snake.movedirection=0;
               DrawSnake();
               break;
           case 39://
               snake.movedirection=2;
               DrawSnake();
               break;
           case 38://
               snake.movedirection=1;
               DrawSnake();
               break;
           case 40://
               snake.movedirection=3;
               DrawSnake();
               break;
       }
    }

吃到食物

//吃到食物
    function EatFood() {
        if(snake.movedirection==0||snake.movedirection==1){//向左或向上時
            //蛇頭(坐標最後一個值)的x、y坐標和食物的x、y坐標相等
            //蛇移動的方向不同,判斷條件也不同(自己可以在紙上先畫出蛇在不同方向與食物接觸的時候的x、y坐標的對應關係是怎麼樣的來確認判斷條件)
            if(snake.arrx[snake.arrx.length-1]==food.x&&snake.arry[snake.arry.length-1]==food.y){
                if(snake.movedirection==0) {//吃到食物後添加數組的長度
                    snake.arrx.unshift(snake.arrx[0]+10);
                    snake.arry.unshift(snake.arry[0]);
                    food.show();
                }else{
                    snake.arrx.unshift(snake.arrx[0]);
                    snake.arry.unshift(snake.arry[0] + 10);
                    food.show();
                }
            }
        }else{//向右或向下時
            if(snake.arrx[snake.arrx.length-1]==food.x&&snake.arry[snake.arry.length-1]==food.y){
                if(snake.movedirection==1) {
                    snake.arrx.unshift(snake.arrx[0] - 10);
                    snake.arry.unshift(snake.arry[0]);
                    food.show();
                }else{
                    snake.arrx.unshift(snake.arrx[0]);
                    snake.arry.unshift(snake.arry[0]-10);
                    food.show();
                }
            }
        }
    }

吃到自己

//吃到自己
    function EatSelf(x,y) {
        for(var i=0;i<snake.arrx.length-1;i++) {
            if(snake.movedirection==0) {//向左
                //條件和吃到食物類似就是判斷舌頭的坐標和身體的左邊,同理不同方向移動時條件也是不一樣的
                if (snake.arry[i] == y && x-snake.arrx[i] == 10) {
                    died();
                }
            }else if(snake.movedirection==1){//向上
                if (snake.arrx[i] == x && y-snake.arry[i] == 10) {
                    died();
                }
            }else if(snake.movedirection==2){//向右
                if (snake.arry[i] == y && snake.arrx[i]-x == 10) {
                    died();
                }
            }else{//向下
                if (snake.arrx[i] == x && snake.arry[i]-y == 10) {
                    died();
                }
            }
        }
    }
//停止計時器事件和移除方向事件
    function died() {
        alert("你掛了!");
        clearInterval(snakemove);
        document.removeEventListener("keydown", Controldirection);
        return;
    }
 document.addEventListener("keydown", Controldirection);
    food.show();
    snake.behavior();
    var snakemove =setInterval(function () {
        DrawSnake();
    },300);

基本功能大概就是這樣。可能還不算完美,後面有時間繼續優化一下!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現象:angular Cannot find module 'angular-in-memory-web-api'報錯找不動“angular-in-memory-web-api”模塊 解決:1、控制台運行 npm install angular-in-memory-web-api --save2、重 ...
  • 用途 遍歷一個jQuery對象,為每個匹配的元素執行一個函數。 語法 .each(function) 參數 function:類型為Function(Integer index,Element element),每個匹配的元素要執行的函數 可以通過讓回調函數返回false來終止迭代。 返回值 返回調 ...
  • 用途 jQuery.trim()函數用於刪除指定字元串開頭和結尾的空格。 $.trim()函數將刪除指定字元串開頭和結尾的所有的換行符、空格,以及製表符。 語法 jQuery.trim(str) 參數 str:要去除前後空格的字元串 返回值 jQuery.trim()方法返回去除了前後空格的字元串 ...
  • substring 方法用於提取字元串中介於兩個指定下標之間的字元 substring(start,end) 開始和結束的位置,從零開始的索引 返回值是一個新的字元串,該字元串值包含 stringObject 的一個子字元串 substring 方法返回的子串包括 start 處的字元,但不包括 e ...
  • 1.DOM內部插入append()與appendTo() 動態創建的元素是不夠的,它只是臨時存放在記憶體中,最終我們需要放到頁面文檔並呈現出來。那麼問題來了,怎麼放到文檔上? 這裡就涉及到一個位置關係,常見的就是把這個新創建的元素,當作頁面某一個元素的子元素放到其內部。針對這樣的處理,jQuery就定 ...
  • 近日壓力山大,找找樂子,看有沒有好的東西可以研究研究,剛好看到我的螞蟻森林居然可以種樹了,很好奇,難道馬雲真會種樹? 二話不說,利用本人專業所學(遙感專業,有木有同行??),來監測監測那些樹木長得如何了?是不是真有,二話不說,直接上圖!! 註意,這裡是螞蟻森林種植的大概範圍,我從高德地圖查詢到的,內 ...
  • [1]坐標定位 [2]四個坐標系 [3]圖形變換 [4]居中變換 ...
  • 說到原生瀏覽器事件函數處理相容,大家可能會想到addEventListener().....以及attachEvent()....相信看了下文,會給你提供不一樣的更優雅的實現方式,希望下文會對你有幫助~~~~~ 總結:以上方法也是jquery源碼中Event模塊中add的方法的借鑒來源,資料來源於此 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...