HTML贪吃蛇游戏源码(穿墙)

news2025/1/18 2:02:53

演示

在这里插入图片描述

完整HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title><・)))><<</title>
    <link rel="shortcut icon" href="${ctx}/image/snake_eating.png">
    <meta name="referrer" content="no-referrer">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <meta name="renderer" content="webkit"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <meta name="format-detection" content="telephone=no"/>
    <style>
        * {
            box-sizing: border-box;
        }

        html,
        body {
            background-color: #000;
            height: 99%;
            border-radius: 50px;
        }

        body {
            background: #222;
            background: -webkit-radial-gradient(#333, #111);
            background: radial-gradient(#333, #111);
            background-position: center center;
            background-repeat: no-repeat;
            background-size: cover;
            color: #fff;
            font: 100%/1.5 sans-serif;
            overflow: hidden;
        }

        /*================================================

        Score

        ================================================*/

        .score {
            color: rgba(255, 255, 255, 0.5);
            font-size: 17px;
            font-weight: bold;
            padding-top: 0.2%;
            text-align: center;
        }

        /*================================================

        hightScoreDiv

        ================================================*/
        #introduce {
            color: rgba(255, 255, 255, 0.5);
            font-size: 17px;
            font-weight: bold;
            padding-top: 0.2%;
            text-align: center;
        }

        .hightScoreDiv {
            color: rgba(255, 255, 255, 0.5);
            font-size: 17px;
            font-weight: bold;
            padding-top: 0.2%;
            text-align: center;
        }

        /*================================================

        Stage

        ================================================*/
        .stage {
            bottom: 0;
            left: 0;
            margin: auto;
            position: absolute;
            right: 0;
            top: 0;
            z-index: 2;
        }

        /*================================================

        Tiles

        ================================================*/

        .tile {
            background: rgba(0, 0, 0, 0.15);
            position: absolute;
            -webkit-transition-property: background,
            box-shadow,
            opacity,
            -webkit-transform;
            transition-property: background,
            box-shadow,
            opacity,
            -webkit-transform;
            transition-property: background,
            box-shadow,
            opacity,
            transform;
            transition-property: background,
            box-shadow,
            opacity,
            transform,
            -webkit-transform;
            -webkit-transform: translateZ(0);
            transform: translateZ(0);
            -webkit-transition-duration: 3000ms;
            transition-duration: 3000ms;
        }

        .tile:before {
            bottom: 0;
            content: '';
            height: 0;
            left: 0;
            margin: auto;
            opacity: 0;
            position: absolute;
            right: 0;
            top: 0;
            width: 0;
            -webkit-transition: opacity 300ms;
            transition: opacity 300ms;
        }

        .tile.path:before {
            opacity: 1;
        }

        .tile.up:before {
            border-bottom: 4px inset rgba(255, 255, 255, 0.15);
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
        }

        .tile.down:before {
            border-top: 4px inset rgba(255, 255, 255, 0.15);
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
        }

        .tile.left:before {
            border-right: 4px inset rgba(255, 255, 255, 0.15);
            border-top: 4px solid transparent;
            border-bottom: 4px solid transparent;
        }

        .tile.right:before {
            border-left: 4px inset rgba(255, 255, 255, 0.15);
            border-top: 4px solid transparent;
            border-bottom: 4px solid transparent;
        }

        @media (max-width: 900px), (max-height: 900px) {
            .tile.up:before,
            .tile.down:before,
            .tile.left:before,
            .tile.right:before {
                border-width: 3px;
            }
        }

        @media (max-width: 500px), (max-height: 500px) {
            .tile.up:before,
            .tile.down:before,
            .tile.left:before,
            .tile.right:before {
                border-width: 2px;
            }
        }

        .tile.pressed {
            background: rgba(0, 0, 0, 0.3);
            box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.6);
            -webkit-transition-duration: 0ms;
            transition-duration: 0ms;
        }
    </style>
</head>
<body>
<div id="eating">
    <div id="introduce">移动:方向键 / 上(W)、下(S)、左(A)、右(D)</div>
    <div class="hightScoreDiv">最高得分:<span id="hightScore">0</span></div>
    <div class="hightScoreDiv">当前得分:<span class="score">0</span></div>
    <div class="stage"></div>
</div>
<div id="phone" style="position: absolute;width: 99%;display: none">
    <div style="width: 100%;padding: 2em 0em;text-align: center;background-color: rgb(0,0,0);font-size: 1.5em;margin-top: 10em">
        暂不支持手机访问😊<br><br>
        <a href="javascript:void(0)" onclick="window.open('../index.html')" style="text-decoration: none;padding: 0.5em 1em;font-size: 0.7em;color: #c7c7c7;background: #c70000;border-radius: 30px;font-weight: bold">返回首页</a></div>
</div>
<!--底部版权信息-->
<div style="position: fixed; bottom: 10px;width: 100%;text-align: center;-moz-user-select: none; -khtml-user-select: none; user-select: none;">
			<span style="color: #666666;font-size:0.5em"><a href="https://beian.miit.gov.cn/" target="_blank"
                                                            style="color: #666666;text-decoration: none;" title="备案查询">湘ICP备2021002539号-1</a> &copy; All rights reserved by
				<a href="javascript:void(0)" onclick="authors()" style="color: #0082ff;text-decoration: none;"
                   title="启用QQ联系作者">霸霸😈</a>
			</span>
