前端技术搭建(动态图片)拖拽拼图!!(内含实现原理)

news2024/12/23 17:50:01

文章目录

  • 前端技术搭建(动态图片)拖拽拼图(内含实现原理)
  • 导言
  • 功能介绍
  • 效果演示链接(觉得不错的,请一键三连嘤嘤嘤)
  • 项目目录
    • 页面搭建
    • css样式设置
    • 工具函数
    • 游戏实现逻辑
  • 开源地址
  • 总结

前端技术搭建(动态图片)拖拽拼图(内含实现原理)

拼图封面.png

导言

两年半前,老师要求我们实现一个拼图拖拽游戏。
基于此,我重构了当年的代码,实现了更加丰富的游戏

功能介绍

动态拖拽拼图,是将以往的二维移动方块的方式,变成了三维移动方式,目标是将一张图片切割打乱,然后,重组为原图的游戏。

功能介绍

  • 等待用户输入玩家名,选择游戏难度
  • 期待用户上传自定义图片(支持gif,jpg,png等)
  • 开始游戏
  • 切割打乱图片
  • 用户拖拽拼图快完成图片
  • 烟花效果
  • 排行榜

image.png

image.png

image.png

效果演示链接(觉得不错的,请一键三连嘤嘤嘤)

通过gif动态图,我开发了一个动态图拖拽拼图网页游戏_哔哩哔哩_bilibili

项目目录

  • puzzle
    • css
      • index.css
    • pic
    • utils
      • confetti.js
      • index.js
    • index.html
    • index.js

页面搭建

首先实现游戏界面搭建,引入相关文件。

我将游戏分为三个部分

  • 游戏准备页面 (id=“start”)
  • 游戏界面 (id=“game_container”),游戏界面也分为三个部分
    1. 左边打乱拼图区域 id=“puzzle”
    2. 中间游戏目标完整图片id=“puzzle_map”
    3. 右边游戏目标id=“puzzle_destionation”
  • 游戏结束页面 (id=“end”)

index.html
界面布局
详情请看代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽拼图</title>
    <script src="./utils/confetti.js"></script>
    <link rel="stylesheet" href="css/index.css">
</head>

<body>
    <div id="start" class="">
        <div class="box">
            <h1>欢迎玩家</h1>
            <p>请创建的你的游戏信息</p>
            <div class="form">
                <!-- 标题 -->
                <div class="group">
                    <label for="nickname">玩家昵称</label>
                    <input type="text" value="red润" id="nickname" name="nickname">
                </div>
                <!-- 难度 -->
                <div class="group">
                    <label for="difficult">
                        难度
                    </label>
                    <select name="difficult" id="difficult">
                        <option value="">请选择难度</option>
                        <option value="3">简单</option>
                        <option value="5">一般</option>
                        <option value="7">困难</option>
                        <option value="9">地狱</option>
                        <option value="11">天堂</option>
                        <option value="15">不要尝试的难度</option>
                    </select>
                </div>
                <!-- 放入图片 -->
                <div class="group" id="drop">
                    <div class="preview">
                        <img src="./pic/upload.png" alt="放入拼图">
                        <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg ,image/png">
                    </div>
                    <p>点击加号(选择你要放入的图片)</p>
                </div>
                <div class="group">
                    <button name="submit">
                        开始(请先上传图片)
                    </button>
                </div>
            </div>
        </div>
    </div>

    <div id="game_container" class="hidden">
        <span>用户名</span>
        <div id="timer">
            <span>00:00</span>
        </div>
        <div id="puzzle_container">
            <div id="puzzle"></div>
            <div id="puzzle_map"></div>
            <div id="puzzle_destionation"></div>
        </div>
        <div class="buttons">
            <button class="stop">暂停</button>
            <button class="restart">重新开始</button>
        </div>
    </div>
    <div id="end" class="hidden">
        <div class="box" style="overflow: scroll;">
            <h3>拼图完成</h3>
            <p>游戏胜利!</p>
            <table>
                <thead>
                    <tr>
                        <th>排名</th>
                        <th>难度</th>
                        <th>用户名</th>
                        <th>游戏时间</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>1</td>
                        <td>不要尝试的难度</td>
                        <td>red润</td>
                        <td>11:11::23</td>
                    </tr>
                </tbody>
            </table>
            <button onclick="document.querySelector('#end').classList.add('hidden'),document.querySelector('#start').classList.remove('hidden')">再来亿遍</button>
        </div>
    </div>
    <script type="module">
        import Main from "./index.js"
        new Main()
    </script>
