蚂蚁爬杆问题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>
关键点
1. 生成随机圆球(蚂蚁)
2. js操作dom移动
3. js根据某一数据排序(因为相撞只可能发生在相邻两个球中,排序减少计算量)
4. 删除超出边界的dom节点
5. js引用传递
Become a Linux Programmer