</div>
<script type="text/javascript">

    window.onload = function (){
        if(isMobile()){
            document.getElementById("phone").style.display="block";
            document.getElementById("eating").style.display="none";
        }
    }
    //判断是否为手机访问
    function isMobile() {
        var userAgentInfo = navigator.userAgent;
        var mobileAgents = ["Android", "iPhone", "SymbianOS", "iPad", "iPod", "ipad", "android", "iphone", "ipod"];//Windows Phone
        var mobile_flag = false;
        //根据userAgent判断是否是手机
        for (var v = 0; v < mobileAgents.length; v++) {
            if (userAgentInfo.indexOf(mobileAgents[v]) > 0) {
                mobile_flag = true;
                break;
            }
        }
        return mobile_flag;
    }
    function authors() {
        alert("联系方式:\n微信号:onlyoneshun\n\n博客地址:\nCSDN:https://yushun.blog.csdn.net")
    }

    /*================================================

      Polyfill

      ================================================*/

    (function () {
        'use strict';
        /*================================================

        Request Animation Frame

        ================================================*/

        var lastTime = 0;
        var vendors = ['webkit', 'moz'];
        for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = function (callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(
                    function () {
                        callback(currTime + timeToCall);
                    }, timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            }
        }

        if (!window.cancelAnimationFrame) {
            window.cancelAnimationFrame = function (id) {
                clearTimeout(id);
            }
        }

    })();

    /*================================================

    DOM Manipulation

    ================================================*/

    (function () {
        'use strict';

        function hasClass(elem, className) {
            return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');
        };

        function addClass(elem, className) {
            if (!hasClass(elem, className)) {
                elem.className += ' ' + className;
            }
        };

        function removeClass(elem, className) {
            var newClass = ' ' + elem.className.replace(/[\t\r\n]/g, ' ') + ' ';
            if (hasClass(elem, className)) {
                while (newClass.indexOf(' ' + className + ' ') >= 0) {
                    newClass = newClass.replace(' ' + className + ' ', ' ');
                }
                elem.className = newClass.replace(/^\s+|\s+$/g, '');
            }
        };

        function toggleClass(elem, className) {
            var newClass = ' ' + elem.className.replace(/[\t\r\n]/g, ' ') + ' ';
            if (hasClass(elem, className)) {
                while (newClass.indexOf(' ' + className + ' ') >= 0) {
                    newClass = newClass.replace(' ' + className + ' ', ' ');
                }
                elem.className = newClass.replace(/^\s+|\s+$/g, '');
            } else {
                elem.className += ' ' + className;
            }
        };

    })();

    /*================================================

    Core

    ================================================*/

    g = {};

    (function () {
        'use strict';

        /*================================================

        Math

        ================================================*/

        g.m = Math;
        g.mathProps = 'E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan ceil cos exp floor log round sin sqrt tan atan2 pow max min'.split(' ');
        for (var i = 0; i < g.mathProps.length; i++) {
            g[g.mathProps[i]] = g.m[g.mathProps[i]];
        }
        g.m.TWO_PI = g.m.PI * 2;

        /*================================================

        Miscellaneous

        ================================================*/

        g.isset = function (prop) {
            return typeof prop != 'undefined';
        };

        g.log = function () {
            if (g.isset(g.config) && g.config.debug && window.console) {
                console.log(Array.prototype.slice.call(arguments));
            }
        };

    })();

    /*================================================

    Group

    ================================================*/

    (function () {
        'use strict';

        g.Group = function () {
            this.collection = [];
            this.length = 0;
        };

        g.Group.prototype.add = function (item) {
            this.collection.push(item);
            this.length++;
        };

        g.Group.prototype.remove = function (index) {
            if (index < this.length) {
                this.collection.splice(index, 1);
                this.length--;
            }
        };

        g.Group.prototype.empty = function () {
            this.collection.length = 0;
            this.length = 0;
        };

        g.Group.prototype.each = function (action, asc) {
            var asc = asc || 0,
                i;
            if (asc) {
                for (i = 0; i < this.length; i++) {
                    this.collection[i][action](i);
                }
            } else {
                i = this.length;
                while (i--) {
                    this.collection[i][action](i);
                }
            }
        };

    })();

    /*================================================

    Utilities

    ================================================*/

    (function () {
        'use strict';

        g.util = {};

        /*================================================

        Random

        ================================================*/

        g.util.rand = function (min, max) {
            return g.m.random() * (max - min) + min;
        };

        g.util.randInt = function (min, max) {
            return g.m.floor(g.m.random() * (max - min + 1)) + min;
        };

    }());

    /*================================================

    State

    ================================================*/

    (function () {
        'use strict';

        g.states = {};

        g.addState = function (state) {
            g.states[state.name] = state;
        };
        var hightScore = "0";
        g.setState = function (name) {
            if (g.state) {
                var score = document.querySelector('.score').innerHTML;
                confirm("游戏结束!本局得分:" + score);
                if (parseInt(score) == 0 || parseInt(score) > parseInt(hightScore)) {
                    hightScore = score;
                    document.getElementById("hightScore").innerText = "当前得分:"+score;
                }
                g.states[g.state].exit();
            }

            g.state = name;
            g.states[g.state].init();
        };

        g.currentState = function () {
            return g.states[g.state];
        };

    }());

    /*================================================

    Time

    ================================================*/

    (function () {
        'use strict';

        g.Time = function () {
            this.reset();
        }

        g.Time.prototype.reset = function () {
            this.now = Date.now();
            this.last = Date.now();
            this.delta = 60;
            this.ndelta = 1;
            this.elapsed = 0;
            this.nelapsed = 0;
            this.tick = 0;
        };

        g.Time.prototype.update = function () {
            this.now = Date.now();
            this.delta = this.now - this.last;
            this.ndelta = Math.min(Math.max(this.delta / (1000 / 60), 0.0001), 10);
            this.elapsed += this.delta;
            this.nelapsed += this.ndelta;
            this.last = this.now;
            this.tick++;
        };

    })();

    /*================================================

    Grid Entity

    ================================================*/

    (function () {
        'use strict';

        g.Grid = function (cols, rows) {
            this.cols = cols;
            this.rows = rows;
            this.tiles = [];
            for (var x = 0; x < cols; x++) {
                this.tiles[x] = [];
                for (var y = 0; y < rows; y++) {
                    this.tiles[x].push('empty');
                }
            }
        };

        g.Grid.prototype.get = function (x, y) {
            return this.tiles[x][y];
        };

        g.Grid.prototype.set = function (x, y, val) {
            this.tiles[x][y] = val;
        };

    })();

    /*================================================

    Board Tile Entity

    ================================================*/

    (function () {
        'use strict';

        g.BoardTile = function (opt) {
            this.parentState = opt.parentState;
            this.parentGroup = opt.parentGroup;
            this.col = opt.col;
            this.row = opt.row;
            this.x = opt.x;
            this.y = opt.y;
            this.z = 0;
            this.w = opt.w;
            this.h = opt.h;
            this.elem = document.createElement('div');
            this.elem.style.position = 'absolute';
            this.elem.className = 'tile';
            this.parentState.stageElem.appendChild(this.elem);
            this.classes = {
                pressed: 0,
                path: 0,
                up: 0,
                down: 0,
                left: 0,
                right: 0
            }
            this.updateDimensions();
        };

        g.BoardTile.prototype.update = function () {
            for (var k in this.classes) {
                if (this.classes[k]) {
                    this.classes[k]--;
                }
            }

            if (this.parentState.food.tile.col == this.col || this.parentState.food.tile.row == this.row) {
                this.classes.path = 1;
                if (this.col < this.parentState.food.tile.col) {
                    this.classes.right = 1;
                } else {
                    this.classes.right = 0;
                }
                if (this.col > this.parentState.food.tile.col) {
                    this.classes.left = 1;
                } else {
                    this.classes.left = 0;
                }
                if (this.row > this.parentState.food.tile.row) {
                    this.classes.up = 1;
                } else {
                    this.classes.up = 0;
                }
                if (this.row < this.parentState.food.tile.row) {
                    this.classes.down = 1;
                } else {
                    this.classes.down = 0;
                }
            } else {
                this.classes.path = 0;
            }

            if (this.parentState.food.eaten) {
                this.classes.path = 0;
            }
        };

        g.BoardTile.prototype.updateDimensions = function () {
            this.x = this.col * this.parentState.tileWidth;
            this.y = this.row * this.parentState.tileHeight;
            this.w = this.parentState.tileWidth - this.parentState.spacing;
            this.h = this.parentState.tileHeight - this.parentState.spacing;
            this.elem.style.left = this.x + 'px';
            this.elem.style.top = this.y + 'px';
            this.elem.style.width = this.w + 'px';
            this.elem.style.height = this.h + 'px';
        };

        g.BoardTile.prototype.render = function () {
            var classString = '';
            for (var k in this.classes) {
                if (this.classes[k]) {
                    classString += k + ' ';
                }
            }
            this.elem.className = 'tile ' + classString;
        };

    })();

    /*================================================

    Snake Tile Entity

    ================================================*/

    (function () {
        'use strict';

        g.SnakeTile = function (opt) {
            this.parentState = opt.parentState;
            this.parentGroup = opt.parentGroup;
            this.col = opt.col;
            this.row = opt.row;
            this.x = opt.x;
            this.y = opt.y;
            this.w = opt.w;
            this.h = opt.h;
            this.color = null;
            this.scale = 1;
            this.rotation = 0;
            this.blur = 0;
            this.alpha = 1;
            this.borderRadius = 0;
            this.borderRadiusAmount = 0;
            this.elem = document.createElement('div');
            this.elem.style.position = 'absolute';
            this.parentState.stageElem.appendChild(this.elem);
        };

        g.SnakeTile.prototype.update = function (i) {
            this.x = this.col * this.parentState.tileWidth;
            this.y = this.row * this.parentState.tileHeight;
            if (i == 0) {
                this.color = '#fff';
                this.blur = this.parentState.dimAvg * 0.03 + Math.sin(this.parentState.time.elapsed / 200) * this.parentState.dimAvg * 0.015;
                if (this.parentState.snake.dir == 'n') {
                    this.borderRadius = this.borderRadiusAmount + '% ' + this.borderRadiusAmount + '% 0 0';
                } else if (this.parentState.snake.dir == 's') {
                    this.borderRadius = '0 0 ' + this.borderRadiusAmount + '% ' + this.borderRadiusAmount + '%';
                } else if (this.parentState.snake.dir == 'e') {
                    this.borderRadius = '0 ' + this.borderRadiusAmount + '% ' + this.borderRadiusAmount + '% 0';
                } else if (this.parentState.snake.dir == 'w') {
                    this.borderRadius = this.borderRadiusAmount + '% 0 0 ' + this.borderRadiusAmount + '%';
                }
            } else {
                this.color = '#fff';
                this.blur = 0;
                this.borderRadius = '0';
            }
            this.alpha = 1 - (i / this.parentState.snake.tiles.length) * 0.6;
            this.rotation = (this.parentState.snake.justAteTick / this.parentState.snake.justAteTickMax) * 90;
            this.scale = 1 + (this.parentState.snake.justAteTick / this.parentState.snake.justAteTickMax) * 1;
        };

        g.SnakeTile.prototype.updateDimensions = function () {
            this.w = this.parentState.tileWidth - this.parentState.spacing;
            this.h = this.parentState.tileHeight - this.parentState.spacing;
        };

        g.SnakeTile.prototype.render = function (i) {
            this.elem.style.left = this.x + 'px';
            this.elem.style.top = this.y + 'px';
            this.elem.style.width = this.w + 'px';
            this.elem.style.height = this.h + 'px';
            this.elem.style.backgroundColor = 'rgba(255, 255, 255, ' + this.alpha + ')';
            this.elem.style.boxShadow = '0 0 ' + this.blur + 'px #fff';
            this.elem.style.borderRadius = this.borderRadius;
        };

    })();

    /*================================================

    Food Tile Entity

    ================================================*/

    (function () {
        'use strict';

        g.FoodTile = function (opt) {
            this.parentState = opt.parentState;
            this.parentGroup = opt.parentGroup;
            this.col = opt.col;
            this.row = opt.row;
            this.x = opt.x;
            this.y = opt.y;
            this.w = opt.w;
            this.h = opt.h;
            this.blur = 0;
            this.scale = 1;
            this.hue = 100;
            this.opacity = 0;
            this.elem = document.createElement('div');
            this.elem.style.position = 'absolute';
            this.parentState.stageElem.appendChild(this.elem);
        };

        g.FoodTile.prototype.update = function () {
            this.x = this.col * this.parentState.tileWidth;
            this.y = this.row * this.parentState.tileHeight;
            this.blur = this.parentState.dimAvg * 0.03 + Math.sin(this.parentState.time.elapsed / 200) * this.parentState.dimAvg * 0.015;
            this.scale = 0.8 + Math.sin(this.parentState.time.elapsed / 200) * 0.2;

            if (this.parentState.food.birthTick || this.parentState.food.deathTick) {
                if (this.parentState.food.birthTick) {
                    this.opacity = 1 - (this.parentState.food.birthTick / 1) * 1;
                } else {
                    this.opacity = (this.parentState.food.deathTick / 1) * 1;
                }
            } else {
                this.opacity = 1;
            }
        };

        g.FoodTile.prototype.updateDimensions = function () {
            this.w = this.parentState.tileWidth - this.parentState.spacing;
            this.h = this.parentState.tileHeight - this.parentState.spacing;
        };

        g.FoodTile.prototype.render = function () {
            this.elem.style.left = this.x + 'px';
            this.elem.style.top = this.y + 'px';
            this.elem.style.width = this.w + 'px';
            this.elem.style.height = this.h + 'px';
            this.elem.style['transform'] = 'translateZ(0) scale(' + this.scale + ')';
            this.elem.style.backgroundColor = 'hsla(' + this.hue + ', 100%, 60%, 1)';
            this.elem.style.boxShadow = '0 0 ' + this.blur + 'px hsla(' + this.hue + ', 100%, 60%, 1)';
            this.elem.style.opacity = this.opacity;
        };

    })();

    /*================================================

    Snake Entity

    ================================================*/

    (function () {
        'use strict';

        g.Snake = function (opt) {
            this.parentState = opt.parentState;
            this.dir = 'e',
                this.currDir = this.dir;
            this.tiles = [];
            for (var i = 0; i < 5; i++) {
                this.tiles.push(new g.SnakeTile({
                    parentState: this.parentState,
                    parentGroup: this.tiles,
                    col: 8 - i,
                    row: 3,
                    x: (8 - i) * opt.parentState.tileWidth,
                    y: 3 * opt.parentState.tileHeight,
                    w: opt.parentState.tileWidth - opt.parentState.spacing,
                    h: opt.parentState.tileHeight - opt.parentState.spacing
                }));
            }
            this.last = 0;
            this.updateTick = 10;
            this.updateTickMax = this.updateTick;
            this.updateTickLimit = 3;
            this.updateTickChange = 0.2;
            this.deathFlag = 0;
            this.justAteTick = 0;
            this.justAteTickMax = 1;
            this.justAteTickChange = 0.05;

            // sync data grid of the play state
            var i = this.tiles.length;

            while (i--) {
                this.parentState.grid.set(this.tiles[i].col, this.tiles[i].row, 'snake');
            }
        };

        g.Snake.prototype.updateDimensions = function () {
            var i = this.tiles.length;
            while (i--) {
                this.tiles[i].updateDimensions();
            }
        };

        g.Snake.prototype.update = function () {
            if (this.parentState.keys.up) {
                if (this.dir != 's' && this.dir != 'n' && this.currDir != 's' && this.currDir != 'n') {
                    this.dir = 'n';
                }
            } else if (this.parentState.keys.down) {
                if (this.dir != 'n' && this.dir != 's' && this.currDir != 'n' && this.currDir != 's') {
                    this.dir = 's';
                }
            } else if (this.parentState.keys.right) {
                if (this.dir != 'w' && this.dir != 'e' && this.currDir != 'w' && this.currDir != 'e') {
                    this.dir = 'e';
                }
            } else if (this.parentState.keys.left) {
                if (this.dir != 'e' && this.dir != 'w' && this.currDir != 'e' && this.currDir != 'w') {
                    this.dir = 'w';
                }
            }

            this.parentState.keys.up = 0;
            this.parentState.keys.down = 0;
            this.parentState.keys.right = 0;
            this.parentState.keys.left = 0;

            this.updateTick += this.parentState.time.ndelta;
            if (this.updateTick >= this.updateTickMax) {
                // reset the update timer to 0, or whatever leftover there is
                this.updateTick = (this.updateTick - this.updateTickMax);

                // rotate snake block array
                this.tiles.unshift(new g.SnakeTile({
                    parentState: this.parentState,
                    parentGroup: this.tiles,
                    col: this.tiles[0].col,
                    row: this.tiles[0].row,
                    x: this.tiles[0].col * this.parentState.tileWidth,
                    y: this.tiles[0].row * this.parentState.tileHeight,
                    w: this.parentState.tileWidth - this.parentState.spacing,
                    h: this.parentState.tileHeight - this.parentState.spacing
                }));
                this.last = this.tiles.pop();
                this.parentState.stageElem.removeChild(this.last.elem);

                this.parentState.boardTiles.collection[this.last.col + (this.last.row * this.parentState.cols)].classes.pressed = 2;

                // sync data grid of the play state
                var i = this.tiles.length;

                while (i--) {
                    this.parentState.grid.set(this.tiles[i].col, this.tiles[i].row, 'snake');
                }
                this.parentState.grid.set(this.last.col, this.last.row, 'empty');


                // move the snake's head
                if (this.dir == 'n') {
                    this.currDir = 'n';
                    this.tiles[0].row -= 1;
                } else if (this.dir == 's') {
                    this.currDir = 's';
                    this.tiles[0].row += 1;
                } else if (this.dir == 'w') {
                    this.currDir = 'w';
                    this.tiles[0].col -= 1;
                } else if (this.dir == 'e') {
                    this.currDir = 'e';
                    this.tiles[0].col += 1;
                }

                // wrap walls
                this.wallFlag = false;
                if (this.tiles[0].col >= this.parentState.cols) {
                    this.tiles[0].col = 0;
                    this.wallFlag = true;
                }
                if (this.tiles[0].col < 0) {
                    this.tiles[0].col = this.parentState.cols - 1;
                    this.wallFlag = true;
                }
                if (this.tiles[0].row >= this.parentState.rows) {
                    this.tiles[0].row = 0;
                    this.wallFlag = true;
                }
                if (this.tiles[0].row < 0) {
                    this.tiles[0].row = this.parentState.rows - 1;
                    this.wallFlag = true;
                }

                // check death by eating self
                if (this.parentState.grid.get(this.tiles[0].col, this.tiles[0].row) == 'snake') {
                    this.deathFlag = 1;
                    clearTimeout(this.foodCreateTimeout);
                }

                // check eating of food
                if (this.parentState.grid.get(this.tiles[0].col, this.tiles[0].row) == 'food') {
                    this.tiles.push(new g.SnakeTile({
                        parentState: this.parentState,
                        parentGroup: this.tiles,
                        col: this.last.col,
                        row: this.last.row,
                        x: this.last.col * this.parentState.tileWidth,
                        y: this.last.row * this.parentState.tileHeight,
                        w: this.parentState.tileWidth - this.parentState.spacing,
                        h: this.parentState.tileHeight - this.parentState.spacing
                    }));
                    if (this.updateTickMax - this.updateTickChange > this.updateTickLimit) {
                        this.updateTickMax -= this.updateTickChange;
                    }
                    this.parentState.score++;
                    this.parentState.scoreElem.innerHTML = this.parentState.score;
                    this.justAteTick = this.justAteTickMax;

                    this.parentState.food.eaten = 1;
                    this.parentState.stageElem.removeChild(this.parentState.food.tile.elem);

                    var _this = this;

                    this.foodCreateTimeout = setTimeout(function () {
                        _this.parentState.food = new g.Food({
                            parentState: _this.parentState
                        });
                    }, 300);
                }

                // check death by eating self
                if (this.deathFlag) {
                    g.setState('play');
                }
            }

            // update individual snake tiles
            var i = this.tiles.length;
            while (i--) {
                this.tiles[i].update(i);
            }

            if (this.justAteTick > 0) {
                this.justAteTick -= this.justAteTickChange;
            } else if (this.justAteTick < 0) {
                this.justAteTick = 0;
            }
        };

        g.Snake.prototype.render = function () {
            // render individual snake tiles
            var i = this.tiles.length;
            while (i--) {
                this.tiles[i].render(i);
            }
        };

    })();

    /*================================================

    Food Entity

    ================================================*/

    (function () {
        'use strict';

        g.Food = function (opt) {
            this.parentState = opt.parentState;
            this.tile = new g.FoodTile({
                parentState: this.parentState,
                col: 0,
                row: 0,
                x: 0,
                y: 0,
                w: opt.parentState.tileWidth - opt.parentState.spacing,
                h: opt.parentState.tileHeight - opt.parentState.spacing
            });
            this.reset();
            this.eaten = 0;
            this.birthTick = 1;
            this.deathTick = 0;
            this.birthTickChange = 0.025;
            this.deathTickChange = 0.05;
        };

        g.Food.prototype.reset = function () {
            var empty = [];
            for (var x = 0; x < this.parentState.cols; x++) {
                for (var y = 0; y < this.parentState.rows; y++) {
                    var tile = this.parentState.grid.get(x, y);
                    if (tile == 'empty') {
                        empty.push({x: x, y: y});
                    }
                }
            }
            var newTile = empty[g.util.randInt(0, empty.length - 1)];
            this.tile.col = newTile.x;
            this.tile.row = newTile.y;
        };

        g.Food.prototype.updateDimensions = function () {
            this.tile.updateDimensions();
        };

        g.Food.prototype.update = function () {
            // update food tile
            this.tile.update();

            if (this.birthTick > 0) {
                this.birthTick -= this.birthTickChange;
            } else if (this.birthTick < 0) {
                this.birthTick = 0;
            }

            // sync data grid of the play state
            this.parentState.grid.set(this.tile.col, this.tile.row, 'food');
        };

        g.Food.prototype.render = function () {
            this.tile.render();
        };

    })();

    /*================================================

    Play State

    ================================================*/

    (function () {
        'use strict';

        function StatePlay() {
            this.name = 'play';
        }

        StatePlay.prototype.init = function () {
            this.scoreElem = document.querySelector('.score');
            this.stageElem = document.querySelector('.stage');
            this.dimLong = 28;
            this.dimShort = 16;
            this.padding = 0.25;
            this.boardTiles = new g.Group();
            this.keys = {};
            this.foodCreateTimeout = null;
            this.score = 0;
            this.scoreElem.innerHTML = this.score;
            this.time = new g.Time();
            this.getDimensions();
            if (this.winWidth < this.winHeight) {
                this.rows = this.dimLong;
                this.cols = this.dimShort;
            } else {
                this.rows = this.dimShort;
                this.cols = this.dimLong;
            }
            this.spacing = 1;
            this.grid = new g.Grid(this.cols, this.rows);
            this.resize();
            this.createBoardTiles();
            this.bindEvents();
            this.snake = new g.Snake({
                parentState: this
            });
            this.food = new g.Food({
                parentState: this
            });
        };

        StatePlay.prototype.getDimensions = function () {
            this.winWidth = window.innerWidth;
            this.winHeight = window.innerHeight;
            this.activeWidth = this.winWidth - (this.winWidth * this.padding);
            this.activeHeight = this.winHeight - (this.winHeight * this.padding);
        };

        StatePlay.prototype.resize = function () {
            var _this = g.currentState();

            _this.getDimensions();

            _this.stageRatio = _this.rows / _this.cols;

            if (_this.activeWidth > _this.activeHeight / _this.stageRatio) {
                _this.stageHeight = _this.activeHeight;
                _this.stageElem.style.height = _this.stageHeight + 'px';
                _this.stageWidth = Math.floor(_this.stageHeight / _this.stageRatio);
                _this.stageElem.style.width = _this.stageWidth + 'px';
            } else {
                _this.stageWidth = _this.activeWidth;
                _this.stageElem.style.width = _this.stageWidth + 'px';
                _this.stageHeight = Math.floor(_this.stageWidth * _this.stageRatio);
                _this.stageElem.style.height = _this.stageHeight + 'px';
            }

            _this.tileWidth = ~~(_this.stageWidth / _this.cols);
            _this.tileHeight = ~~(_this.stageHeight / _this.rows);
            _this.dimAvg = (_this.activeWidth + _this.activeHeight) / 2;
            _this.spacing = Math.max(1, ~~(_this.dimAvg * 0.0025));

            _this.stageElem.style.marginTop = (-_this.stageElem.offsetHeight / 2) + _this.headerHeight / 2 + 'px';

            _this.boardTiles.each('updateDimensions');
            _this.snake !== undefined && _this.snake.updateDimensions();
            _this.food !== undefined && _this.food.updateDimensions();
        };

        StatePlay.prototype.createBoardTiles = function () {
            for (var y = 0; y < this.rows; y++) {
                for (var x = 0; x < this.cols; x++) {
                    this.boardTiles.add(new g.BoardTile({
                        parentState: this,
                        parentGroup: this.boardTiles,
                        col: x,
                        row: y,
                        x: x * this.tileWidth,
                        y: y * this.tileHeight,
                        w: this.tileWidth - this.spacing,
                        h: this.tileHeight - this.spacing
                    }));
                }
            }
        };

        StatePlay.prototype.upOn = function () {
            g.currentState().keys.up = 1;
        }
        StatePlay.prototype.downOn = function () {
            g.currentState().keys.down = 1;
        }
        StatePlay.prototype.rightOn = function () {
            g.currentState().keys.right = 1;
        }
        StatePlay.prototype.leftOn = function () {
            g.currentState().keys.left = 1;
        }
        StatePlay.prototype.upOff = function () {
            g.currentState().keys.up = 0;
        }
        StatePlay.prototype.downOff = function () {
            g.currentState().keys.down = 0;
        }
        StatePlay.prototype.rightOff = function () {
            g.currentState().keys.right = 0;
        }
        StatePlay.prototype.leftOff = function () {
            g.currentState().keys.left = 0;
        }

        StatePlay.prototype.keydown = function (e) {
            e.preventDefault();
            var e = (e.keyCode ? e.keyCode : e.which),
                _this = g.currentState();
            if (e === 38 || e === 87) {
                _this.upOn();
            }
            if (e === 39 || e === 68) {
                _this.rightOn();
            }
            if (e === 40 || e === 83) {
                _this.downOn();
            }
            if (e === 37 || e === 65) {
                _this.leftOn();
            }
        };

        StatePlay.prototype.bindEvents = function () {
            var _this = g.currentState();
            window.addEventListener('keydown', _this.keydown, false);
            window.addEventListener('resize', _this.resize, false);
        };

        StatePlay.prototype.step = function () {
            this.boardTiles.each('update');
            this.boardTiles.each('render');
            this.snake.update();
            this.snake.render();
            this.food.update();
            this.food.render();
            this.time.update();
        };

        StatePlay.prototype.exit = function () {
            window.removeEventListener('keydown', this.keydown, false);
            window.removeEventListener('resize', this.resize, false);
            this.stageElem.innerHTML = '';
            this.grid.tiles = null;
            this.time = null;
        };

        g.addState(new StatePlay());

    })();

    /*================================================

    Game

    ================================================*/

    (function () {
        'use strict';

        g.config = {
            title: 'Snakely',
            debug: window.location.hash == '#debug' ? 1 : 0,
            state: 'play'
        };

        g.setState(g.config.state);

        g.time = new g.Time();

        g.step = function () {
            requestAnimationFrame(g.step);
            g.states[g.state].step();
            g.time.update();
        };
        window.addEventListener('load', g.step, false);

    })();
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/155697.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中科大2006年复试机试题