</body>

</html>

css样式设置

index.css 布局样式 详细请看代码

* {
    margin: 0;
    padding: 0;
    /* 比如输入框选中时候的边框 */
    outline: none;

    font-family: "Arial", sans-serif;
    color: #282828;
    /* 下划线 */
    text-decoration: none;
    /* 列表前面的 点 */
    list-style-type: none;
    box-sizing: border-box;
}

html,
body {
    width: 100%;
    height: 100%;
    background-color: black;
    background: url("../pic/坤坤1.gif");
    background-size: 100% 100%;
}

.hidden {
    display: none !important;
}

/* 公用样式 */
#start {
    width: 100%;
    height: 100%;
    position: fixed;
}

#end {
    width: 100%;
    height: 100%;
    position: fixed;
    mix-blend-mode:luminosity;
}

.box {
    border-radius: 15px;
    padding: 40px;
    margin: 40px 40px;
    width: calc(100% - 80px);
    height: calc(100% - 80px);
    text-align: center;
    background-color: #F2F2F2;
}

/* 游戏开始 */
#start .group {
    margin-top: 20px;
}

#start .group input,
#start .group select {
    width: 99%;
    height: 40px;
    line-height: 40px;
    text-align: center;
}

#start .group label {
    text-transform: uppercase;
    font-size: 15px;
    text-align: left;
}

#start .group button {
    width: 100%;
    height: 60px;
}

/* 选择上传图片功能 */
#start #drop {
    display: flex;
    flex-direction: row;
    width: 100%;
    height: 100px;
    line-height: 100px;
    text-align: center;
    border: dotted 1px rgba(0, 0, 0, 0.2);
}

#start #drop p {
    width: calc(100% - 100px);
}

#start .preview {
    position: relative;
    background-color: red;
    width: 100px;
    height: 100px;
}

#start .preview img {
    position: absolute;
    width: 100px;
    height: 100px;
    left: 0;
}

#start .preview input {
    left: 0;
    top: 0;
    width: 100px;
    height: 100px;
    position: absolute;
    opacity: 0;
}

/* 游戏内容区域 */
#game_container {
    width: 100%;
    height: 100%;
    background-color: #009BBC;
    padding: 70px 50px 50px;
    text-align: center;

}

#game_container>span {
    display: inline-block;
    height: 30px;
    line-height: 30px;
    width: 100%;
    background-color: white;
    ;
}

#game_container #timer span {
    display: inline-block;
    width: 100%;
    height: 30px;
    line-height: 30px;
    background-color: #004D5E;
}

/* 拼图区域 */
#puzzle_container {

    height: 300px;
    width: 100%;
    display: flex;
    flex-direction: row;
}

#puzzle_container #puzzle {
    width: 300px;
    height: 300px;
    border: dotted 1px black;
    position: relative;
}

#puzzle_container #puzzle_map {
    border-radius: 0;
    flex: 1;
    height: 300px;
    border: dotted 1px rgb(0, 0, 0);
}

#puzzle_container #puzzle_destionation {
    width: 300px;
    height: 300px;
    position: relative;
    border: dotted 1px black;
}

#game_container .buttons button {
    width: 100%;
    height: 30px;
}

/* 游戏结束 */
#end {
    width: 100%;
    height: 100%;
}

#end h3 {
    text-align: center;
}

#end p {
    text-align: center;
}

#end table {

    width: 100%;
    /* 共享边框 */
    border-collapse: collapse;
}

#end table th,
td {
    padding: 10px;
    border: solid 1px rgb(0, 0, 0, 0.2);
}

#end button {
    width: 100%;
    text-align: center;
    height: 50px;
}

工具函数

utils/index.js 工具函数 封装复用函数

