HTML2048小游戏(最新版)

news2024/9/23 1:25:46

比上一篇文章的2048更好一点。 控制方法:WASD键(小写)或页面上四个按钮

效果图如下:                 源代码在图片后面   

源代码

 ·HTML·

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048 Game</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="game-container">
        <div id="game-board"></div>
        <div id="controls">
            <button id="up">W</button>
            <button id="left">A</button>
            <button id="down">S</button>
            <button id="right">D</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

 ·CSS·

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    font-family: 'Arial', sans-serif;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #faf8ef;
}

#game-container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

#game-board {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(4, 1fr);
    gap: 10px;
    background-color: #bbada0;
    padding: 10px;
    border-radius: 10px;
    margin-bottom: 20px;
}

.tile {
    width: 80px;
    height: 80px;
    background-color: #cdc1b4;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 24px;
    border-radius: 10px;
    transition: all 0.2s ease-in-out;
}

#controls {
    display: flex;
    gap: 10px;
}

button {
    width: 60px;
    height: 60px;
    font-size: 20px;
    border-radius: 10px;
    background-color: #8f7a66;
    color: white;
    border: none;
    cursor: pointer;
}

button:hover {
    background-color: #9f8b76;
}

  ·JavaScript·

document.addEventListener('DOMContentLoaded', () => {
    const boardSize = 4;
    let board = [];
    let score = 0;

    const gameBoard = document.getElementById('game-board');
    const buttons = {
        up: document.getElementById('up'),
        down: document.getElementById('down'),
        left: document.getElementById('left'),
        right: document.getElementById('right')
    };

    function initBoard() {
        for (let i = 0; i < boardSize * boardSize; i++) {
            const tile = document.createElement('div');
            tile.classList.add('tile');
            gameBoard.appendChild(tile);
        }
        board = Array.from(document.querySelectorAll('.tile'));
        generateTile();
        generateTile();
        updateBoard();
    }

    function generateTile() {
        let emptyTiles = board.filter(tile => !tile.textContent);
        if (emptyTiles.length > 0) {
            let randomTile = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
            randomTile.textContent = Math.random() < 0.9 ? '2' : '4';
        }
    }

    function updateBoard() {
        board.forEach(tile => {
            const value = tile.textContent;
            tile.style.backgroundColor = getTileColor(value);
        });
    }

    function getTileColor(value) {
        switch (value) {
            case '2': return '#eee4da';
            case '4': return '#ede0c8';
            case '8': return '#f2b179';
            case '16': return '#f59563';
            case '32': return '#f67c5f';
            case '64': return '#f65e3b';
            case '128': return '#edcf72';
            case '256': return '#edcc61';
            case '512': return '#edc850';
            case '1024': return '#edc53f';
            case '2048': return '#edc22e';
            default: return '#cdc1b4';
        }
    }

    function move(direction) {
        switch (direction) {
            case 'up': moveUp(); break;
            case 'down': moveDown(); break;
            case 'left': moveLeft(); break;
            case 'right': moveRight(); break;
        }
        generateTile();
        updateBoard();
    }

    function moveUp() {
        for (let i = 0; i < boardSize; i++) {
            let column = [];
            for (let j = 0; j < boardSize; j++) {
                column.push(board[i + j * boardSize].textContent);
            }
            let newColumn = slideTiles(column);
            for (let j = 0; j < boardSize; j++) {
                board[i + j * boardSize].textContent = newColumn[j];
            }
        }
    }

    function moveDown() {
        for (let i = 0; i < boardSize; i++) {
            let column = [];
            for (let j = 0; j < boardSize; j++) {
                column.push(board[i + j * boardSize].textContent);
            }
            let newColumn = slideTiles(column.reverse()).reverse();
            for (let j = 0; j < boardSize; j++) {
                board[i + j * boardSize].textContent = newColumn[j];
            }
        }
    }

    function moveLeft() {
        for (let i = 0; i < boardSize; i++) {
            let row = [];
            for (let j = 0; j < boardSize; j++) {
                row.push(board[i * boardSize + j].textContent);
            }
            let newRow = slideTiles(row);
            for (let j = 0; j < boardSize; j++) {
                board[i * boardSize + j].textContent = newRow[j];
            }
        }
    }

    function moveRight() {
        for (let i = 0; i < boardSize; i++) {
            let row = [];
            for (let j = 0; j < boardSize; j++) {
                row.push(board[i * boardSize + j].textContent);
            }
            let newRow = slideTiles(row.reverse()).reverse();
            for (let j = 0; j < boardSize; j++) {
                board[i * boardSize + j].textContent = newRow[j];
            }
        }
    }

    function slideTiles(tiles) {
        let newTiles = tiles.filter(tile => tile);
        for (let i = 0; i < newTiles.length - 1; i++) {
            if (newTiles[i] === newTiles[i + 1]) {
                newTiles[i] = (parseInt(newTiles[i]) * 2).toString();
                newTiles[i + 1] = '';
            }
        }
        newTiles = newTiles.filter(tile => tile);
        while (newTiles.length < boardSize) {
            newTiles.push('');
        }
        return newTiles;
    }

    buttons.up.addEventListener('click', () => move('up'));
    buttons.down.addEventListener('click', () => move('down'));
    buttons.left.addEventListener('click', () => move('left'));
    buttons.right.addEventListener('click', () => move('right'));

    document.addEventListener('keydown', (e) => {
        switch (e.key) {
            case 'w': move('up'); break;
            case 's': move('down'); break;
            case 'a': move('left'); break;
            case 'd': move('right'); break;
        }
    });

    initBoard();
});

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

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