中科大2006年复试机试题 文章目录中科大2006年复试机试题第一题问题描述解题思路及代码第二题问题描述解题思路及代码第三题问题描述解题思路及代码第四题问题描述解题思路及代码第五题问题描述解题思路及代码第六题问题描述解题思路及代码第一题 问题描述 求矩阵的转置。 给…

three.js入门篇6之 环境贴图、经纬线映射贴图与高动态范围成像HDR

目录013-1 环境贴图013-2 经纬度映射贴图与HDR013-1 环境贴图 就是把周边的环境&#xff0c;贴在物体的表面之上 注意&#xff1a;px&#xff1a;x轴正向&#xff0c;nx&#xff1a;x轴负向 import * as THREE from "three" // console.log(main.js,THREE);// 导入…

06什么是Fabless?什么是IDM?

Fabless是SIC&#xff08;半导体集成电路&#xff09;行业中无生产线设计公司的简称&#xff0c;只搞设计的无晶圆厂半导体公司&#xff0c;生产交给像台积电这样的代工厂去做。 IDM是整合元件制造商&#xff0c;像英特尔这样既设计又制造的就叫IDM&#xff0c;因为规模大&…

对于字节,16进制,2进制, 0xFF,位移的一些杂记

1.普通字符串95 对应的16进制的展示&#xff0c;使用工具查看如下图 下图为普通字符串 下图为95对应的16进制 95对应的16进制字符串为39 35》39代表一个字节 35代表另一个字节 &#xff08;一个字节是由两位16进制字符串组成&#xff0c;比如39或35&#xff09; 1个字节对应…