export default class Utils {
    /**
     * 通过传入的文件,拿到文件数据流
     * @param {object} file 传入的文件
     * @returns {string} url 返回图片url
     */
    static getUrlByFile(file) {
        let url = null;
        // 下面函数执行的效果是一样的,只是需要针对不同的浏览器执行不同的 js 函数而已
        if (window.createObjectURL != undefined) { // basic
            url = window.createObjectURL(file);
        } else if (window.URL != undefined) { // mozilla(firefox)
            url = window.URL.createObjectURL(file);
        } else if (window.webkitURL != undefined) { // webkit or chrome
            url = window.webkitURL.createObjectURL(file);
        }
        return url;
    }
    /**
     * 将秒转换为 天时分秒
     * @param {*} value 毫秒
     * @returns {string} str 格式化后的字符串
     */
    static formatSeconds(value) {
        let s = value//秒
        let m = 0;//分
        let h = 0;//小时
        let d = 0;//天
        if (s > 60) {
            m = parseInt(s / 60)
            s = parseInt(s % 60)
            if (m > 60) {
                h = parseInt(m / 60)
                m = parseInt(m % 60)
                if (h > 24) {
                    d = parseInt(h / 24)
                    h = parseInt(h % 24)
                }
            }
        }
        let result = ''
        if (s > 0) {
            if (s < 10) {
                result = "0" + s + "秒"
            } else {
                result = s + "秒"
            }
        }
        if (m > 0) {
            if (m < 10) {
                result = "0" + m + "分" + ":" + result
            } else {
                result = m + "分" + ":" + result
            }
        }
        if (h > 0) {
            if (h < 10) {
                result = "0" + h + "时" + ":" + result
            } else {
                result = h + "时" + ":" + result
            }
        }
        if (d > 0) {
            if (d < 10) {
                result = "0" + d + "天" + ":" + result
            } else {
                result = d + "天" + ":" + result
            }
        }
        return result
    }

    /**
     * 只显示一个用户场景
     * @param {*} name 
     */
    static showOne(that,name){
        // this.startEle.classList.remove("hidden")
        // this.gameContainerEle.classList.add("hidden")
        // this.endEle.classList.add("hidden")
        that[name].classList.remove('hidden')
        let names = ["startEle","gameContainerEle",'endEle']
        names.filter(item=>item!==name).forEach(item=>{
            that[item].classList.add('hidden')
        })
    }

    /**
     * 根据传入的数值,返回一个和数值长度大小相等的数组
     * @param {*} num 
     * @returns {arr[]}
     */
    static rM(num){
        let randomArr = []
        // 保存有序数组
        for(let a=0;a<num;a++){
            randomArr.push(a)
        }
        // 打乱有序数组
        randomArr.sort((a,b)=>Math.random()-0.5)
        return randomArr
    }
}



游戏实现逻辑

index.js 游戏实现完整逻辑 详情请看代码

import Utils from './utils/index.js';
export default class Main {