相关文章

idea Apipost 插件导出接口文档字段类型全部是string

idea版本&#xff1a;2023.2.1 Apipost-Helper-2.0插件版本&#xff1a; 联系官方客服后&#xff0c;更换插件版本&#xff0c;问题解决。更换后的插件版本为&#xff1a; 插件链接放在文章首部了&#xff0c;可直接下载&#xff0c;使用idea直接安装这个zip包&#xff0c;无需…

内容安全(深度行为检测技术、IPS、AV、入侵检测方法)

1、深度行为检测技术 深度行为检测技术&#xff1a;是一种基于深度学习和机器学习的技术&#xff0c;它通过分析用户在网络中的行为模式&#xff0c;识别异常或潜在威胁行为&#xff0c;从而保护网络安全和内容安全 分类&#xff1a; 深度包检测技术&#xff08;Deep Packet…

uniapp转小程序,小程序转uniapp方法

&#x1f935; 作者&#xff1a;coderYYY &#x1f9d1; 个人简介&#xff1a;前端程序媛&#xff0c;目前主攻web前端&#xff0c;后端辅助&#xff0c;其他技术知识也会偶尔分享&#x1f340;欢迎和我一起交流&#xff01;&#x1f680;&#xff08;评论和私信一般会回&#…

【数据结构】单链表 双向链表

目录 链表链表的分类单链表单链表接口的实现内部类头插法尾插法任意位置插入查找是否包含关键字key是否在单链表当中删除第一次出现关键字为key的节点删除所有值为key的节点得到单链表的长度清空链表单链表的优缺点 双向链表双向链表接口的实现内部类头插法尾插法任意位置插入查…

0602STM32定时器输出比较

STM32定时器输出比较 PWM简介 主要用来输出PWM波形&#xff0c;PWM波形又是驱动电机的必要条件&#xff0c;所以如果想用STM32做一些有电机的项目&#xff0c;比如智能车&#xff0c;机器人等。那输出比较功能就要认真掌握 1.PWM驱动LED呼吸灯 2.PWM驱动舵机 3.PWM驱动直流电机…

5.5 软件工程-系统测试

系统测试 - 意义和目的 系统测试 - 原则 系统测试 - 测试过程 系统测试 - 测试策略 系统测试 - 测试方法 真题 系统测试 - 测试用例设计 黑盒测试 白盒测试 真题 系统测试 - 调试 系统测试 - 软件度量 真题

轨道交通AR交互教学定制公司优选深圳华锐视点

在寻找上海AR开发制作公司作为合作伙伴的过程中&#xff0c;选择一家既技术深厚又具备丰富经验的AR开发企业&#xff0c;成为了众多客户与合作伙伴的共同追求。华锐视点上海AR开发制作公司作为业界的佼佼者&#xff0c;凭借其卓越的公司规模、丰富的行业案例以及顶尖的ar增强现…

华为的热机备份和流量限制

要求&#xff1a; 12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW4&#xff0c;生产区和办公区的流量走FW5 13&#xff0c;办公区上网用户限制流量不超过100M&#xff0c;…

好玩的调度技术-场景编辑器