select for update加了行锁还是表锁?

最近在开发需求的时候&#xff0c;用到了select......for update。在代码评审的时候&#xff0c;一位同事说 &#xff0c;唯一索引一个非索引字段&#xff0c;是否可能会锁全表呢&#xff1f;本文将通过9个实验操作的例子&#xff0c;给大家验证select......for update到底加了…

迁移环境时,忘记私钥证书密码怎么办?

知行之桥的版本在进行不断更新&#xff0c;相较之前的版本而言&#xff0c;知行之桥每一次更新的版本&#xff0c;无论在操作还是功能亦或是便利性上都有更好的优势&#xff0c;因此不少企业会在新版本更新之后果断选择新的版本&#xff0c;企业选择版本更新之后&#xff0c;需…

He3 新版上新

系统功能更新 支持拖动工具&#xff0c;调整位置 支持置顶 支持自定义分类 新增工具 Paseto 生成器 2. 文本分析 JSON 转 PHP&#xff0c;YAML 转 PHP UTF7 编码、UTF7 解码 6. UTM 生成器 CSS 边框圆角生成器 CSV 类转换工具&#xff0c;目前支持 CSV 与 Markdown、HTML、JS…

什么是无代码ITSM工具

拥有强大 ITSM 团队的企业已经能够生存下来&#xff0c;并且在某些情况下在整个大流行期间表现出色。成功的 IT 团队以其在日常运营中断时快速恢复的能力而闻名。 当您需要重新组织服务交付流程时&#xff0c;ITSM 平台可以减少工程工作量&#xff0c;这对于制定弹性 ITSM 战略…