    constructor() {
        // 记录游戏时间
        this.time = 0;
        // 定时器对象
        this.timer = null;
        // 游戏是否暂停
        this.stop = false;
        // 游戏难度等级
        this.level = 3
        // 玩家昵称
        this.nickname = null

        // 拖拽拼图的宽高
        this.width = 300;
        this.height = 300;

        // 用户上传的图片文件
        this.file = null
        // 用户上传图片后转换为数据流 作为url路径
        this.url = null

        // start容器元素
        this.startEle = document.querySelector("#start");
        // game_container容器元素
        this.gameContainerEle = document.querySelector("#game_container")
        // end容器元素
        this.endEle = document.querySelector("#end")

        // start元素下面的img
        this.startImg = document.querySelector("#start img")
        // start元素下面的用户名
        this.startNickName = document.querySelector("#start #nickname")
        // start元素下面的等级
        this.startLevel = document.querySelector("#start #difficult")
        // start元素下面的开始按钮
        this.startBtn = document.querySelector("#start button")
        // start元素input上传文件元素
        this.startPic = document.querySelector("#start #pic")

        // game_container下面的timer
        this.gameTimer = document.querySelector("#game_container #timer")
        // 暂停按钮
        this.gameStopBtn = document.querySelector("#game_container .stop")
        // 重新开始按钮
        this.gameRestartBtn = document.querySelector("#game_container .restart")

        // 左边拼图块
        this.puzzle = document.querySelector('#puzzle')
        // 中间拼图块
        this.puzzleMap = document.querySelector('#puzzle_map')
        // 右边拼图块
        this.puzzleDestionation = document.querySelector("#puzzle_destionation")

        this.init()
    }
    init() {
        // 烟花
        this.jsConfetti = new JSConfetti()
        const addFire = (i = 1) => {
            for (i; i > 0; i--) {
                setTimeout(() => {
                    this.jsConfetti.addConfetti()

                    
                }, i * 500)
            }
        }
        addFire(11)

        console.log("游戏初始化");
        // 初始化排行榜
        this.initRank()
        // 显示开始界面,隐藏其他界面
        Utils.showOne(this, "endEle")

        // 禁用开始按钮
        this.startBtn.disabled = true
        this.startBtn.style.cursor = "not-allowed";
        // 监听图片上传
        this.addEventListenerStartPicChange()
        // 监听开始游戏按钮
        this.addEventListenerStartBtn()
        // 监听是否点击游戏暂停按钮
        this.addEventListenerIsStop()
        // 监听是否重新游戏
        this.gameRestartBtn.addEventListener("click", () => {
            this.restartGame()
        })

    }
    initRank() {
        let tbody = document.querySelector("table>tbody")
        let rankArr = JSON.parse(localStorage.getItem("ranking"))
        let objs = []
        objs.push(`<tr>
            <td>1</td>
            <td>不要尝试的难度</td>
            <td>red润</td>
            <td>4天:3时:5分:18秒</td>
        </tr>
        `)
        for (const key in rankArr) {
            let obj = rankArr[key]
            parseInt(obj.level)
            if (obj.level == 3) {
                obj.level = "简单"
            } else if (obj.level == 5) {
                obj.level = "一般"
            } else if (obj.dif == 7) {
                obj.level = "困难"
            } else if (obj.level == 9) {
                obj.level = "地狱"
            } else if (obj.level == 11) {
                obj.level = "天堂"
            } else if (obj.level == 15) {
                obj.level = "不要尝试的难度"
            }
            let node = `<tr>
              <td>${parseInt(key) + 2}</td>
              <td>${obj.level}</td>
              <td>${obj.name}</td>
              <td>${obj.time}</td>
            </tr>`
            objs.push(node)
        }
        tbody.innerHTML = objs

    }
    // 监听用户是否点击上传图片,将上传的图片存储下来
    addEventListenerStartPicChange() {
        // 注意this的指向
        this.startPic.addEventListener("change", (e) => {
            // 存储用户上传的图片
            this.file = e.target.files[0];
            // 转换
            this.url = Utils.getUrlByFile(this.file);

            if (this.url !== null) {
                this.startBtn.disabled = false
                this.startBtn.style.cursor = "pointer";
                this.startImg.src = this.url

                this.initGameContainer()
            }

        })
    }
    // 监听开始游戏按钮
    addEventListenerStartBtn() {
        this.startBtn.addEventListener('click', () => {
            this.initGameContainer()
        })
    }
    // 监听 暂停按钮 点击
    addEventListenerIsStop() {
        this.gameStopBtn.addEventListener("click", () => {
            this.stop = !this.stop
            if (this.stop === false) {
                this.startCountTime()
                this.gameStopBtn.innerHTML = "暂停游戏"
            } else {
                this.stopCountTime()
                this.gameStopBtn.innerHTML = "继续游戏"
            }

        })
    }
    // 开始定时
    startCountTime() {
        if (this.timer) clearInterval(this.timer)
        this.timer = setInterval(() => {
            this.time++
            this.gameTimer.innerHTML = Utils.formatSeconds(this.time)
        }, 1000)
    }
    // 暂停
    stopCountTime() {
        if (this.timer) clearInterval(this.timer)
    }
    // 重新游戏
    restartGame() {
        window.location.reload()
    }