好玩的调度技术-场景编辑器 文章目录 好玩的调度技术-场景编辑器前言一、演示一、代码总结好玩系列 前言 这两天写前端写上瘾了&#xff0c;顺手做了个好玩的东西&#xff0c;好玩系列也好久没更新&#xff0c;正好作为素材写一篇文章&#xff0c;我真的觉得蛮好玩的&#xff…

vscode+SSH连接Ubuntu

目录 问题引入 基本思路 Permission denied, please try again 修改用户名与密码 新建用户 最终成功方案 问题引入 ssh 用户名ip地址。用户名是远端服务器的用户名&#xff0c;ip地址也是远端服务器的地址。linux虚拟机的ip地址与windous主体不一样&#xff0c;所以还需要…

Python、Rust与AI的未来展望

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

基于modbus tcp通讯的雷赛导轨控制器调试软件

0.前言 之前工作遇到了雷赛电机驱动器设备&#xff0c;主要是用来控制光学导轨移动。雷赛的调试软件用的时串口通讯&#xff0c;还要他们定制的串口线&#xff0c;在现场都是485转网络的接口&#xff0c;调试起来也很不方便。所以我就照着他们的说明书&#xff0c;写了一个简易…

Git 用法

基本介绍 版本控制工具用处&#xff1a; 备份代码还原协同开发追溯 版本控制工具 1、集中式版本控制工具 版本库是集中存放在中央服务器的&#xff0c;team 里每个人 work 时从中央服务器下载代码&#xff0c;是必须联网才能工作&#xff0c;局域网或互联网。个人修改后然后…

推荐一款处理TCP数据的架构--EasyTcp4Net

EasyTcp4Net是一个基于c# Pipe,ReadonlySequence的高性能Tcp通信库,旨在提供稳定,高效,可靠的tcp通讯服务。 基础的消息通讯 重试机制 超时机制 SSL加密通信支持 KeepAlive 流量背压控制 粘包和断包处理 (支持固定头处理,固定长度处理,固定字符处理) 日志支持Pipe &…

[RK3588-Android12] 关于如何取消usb-typec的pd充电功能

问题描述 RK3588取消usb-typec的pd充电功能 解决方案&#xff1a; 在dts中fusb302节点下usb_con: connector子节点下添加如下熟悉&#xff1a; 打上如下2个补丁 diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index c8a4e57c9f9b..173f8cb7…

小程序-视图与逻辑

一、页面导航 声明式导航 编程式导航 导航传参 1.声明式导航传参 2.编程式导航传参 3.在onload中接收导航参数 二、页面事件 下拉刷新 上拉触底 三、生命周期 分类 生命周期函数分类 1.应用的生命周期函数 2.页面的生命周期函数 四、WXS脚本 基础语法 wxs的特点 五、案…

OAI 5G-NR源码架构

OAI 5G-NR源码架构 1 特性范围 目前gNB和5G-NRUE支持如下的配置&#xff1a; 工作模式&#xff1a;TDDCP长度&#xff1a;Normal CP子载波间隔&#xff1a; 30kHz信道带宽&#xff1a;40MHz(106PRB)、80MHz(217PRB)、100MHz(237PRB)天线端口&#xff1a;单波束时隙格式&…

LG 选择 Flutter 来增强其智能电视操作系统 webOS

可以这个话题会让大多数人困惑&#xff0c;2024 年了为什么还会冒出 webOS 这种老古董&#xff1f;然后 LG 为什么选择 webOS &#xff1f;现在为什么又选择 Flutter &#xff1f; 其实早在 Google I/O 发布 Flutter 3.22 版本的时候&#xff0c;就提到了 LG 选择 Flutter 来增…

HTML的简单应用 标记信件

前言&#xff1a; 暑假开始了&#xff0c;我也要正式开始学习web的相关知识了&#xff0c;先从三大件的html开始吧&#xff0c;目前只简单了解了html相关知识的基础&#xff0c;能写一些包含一些文字和图片的简单网页&#xff0c;其实会的东西还是不多&#xff0c;这边看书时发…

关于vue实现导出excel表,以及导出的excel后的图片超过单元格的问题

实现导出带图标片的excel的方法&#xff0c; 首先&#xff1a; import table2excel from js-table2excel // 导出表格 按钮点击后触发事件 const onBatchExport () > {const column [//数据表单{title: "ID", //表头名称titlekey: "id", //数据ty…