沒事寫個游戲自己玩~

来源:http://www.cnblogs.com/-Steven/archive/2017/12/19/8060431.html
-Advertisement-
Play Games

小時候懷念的貪吃蛇游戲~~啦啦啦 ...


小時候懷念的貪吃蛇游戲~~啦啦啦

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>貪吃蛇</title>
    <style>
        body,
html {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background-color: #89ecb6;
}
.container {
  width: 800px;
  border: 4px solid #000;
  margin: 40px auto 0;
}
.container .map {
  width: 500px;
  margin: 20px auto;
}
.container .map div {
  height: 25px;
}
.container .map div span {
  float: left;
  width: 25px;
  height: 25px;
  background-color: #ffffff;
  box-sizing: border-box;
  border: 0.5px solid #4ec4d4;
}
.container .map div span.snake {
  background-color: black;
}
.container .map div span.food {
  background-color: red;
}
.container .map div span.head {
  border-radius: 50%;
  background-color: #d0ff00;
}
.container .footer {
  border-top: 2px solid #000;
  padding: 20px 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
}
.container .footer .startBtn {
  cursor: pointer;
}
.container .footer .startBtn:hover {
  color: red;
}

    </style>
</head>

<body>
    <div class="container">
        <div class="map">

        </div>
        <div class="footer">
            <div class="startBtn">開始游戲</div>
            <div class="coins">得分:<span class="score">0</span>分</div>
        </div>
    </div>
</body>
<script>
    //單列模式
const RetroSnaker = {
    x:20,//地圖X大小
    y:20,//地圖Y大小
    snake:[],//蛇的數據
    snakeLen:4,
    viewMap:[],//用來繪製蛇以及其他物品的  其實就是所有span  地圖
    dataMap:[],//存放所有的數據
    direction:39,//存儲方向
    changeDirAble:true,//能否改變方向
    speed:200,
    score:0,
    scoreInfo:document.querySelector('.score'),
    initMap(){
        this.createMap();;
    },
    initGame(){
        this.initSnake();
        this.addObject('food');
        this.changeDir();
        this.walk();

    },
    createData(){
        let {x,y} = this;
        let map  =new Array(y);
        for (let i = 0;i<map.length;i++){
            map[i] = new Array(x).fill(false);
        }
        
        return map;
    },
    createMap(){
        let gameMap = document.querySelector('.map');
        window.removeEventListener('keydown',this.changeDir.fn);
        clearInterval(this.gameTimer);
        this.scoreInfo.innerHTML = this.score = 0;
        gameMap.innerHTML ='';
        this.changeDirAble =true;
        this.direction=39;
        this.snake =[];
        this.viewMap = this.createData();
        this.dataMap = this.createData();
        let{x,y,viewMap,dataMap} = this;
        for(let i =0;i<y;i++){
            const row = document.createElement('div');
            for(let j = 0;j<x;j++){
                const col= document.createElement('span');
                viewMap[i][j] = row.appendChild(col);
            }
            gameMap.appendChild(row);
        }
    },
    createPoint(startX,startY,endX,endY){
        let{x,y,dataMap} = this;
        // startX = startX ||0;
        // startY = startY ||0;
        let p = [];
        let X = this.rp([startX,endX]);
        let Y =this.rp([startY,endY]);
        //這個點不能生成到蛇身上
        if(dataMap[Y][X]){
            return this.createPoint(startX,startY,endX,endY);
        }
        p.push(Y,X)
        return p ;
    },
    //隨機數
    rp(arr){
        const min = Math.min(...arr);
        const max =Math.max(...arr);
        return Math.round(Math.random()*(max - min) + min)
    },
    initSnake(){
        let {snake,snakeLen,x,y,viewMap,dataMap} = this;
        let p= this.createPoint(snakeLen-1,0,x-snakeLen,y-1);
        for(let i=0;i<snakeLen;i++){
            let x = p[1] -i;
            let y = p[0];
            snake.push([y,x]);
            viewMap[y][x].className = !i?'head':'snake';
            dataMap[y][x] = 'snake';
        }
    },
    addObject(name){
        let {x,y,viewMap,dataMap} =this;
        let p =this.createPoint(0,0,x-1,y-1);
        viewMap[p[0]][p[1]].className = name;
        dataMap[p[0]][p[1]]= name;
    },
    walk(){
        clearInterval(this.gameTimer);
        this.gameTimer = setInterval(this._walk.bind(this),this.speed);
    },
    _walk(){
        let {snake,viewMap,dataMap} = this;
        let headX = snake[0][1];
        let headY = snake[0][0];
        viewMap[headY][headX].className = 'snake';
        //檢測方向
        switch(this.direction){
            case 37:
                headX -=1;
                break;
            case 38:
                headY -=1;
                break;
            case 39:
                headX +=1;
                break;
            case 40:
                headY +=1;
                break;
        }
        //如果不是食物就不增加長度
        //判斷下一個格子是不是牆壁或者自己
        if(headY>19||headY<0||headX>19||headX<0){//是牆壁
            this.endFn('撞牆啦!');
            return;
        }
        if(dataMap[headY][headX]!=='food'){
            let lastIndex = snake.length-1;
            let lastX=  snake[lastIndex][1];
            let lastY=  snake[lastIndex][0];
            snake.pop();
            viewMap[lastY][lastX].className = '';
            dataMap[lastY][lastX] = false;
            if(viewMap[headY][headX].classList.contains('snake')){
                this.endFn('吃了自己啦!');
            }
        }else{
            this.addObject('food');
            this.scoreInfo.innerHTML = ++this.score;
        }
        snake.unshift([headY,headX]);
        viewMap[headY][headX].className = 'snake head';
        dataMap[headY][headX] = 'snake';
        this.changeDirAble =true;
    },
    changeDir(){
        const fn = this.changeDir.fn = this._changeDIr.bind(this);
        window.addEventListener('keydown',fn);
    },
    _changeDIr(e){
        if(!this.changeDirAble) return;
        const {keyCode} = e;
        if(keyCode >36 && keyCode <41 &&Math.abs(this.direction-keyCode)!==2){
            this.direction = keyCode;
            this.changeDirAble =false;
        }
    },
    endFn(text){
        this.initMap();
        alert(text+'  '+'游戲結束');
    }
}
var start = document.querySelector('.startBtn');
RetroSnaker.initMap();
start.onclick = function(){
    RetroSnaker.initMap();
    RetroSnaker.initGame();
}
</script>
</html>

 


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