    // 初始化游戏地图
    initGameContainer() {
        if (!this.startNickName.value || !this.startLevel.value) {
            alert("用户名或者游戏难度不能为空");
            return;

        }
        // 存储用户选择的难度等级
        this.level = this.startLevel.value
        // 存储玩家名字
        this.nickname = this.startNickName.value

        // 显示游戏地图,隐藏其他地图
        Utils.showOne(this, "gameContainerEle")
        // 初始化拼图
        this.initPuzzle()
        // 开始计时
        this.startCountTime()


    }
    // 初始化拼图
    initPuzzle() {
        // 左边
        this.puzzle.style.background = `url(${this.url})`
        this.puzzle.style.backgroundSize = "100% 100%";
        // 中间
        this.puzzleMap.style.background = `url(${this.url})`
        this.puzzleMap.style.backgroundSize = "100% 100%";

        // 右边
        this.puzzleDestionation.style.background = `url(${this.url})`
        this.puzzleDestionation.style.backgroundSize = "100% 100%";

        // 创建左边拖拽
        this.createPuzzle(this.puzzle)
        // 创建右边接收区
        this.createPuzzle(this.puzzleDestionation)

    }
    // 根据传入的puzzle,创建拖拽元素
    createPuzzle(ele) {
        // 存储打乱后的div
        let arr = [];
        // 给每个div设置一个唯一id
        let id_num = 0;
        // 每行/每列 puzzle块的数量 300/3 = 10
        let ppx = `${Math.floor(this.width / this.level)}`;
        // 根据用户选择的难度,产生对应的随机数组 3*3
        let randomNum = Utils.rM(this.level);
        for (let i = 0; i < this.level; i++) {
            for (let j = 0; j < this.level; j++) {
                let div = document.createElement("div");
                div.style.backgroundRepeat = "no-repeat";
                div.style.zIndex = '100'
                div.style.width = ppx + 'px'
                div.style.height = ppx + 'px'
                div.style.position = 'absolute'


                if (ele.id === 'puzzle') {
                    div.style.border = `${1}px solid yellow`
                    // 打乱拼图位置
                    div.style.top = `${randomNum[j] * ppx}px`
                    div.style.left = `${randomNum[i] * ppx}px`
                    div.style.background = `url(${this.url})`
                    div.style.boxSizing = 'border-box'
                    div.style.backgroundSize = "300px 300px"
                    div.draggable = true
                    // 虽然位置是乱的,但是id是正常的
                    div.id = id_num
                    // 水平/垂直
                    div.style.backgroundPosition = `-${(j * ppx)}px -${(i * ppx)}px`
                    arr.push(div)
                } else {
                    div.style.border = `${1}px solid pink`
                    //不能打乱图片顺序
                    div.style.top = (i * ppx) + 'px'
                    div.style.left = (j * ppx) + 'px'
                    div.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'
                    div.className = id_num
                    div.id = id_num + "1"
                    arr.push(div)
                }
                id_num++;
            }
        }
        // 设置拖拽事件和放置事件
        this.setPuzzleEvent(ele, arr)


    }
    setPuzzleEvent(ele, arr) {
        // 左边拼图拖拽的时候,设置id
        if (ele.id === 'puzzle') {
            for (let i = 0; i < arr.length; i++) {
                ele.appendChild(arr[i])
                arr[i].ondragstart = (e) => {
                    e.dataTransfer.setData("Id", e.target.id)
                }
            }
        } else {
            for (let i = 0; i < arr.length; i++) {
                ele.appendChild(arr[i])
                arr[i].ondragover = (e) => {
                    e.preventDefault()
                }
                let that = this
                arr[i].ondrop = function (e) {
                    let leftId = e.dataTransfer.getData("Id");

                    let leftDiv = document.getElementById(leftId);
                    leftDiv.style.top = 0;
                    leftDiv.style.left = 0;
                    // 将拖拽方块,从左边放到右边
                    this.appendChild(leftDiv);

                    // 右边的所有元素节点
                    let allNodes = this.parentNode.childNodes;
                    that.isWin(allNodes)

                }
            }
        }
    }
    // 是否胜利
    isWin(allNodes) {
        // 判断游戏是否胜利
        let allChild = []

        // 存储右边元素的儿子节点的id
        allNodes.forEach(element => {
            let child = element.childNodes[0]
            if (child) {
                allChild.push(child.id)
            }
        });
        // 长度要相等,然后,判断是否完全重合
        if (allNodes.length === allChild.length) {
            for (let i = 0; i < allChild.length; i++) {
                if (i == allChild[i]) {
                    alert("游戏胜利")
                    this.joinRank()
                    return
                }
            }
        } else {
            console.log("加油马上就成功了");
        }
    }
    // 加入排行榜
    joinRank() {
        let rankArr = []
        if (localStorage.getItem("ranking")) {
            rankArr = JSON.parse(localStorage.getItem("ranking"))
        }
        let obj = {
            name: this.nickname,
            level: this.level,
            time: Utils.formatSeconds(this.time)
        }
        rankArr.unshift(obj)
        localStorage.setItem("ranking", JSON.stringify(rankArr))
        this.stopCountTime();
        this.time = 0;
        
        this.restartGame()
    }

}


