沒事寫個游戲自己玩~

来源: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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...