<!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引用傳遞