Python学习笔记——元组

Python将不能修改的值称为不可变的&#xff0c;而不可变的列表被称为元组。定义元组元组创建只需要在括号中添加元素&#xff0c;并使用逗号隔开即可。元组使用小括号 ( )&#xff0c;列表使用方括号 [ ]。定义元组后&#xff0c;就可以使用索引来访问其元素&#xff0c;就像访…

ansible作业二

ansible匹配自定义路径清单文件 查看当前匹配的清单文件路径 [rootserver ~]# ansible --version ansible [core 2.13.5]config file /etc/ansible/ansible.cfg --- 默认配置文件configured module search path [/root/.ansible/plugins/modules, /usr/share/ansible/plugin…

力扣(LeetCode)1150. 检查一个数是否在数组中占绝大多数(C++/Python3)

遍历 直观思考&#xff0c;一次遍历数组&#xff0c;计数 target 。用 target 出现次数和数组长度的一半做比较&#xff0c;即可得到答案。 class Solution { public:bool isMajorityElement(vector<int>& nums, int target) {int cnt 0;for(auto &x:nums)if(…

7、Servlet——Servlet核心接口和类、创建Servlet的三种方式

目录 一、Servlet核心接口和类 1、Servlet接口 2、GenericServlet抽象类 3、HttpServlet类 二、创建Servlet的三种方式 1、实现Servlet接口 2、继承GenericServlet抽象类 3、继承HttpServlet类 三、web.xml中其他配置 1、启动优先级&#xff1a; 2、url-pattern定…

