2048 test

<!DOCTYPE html>
<html lang="en">
    <head>
        <script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
        <script type="application/javascript">
            let img;
            function Tile(pos, val, puzzle){
                this.pos     = pos;
                this.val     = val;
                this.puzzle  = puzzle;
                this.merging = false;
                this.getCol = () => Math.round(this.pos % 4);
                this.getRow = () => Math.floor(this.pos / 4);
                this.show = function() {
                    let size = 0.25*width;
                    noStroke();
                    image(img[this.val],(this.getCol())*size, (this.getRow())*size);
                };
                this.move = function(dir) {
                    let col = this.getCol() + (1 - 2*(dir < 0))*Math.abs(dir)%4;
                    let row = this.getRow() + (1 - 2*(dir < 0))*Math.floor(Math.abs(dir)/4);
                    let target = this.puzzle.getTile(this.pos + dir);
                    if (col < 0 || col > 3 || row < 0 || row > 3) {
                        return false;
                    } else if (target) {
                        if(this.merging || target.merging || target.val !== this.val)
                            return false;
                        target.val += this.val;
                        target.merging = true;
                        this.puzzle.score += target.val;
                        this.puzzle.removeTile(this);
                        return true;
                    }
                    this.pos += dir;
                    return true;
                }
            }

            function Puzzle(){
                this.tiles = [];
                this.dir = 0;
                this.score = 0;
                this.hasMoved = false;
                this.validPositions = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

                this.getOpenPositions = () => this.validPositions.filter(i => this.tiles.map(x => x.pos).indexOf(i) === -1);
                this.getTile          = pos => this.tiles.filter(x => x.pos === pos)[0];
                this.removeTile       = tile => this.tiles.splice(this.tiles.indexOf(tile), 1);

                this.validMoves = function(){
                    if(this.tiles.length < 16)
                        return true;

                    let res = false;
                    this.tiles.sort((x,y) => x.pos - y.pos);
                    for(let i = 0; i < 16; i++)
                        res = res || ( (i%4 < 3) ? this.tiles[i].val === this.tiles[i+1].val : false )
                            || ( (i  < 12) ? this.tiles[i].val === this.tiles[i+4].val : false );
                    return res;
                };

                this.checkGameState = function(){
                    if (!this.validMoves()){
                        alert('Game Over!');
                        this.restart();
                    }
                };

                this.restart = function(){
                    this.tiles    = [];
                    this.dir      = 0;
                    this.score    = 0;
                    this.hasMoved = false;
                    this.generateTile();
                    this.generateTile();
                };

                this.show = function(){
                    background([251,244,252]);
                    fill([248,214,247]);
                    textSize(0.05*width);
                    textAlign(CENTER, TOP);
                    text("SCORE: " + this.score, 0.5*width, width);

                    for(let tile of this.tiles)
                        tile.show();
                };

                this.animate = function(){
                    if(this.dir === 0)
                        return;

                    let moving = false;
                    this.tiles.sort((x,y) => this.dir*(y.pos - x.pos));
                    for(let tile of this.tiles)
                        moving = moving || tile.move(this.dir);

                    if(this.hasMoved && !moving){
                        this.dir = 0;
                        this.generateTile();

                        for(let tile of this.tiles)
                            tile.merging = false;
                    }
                    this.hasMoved = moving;
                };

                this.generateTile = function(){
                    let positions = this.getOpenPositions();
                    let pos       = positions[Math.floor(Math.random()*positions.length)];
                    let val       = 2 + 2*Math.floor(Math.random()*1.11);
                    this.tiles.push(new Tile(pos, val, this));
                };
                this.generateTile();
                this.generateTile();

                this.keyHandler = function(key) {
                    if (key === UP_ARROW) this.dir = -4;
                    else if (key === DOWN_ARROW) this.dir = 4;
                    else if (key === RIGHT_ARROW) this.dir = 1;
                    else if (key === LEFT_ARROW) this.dir = -1;
                }
            }

            let game;

            function setup() {
                createCanvas(400, 420);
                img = {
                    2:loadImage('2.png'),
                    4:loadImage('4.png'),
                    8:loadImage('8.png'),
                    16:loadImage('16.png'),
                    32:loadImage('32.png'),
                    64:loadImage('64.png'),
                    128:loadImage('128.png'),
                    256:loadImage('256.png'),
                    512:loadImage('512.png'),
                    1024:loadImage('1024.png'),
                    2048:loadImage('2048.png'),
                    4096:loadImage('4096.png'),
                    8192:loadImage('8192.png'),
                    16384:loadImage('16384.png'),
                    32768:loadImage('32768.png'),
                    65536:loadImage('65536.png')
                };
                game = new Puzzle();
            }

            function draw() {
                game.checkGameState();
                game.animate();
                game.show();
            }

            function keyPressed(){
                game.keyHandler(keyCode);
            }
            
            let preX = 0;
            let preY = 0;

            function touchStarted(event) {
                preX = mouseX;
                preY = mouseY;
                if (touches.length === 1) event.preventDefault();
            }

            function touchEnded() {
                let dx = mouseX - preX;
                let dy = mouseY - preY;
                if (Math.abs(dx) > Math.abs(dy)) {
                    if (dx > 0) game.keyHandler(RIGHT_ARROW);
                    else game.keyHandler(LEFT_ARROW);
                } else {
                    if (dy < 0) game.keyHandler(UP_ARROW);
                    else game.keyHandler(DOWN_ARROW);
                }
            }
        </script>
        <script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <title>2048</title>
    </head>
    <body id="main" onload="(() => $('#main').css('transform','scale(' + (window.innerHeight < window.innerWidth ? window.innerHeight : window.innerWidth) / 420 + ')'))()" style="position: absolute; transform-origin: 0 0"></body>
</html>

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注