zoukankan      html  css  js  c++  java
  • 蚂蚁爬杆问题js实现

    运行效果

    代码

    <!DOCTYPE html>
    <html>
    <head>
        <title>蚂蚁爬杆实验</title>
        <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    </head>
    <body>
        <div style="margin: auto">
            <h1 align="center" style="margin-bottom: 50px">蚂蚁爬杆实验</h1>
            <div class="card">
                <h3>说明</h3>
                <ul>
                    <li>蚂蚁从杆子左边爬到右边需要两分钟</li>
                    <li>现在一共有20只蚂蚁</li>
                    <li>每只蚂蚁出现位置随机</li>
                    <li>每只蚂蚁初始移动方向随机</li>
                    <li>两只蚂蚁相遇则折返</li>
                    <li>问多长时间后杆子上没有蚂蚁</li>
                </ul>
            </div>
    
            <div class="card">
                <h3>参照杆</h3>
                <div class="box" id='box_reference'></div>
            </div>
            <div class="card">
                <h3>实验杆</h3>
                <div class="box" id='box'></div>
            </div>
            <div class="card">
                <h3>控制台</h3>
                <div>
                    <div class="card-console">
                        <label>蚂蚁数量:<input type="text" id='ant_num' value="20"></label>
                        <label>移动步长(px):<input type="text" id='speed' value="1"></label>
                        <label>移动时间间隔(ms):<input type="text" id='time_interval' value="20"></label>
                    </div>
                    <div class="card-console">
                        <button class="btn-console" id='start'>暂停</button>
                        <button class="btn-console" id='restart'>重新开始</button>
                    </div>
                </div>
            </div>
        </div>
    <script type="text/javascript">
    window.TIMER = 'no_timer'//-1代表没有定时器
    window.SPEED = 3
    window.COLORS = ['yellow', 'white', 'cyan', 'Red', '#FF00FF', '#00FF00', '#FFA500']
    function compare(o1, o2){//特定的比较器,比较style中的left
        return o1.position().left - o2.position().left
    }
    
    $(document).ready(function(){
    
        let base_left = $('#box').position().left
        let div_len = parseInt($('#box').css('width'))
        let dom_str = '<span class="ant" id="ant_{id}" style="left:{left}px; background-color: {color};">{v}</span>'
    
        $('#start').click(function(){//启动暂停按钮何二为一了
            if($(this).text()=='继续'){//继续程序
                create_timer()
                $(this).text('暂停')
                return
            }
            delete_timer()
            $(this).text('继续')
        })
    
        $('#restart').click(function(){//启动定时器
            $('#start').text('暂停')
            init()
            delete_timer()
            create_timer()
        })
    
        function create_timer(){
            if(TIMER != 'no_timer')
                return
            TIMER = window.setInterval(ants_move, TIME_INTERVAL)//生成定时器
        }
    
        function delete_timer(){
            if(TIMER == 'no_timer')
                return
            window.clearInterval(TIMER)//清除定时器
            window.TIMER = 'no_timer'        
        }
    
        function init(){
            let ant_num = parseInt($('#ant_num').val())
            let speed = parseInt($('#speed').val())
            window.SPEED = speed//因为碰撞检测有用到速度,为了方便就挂在window下了
            window.TIME_INTERVAL = parseInt($('#time_interval').val())
            create_ants(ant_num, speed)
        }
        init()
        create_timer()
    
        $(window).resize(function(){//窗口变化检测,因为水平居中,div相对像素点会变
            base_left = $('#box').position().left
        })
    
        function create_ant(id, left, v, color){//生成单只蚂蚁
            let temp_dom = dom_str.replace('{id}', id).replace('{left}', left).replace('{v}', v).replace('{color}', color)
            return temp_dom
        }
    
        function create_ants(n, speed){//生成蚂蚁
            let box_html = ''
            for(let i=0; i<n; i++){
                let temp_left = base_left + Math.random()*div_len//随机位置
                let v = speed
                if(Math.random()>0.5)//随机方向
                    v = -v
                let color = COLORS[Math.floor(COLORS.length * Math.random())]
                box_html += create_ant(i, temp_left, v, color)
            }
            $('#box').html(box_html)//生成实验杆蚂蚁
            $('#box_reference').html(create_ant(999, base_left+0, speed, 'yellow'))//生成对照杆蚂蚁
        }
    
        function single_move(dom){//单个蚂蚁移动
            let v = parseInt(dom.text())
            let left = dom.position().left
            dom.css('left', left + v)
        }
    
        function ants_move(){//所有蚂蚁移动
            let ants = []
            $('#box>.ant').each(function(){//实验杆移动
                let dom = $(this)
                single_move(dom)
                destroy_dom(dom)
                ants.push(dom)
            })
            reference_ant = $('#box_reference>.ant:first')
            if(reference_ant.length > 0 ){//如果元素存在
                single_move(reference_ant)//对照杆蚂蚁移动
                destroy_dom(reference_ant)//爬出杆子清除
            }
            ants = ants.sort(compare)
            scan_array(ants)
        }
    
        function destroy_dom(dom){//删除不在杆上的蚂蚁
            let r = parseInt(dom.width())/2
            let left = dom.position().left
            if(left<base_left-r || left>base_left+div_len-r)
                dom.remove()
        }
    
        function scan_array(ants){//扫描数组
            for(let i=0; i<ants.length-1; i++){
                bump(ants[i], ants[i+1])
            }
        }
    
        function bump(ant1, ant2){//碰撞
            let left1 = parseInt(ant1.position().left)
            let left2 = parseInt(ant2.position().left)
            if(Math.abs(left1-left2) > SPEED)//如果两球相距大于速度,不会相撞
                return false
    
            let v1 = parseInt(ant1.text())
            let v2 = parseInt(ant2.text())
            if((v1 * v2) > 0)//如果移动方向一样,不会相撞
                return false
    
            if(((left1 - left2)/(v1 - v2)) > 0)//速度相向但位置相背
                return false
    
            ant1.text(-v1)
            ant2.text(-v2)
            // alert(1)
            return true
        }
    })
    </script>
    <style type="text/css">
        body{
            display: flex;
            align-items: center;
        }
        .box{
            height: 20px;
            width: 1000px;
            background-color: black;
        }
        .ant{
            position: absolute;
            height: 20px;
            width: 20px;
            border-radius: 10px;
            font-size: 10px;
            text-align: center;
        }
        .card{
            background: #8be88038;
            padding: 10px;
            margin: 10px;
            border-radius: 10px;
            box-shadow: 0px 0px 2px #000;
        }
        .card-console{
            margin: 10px
        }
        .btn-console{
            width: 100px;
            height: 30px;
            border: 0px;
            background: black;
            border-radius: 5px;
            color: white;
            font-weight: bold;
            cursor: pointer;    
        }
    </style>
    </body>
    </html>
    View Code

    关键点

    1. 生成随机圆球(蚂蚁)
    2. js操作dom移动
    3. js根据某一数据排序(因为相撞只可能发生在相邻两个球中,排序减少计算量)
    4. 删除超出边界的dom节点
    5. js引用传递
  • 相关阅读:
    距离计算
    推荐系统
    jvm内存配置参数
    Vim 文件配置
    [转]linux shell 多线程实现
    synchronized 和 ReentrantLock 区别
    sptring boot 修改默认Banner
    Java容器类总结
    JAVA基本类型和包装类
    Linux 虚拟内存机制
  • 原文地址:https://www.cnblogs.com/lurenjia1994/p/10660625.html
Copyright © 2011-2022 走看看