开源地址

  • 开源地址:zou-hong-run/puzzle: 拖拽拼图 (github.com)
  • 项目在线体验地址(电脑体验,手机尚未适配):https://zou-hong-run.github.io/puzzle/new_version

总结

  • 通过本次编写代码体验,加强了拖拽api的理解,面向对象的理解
  • 还有很多不足,请大家指教
  • 大佬们觉得不错的话,请一键三连呀

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

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

相关文章

热门洗地机评测|追觅VS希亦VS米博洗地机,哪款更值得入手?

智能科技的发展越来越方便人们的生活&#xff0c;特别是现今人们生活水平不断提高&#xff0c;房子越住越大&#xff0c;需要顾及的房屋卫生打扫面积也越来越广。而单是通过人工去拖扫不仅很累还很浪费时间。于是洗地机的出现让很多深陷家务劳动的朋友得以解脱。因为很多洗地机…

人工智能-Dlib+Python实现人脸识别(人脸检测以及68点特征提取)

Dlib是一个现代的C ++工具包,包含机器学习算法和工具,用于在C ++中创建复杂的软件来解决实际问题。它广泛应用于工业界和学术界,包括机器人,嵌入式设备,移动电话和大型高性能计算环境。Dlib的开源许可 允许您在任何应用程序中免费使用它 Dlib可以使用pip install来安装或…

基于开源IM即时通讯框架MobileIMSDK:RainbowChat v9.0版已发布

关于MobileIMSDK MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架&#xff0c;超轻量级、高度提炼&#xff0c;一套API优雅支持UDP 、TCP 、WebSocket 三种协议&#xff0c;支持iOS、Android、H5、标准Java平台&#xff0c;服务端基于Netty编写。 工程开源地址是&am…

OpenMLDB荣登ACM旗舰期刊

日前&#xff0c;最新一期的ACM&#xff08;国际计算机学会&#xff09;旗舰期刊《Communications of the ACM》(ACM 通讯) 刊登了开源机器学习数据库项目 OpenMLDB 的文章&#xff0c;获得了期刊编辑主席团的一致认可。 文章链接&#xff1a;https://cacm.acm.org/magazines/2…

opencv对相机进行畸变矫正,及矫正前后的坐标对应

文章目录 1.背景2.需求分析3.解决方案3.1.镜头畸变矫正3.2.知道矫正后的画面坐标&#xff08;x&#xff0c;y&#xff09;&#xff0c;求其在原画面的坐标&#xff08;x&#xff0c;y&#xff09;3.2.知道原画面坐标&#xff08;x1&#xff0c;y1&#xff09;&#xff0c;求其在…

【Linux】网络基础之TCP协议

目录 &#x1f308;前言&#x1f338;1、基本概念&#x1f33a;2、TCP协议报文结构&#x1f368;2.1、源端口号和目的端口号&#x1f369;2.2、4位首部长度&#x1f36a;2.3、32位序号和确认序号&#xff08;重点&#xff09;&#x1f36b;2.4、16位窗口大小&#x1f36c;2.5、…

解决rosdep网络问题

众所周知&#xff0c;想要使用rosdep&#xff0c;需要两个步骤&#xff1a; sudo rosdep init rosdep update其中&#xff0c;第一步就是下载了一个文件&#xff0c;第二步是从服务器下载一些数据。 但是因为国内的网络的原因&#xff0c;这两步都有一点困难。但是可以使用tun…

P3611 [USACO17JAN] Cow Dance Show S

思路&#xff1a;二分K&#xff0c;查看当前K能否满足总时间不超过最大时间 ACcode: #include<bits/stdc.h> using namespace std; #define int long long const int N1e410; int n,tmax,a[N]; bool check(int x) {priority_queue < int, vector < int >, gre…

ASCII码、UniCode码、字符转换、中文、英文、二进制、十进制、十六进制

文章目录 效果图htmlJavaScript 效果图 html <div class"w_680 p_t_20 p_b_20 p_l_6 p_r_6"><div class"w_100_ d_f jc_c"><textarea class"w_97_ h_86 fs_16 resize_none outline_none" oninput"oninputF(event)">…

OpenAI重磅官宣ChatGPT安卓版本周发布,现已开启下载预约,附详细预约教程