【SpringCloud02】订单-支付微服务模块(支付模块构建)

1.微服务cloud整体聚合父工程Project New Project 聚合总父工程名字 Maven选版本 工程名字 字符编码 注解生效激活 Java编译版本选8 File Type过滤 2.父工程POM 2.1Pom.xml文件 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi&quo…

docker中MySQL忘记登录密码找回方法

查看docker启动列表 docker ps 进入启动的mysql容器中 docker exec -it mysql /bin/bash 修改mysql配置文件 vim /etc/mysql/conf.d/docker.cnf 在最后添加 skip-grant-tables 如果出现命令没找到&#xff0c;则需要安装。 依次使用以下命令安装vim apt-get update apt…

java 系列文章之异常

文章目录一、概念二、异常分类1. Error2. Exception三、异常的处理方式四、Throw 和 throws 的区别1. 位置不同2. 功能不同总结一、概念 果某个方法不能按照正常的途径完成任务&#xff0c;就可以通过另一种路径退出方法。在这种情况下会抛出一个封装了错误信息的对象。此时&a…

关于单行处理函数——ifnull()

我们先来看一个实例&#xff1a; 需求&#xff1a;在员工表emp中查看员工的年薪 分析&#xff1a;计算年薪除了月薪外补助也应该计算在内&#xff0c;所以年薪 (月薪 补助) * 12 sql语句&#xff1a;select ename,(sal comm) *12 as 年薪 from emp; …

SpringBoot+Vue项目在线拍卖系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…

编译原理分析器大作业之字幕分析器

写这篇文章的主要目的呢是分享一下编译原理大作业——电影字幕分析器&#xff0c;分享一下我的做法&#xff0c;可能采用的做法不是特别好的用法&#xff0c;希望各位多多指点&#xff0c;觉得文章不错给点小赞赞喔!!! 题目介绍 写一个srt字幕解释器&#xff0c;需要分析单词…

动手深度学习-线性神经网络:线性回归

目录线性模型&#xff08;1&#xff09;度量模型质量-损失函数&#xff08;2&#xff09;更新模型以提高模型预测质量-随机梯度下降线性回归的从零开始实现线性回归的简洁实现参考教程&#xff1a;https://courses.d2l.ai/zh-v2/线性模型 定义&#xff1a;回归&#xff08;reg…

FFmpeg音频重采样API(libswresample)

目录 参考 lswr功能介绍 lswr使用说明 示例代码 \1. 参考 [1] FFmpeg/Libswresample Documentation [2] FFmpeg/Libswresample Detailed Description [3] FFmpeg/doc/examples/resampling_audio.c \2. lswr功能介绍 FFmpeg中重采样的功能由libswresample(后面简写为lswr…