-Advertisement-
Play Games
更多相關文章
  • 1、Android系統目前支持的CPU架構:ARMv5、ARMv7、x86、MIPS、ARMv8、MIPS64、x86_64,每一種都關聯著一個ABI(Application Binary Interface) 2、ABI:定義了二進位文件(尤其是.so文件)如何運行在相應系統平臺上,包括使用的指令 ...
  • 問題引入: 有一個下載功能,在Android 5.x設備上運行正常,Android 6.x上運行異常,現象是下載進度卡在0%。 問題排查發現,是sdk的target設置為23導致,修改為21則恢復正常。 這就引出了今天討論的問題:Android中build target,minSdkVersion, ...
  • 一、簡介 什麼是cocoapods?——是OS X和iOS下一個第三方類庫管理工具。通過cocoapods,可以為項目添加“Pods“依賴庫,並且管理其版本。 cocoapods好處: (1)可以方便引入第三方依賴庫,自動完成各種配置:配置編譯階段、連接器選項等。 (2)可以方便查找新的、標準的第三 ...
  • 第二篇教程之前寫了一半,感覺不太好寫,而且內容單純介紹API,要說的很多,又枯燥乏味。所以那半篇文章就放下了。後來又開始思考這教程該怎麼寫,經過幾天的沉澱,終於有了一個決定:這個教程,就用IT戀里的實例來和大伙分享了,看看在實戰是怎麼被應用的。 ...
  • 實現應用自身被卸載時打開某一網址的c代碼 以上c文件源碼和使用的文章出自: http://blog.csdn.net/qq_21793463/article/details/48246685 向您的項目添加 C 和 C++ 代碼 搭配使用 Android Studio 2.2 或更高版本與 Andr ...
  • 原文鏈接:http://www.cnblogs.com/feidu/p/8057012.html 當Android跨進程啟動Activity時,過程界面很黑屏(白屏)短暫時間(幾百毫秒?)。當然從桌面Lunacher啟動一個App時也會出現相同情況,那是因為App冷啟動也屬於跨進程啟動Activit ...
  • 1、概述 Vue在觀察到數據變化時並不是立即更新DOM,而是開啟一個隊列,並緩衝在同一個事件迴圈中發生所有數據的改變。 在緩衝時會去除重覆的數據,從而避免不必要的計算和DOM操作。 在下一個事件迴圈的tick中,Vue刷新隊列並執行實際(已去重)的工作。 $nextTick就是知道什麼時候DOM更新 ...
  • 常用標簽的行內類型標簽有:a、span、img;塊級標簽有:div、p、h1~6、ul、ol、li、dl、dt、dd。 行內類型標簽的特征:標簽的大小由標簽的內容決定,不能設置width和height,不會自動換行。 塊級標簽的特征:可以設置width和height,會自動換行。 行內類型標簽還有一 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...