7月22号&#xff0c;OpenAI 突然宣布&#xff0c;安卓版 ChatGPT 将在下周发布&#xff01;换句话说&#xff0c;本周安卓版 ChatGPT正式上线&#xff01; 最早&#xff0c;ChatGPT仅有网页版。 今年5月&#xff0c;iOS版ChatGPT正式发布&#xff0c;当时OpenAI表示Android版将…

中缀表达式转后缀表达式,使用逆波兰计算。可以计算小数

1、使用方法 传递一个分开保存符号与数字的List即可&#xff1a;List SumNumber; 获取参数的构造方法如下&#xff1a; public ReversePolish(List<String> sumNumber) {SumNumber sumNumber;}要求的List保存数据的方式如下&#xff1a; 例如&#xff1a;123 然后使用…

【C++】详解多态的底层原理

文章目录 前言1. 虚函数表指针与虚函数表2. 子类的虚函数表&#xff08;单继承&#xff09;3. 多态的实现原理3.1 多态是如何实现的3.2 多态调用与非多态调用的区别3.3 为什么父类的对象不能实现多态 4. 其它多态相关问题的理解4.1 虚函数是存在哪里的&#xff1f;4.2 子类新增…

手机照片误删除?无需担忧,点击这里,即可轻松恢复

手机照片误删除&#xff1f;无需担忧&#xff0c;点击这里&#xff0c;即可轻松恢复 开头&#xff1a;在数字化时代&#xff0c;手机已成为我们生活中不可或缺的伙伴。随着手机摄影的普及&#xff0c;我们记录了许多珍贵的瞬间和回忆。然而&#xff0c;有时候我们不小心误删除…

项目经理必备的5种管理能力

作为中层管理者&#xff0c;需要同时完成上级的任务安排和照顾下属的情绪&#xff0c;这是职场中最具挑战性的管理能力。项目经理必备能力中&#xff0c;计划制定、有效授权、高效沟通、化解冲突、项目跟踪是至关重要的。 1、计划制定是项目管理的关键。 作为项目经理&#…

Tribon二次开发- tbbatchjob

在Tribon安装目录下C:\Tribon\M3\Bin里面有许多未知用途的exe,有的双击后时一个DOS终端,有的一闪而过,有的需要按照提示输入信息,有的需要提前在指定的目录配置文件,该如何使用呢? 这些exe大多可以在Tribon以外通过.NET来使用,有的可以通过添加.NET项目引用来使用,有的…

聊聊spring中bean的作用域

前言 今天分享一下spring bean的作用域&#xff0c;理解bean的作用域能够在使用过程中避免一些问题&#xff0c;bean的作用域也是spring bean创建过程中一个重要的点。 Spring bean的作用域类型 singleton&#xff08;单例模式&#xff09;&#xff1a;在整个应用程序的生命周…

成都爱尔蔡裕:泡在“糖”里的脆弱血管,暴露在眼睛深处

糖尿病是一组由多病因引起的以慢性高血糖为特征的终身性代谢性疾病。长期血糖增高&#xff0c;大血管、微血管受损并危及心、脑、肾、周围神经、眼睛、足等。医生临床数据显示&#xff0c;糖尿病发病后10年左右&#xff0c;将有30%&#xff5e;40%的患者至少会发生一种并发症&a…

【TypeScript】对函数类型的约束定义

导读 函数是JavaScript 中的 一等公民 概念&#xff1a;函数类型的概念是指给函数添加类型注解&#xff0c;本质上就是给函数的参数和返回值添加类型约束 文章目录 声明式函数:表达式函数&#xff1a;箭头函数可选参数和默认参数&#xff1a;参数默认值&#xff1a;过剩参数的处…

脚本 打开 cmd 跳转到某个文件夹并执行某些命令

很多时候我们需要启动windows安装的redis、nacos等。 通常我们可以打开安装软件的目录&#xff0c;在文件夹目录那一栏输入cmd,再执行相关启动命令但是这样比较麻烦&#xff0c;现在我们写一个bat脚本&#xff0c;直接启动脚本就可以实现启动程序了。 例如&#xff0c; 1&…

docker入门讲解

目录 第 1 章 Docker核心概念与安装 为什么使用容器&#xff1f; Docker是什么 Docker设计目标 Docker基本组成 容器 vs 虚拟机 Docker应用场景 Linux 安装 Docker 第 2 章 Docker镜像管理 Docker 容器管理 Docker 容器数据持久化 Docker 容器网络 Dockerfile 定制…