原生JS實現多個小球碰撞反彈效果樣本,js樣本
本文執行個體講述了原生JS實現多個小球碰撞反彈效果。分享給大家供大家參考,具體如下:
實現思路:小球的移動,是通過改變小球的left和top值來改變,座標分別為(x,y)當x/y值加到最大,即加到父級的寬度或者高度時,使x值或者y值減小,同理當x值或者y值減到最小時,同樣的使x值或者y值增加,以上的思路可以實現小球的碰壁反彈
小球與小球之間的碰撞,要判斷小球在被撞小球的哪個方向,從而判斷小球該向哪個方向移動,同樣的改變小球的座標值,來實現小球的反彈
實現代碼:
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <title>小球碰撞</title> <style type="text/css"> * { margin: 0; padding: 0; } #wrap { height: 800px; width: 1300px; border: 1px solid red; /*小球設定相對定位*/ position: relative; margin: 0 auto; overflow: hidden; } p { width: 40px; height: 40px; border-radius: 50%; background-color: red; position: absolute; top: 0; left: 0; color: white; font-size: 25px; text-align: center; line-height: 40px; } </style> </head> <body> <div id="wrap"> </div> </body> <!--<script src="js/common.js" type="text/javascript" charset="utf-8"></script>--> <script type="text/javascript"> /** * 產生並返回一個從m到n全區間的隨機數 * @param {Object} m * @param {Object} n */ function randomNum(m, n) { return Math.floor(Math.random() * (n - m + 1) + m); } /** * 產生一個隨機顏色,並返回rgb字串值 */ function randomColor() { var r = randomNum(0, 255); var g = randomNum(0, 255); var b = randomNum(0, 255); return "rgb(" + r + "," + g + "," + b + ")"; } //獲得wrapDiv var wrapDiv = document.getElementById("wrap"); //定義數組儲存所有的小球 var balls = []; //產生小球函數 function createBalls() { for (var i = 0; i < 20; i++) { var ball = document.createElement("p"); //隨機小球起始的X座標和小球的Y座標 ball.x = randomNum(0, 1200); ball.y = randomNum(0, 700); //隨機小球的移動速度 ball.speed = randomNum(2, 5); //隨機小球移動的方向 if (Math.random() - 0.5 > 0) { ball.xflag = true; } else { ball.xflag = false; } if (Math.random() - 0.5 > 0) { ball.yflag = true; } else { ball.yflag = false; } //隨機小球的背景顏色 ball.style.backgroundColor = randomColor(); ball.innerHTML = i + 1; //將小球插入當wrapDiv中 wrapDiv.appendChild(ball); //將所有的小球儲存到數組中 balls.push(ball); } } createBalls(); //小球移動函數,判斷小球的位置 function moveBalls(ballObj) { setInterval(function() { ballObj.style.top = ballObj.y + "px"; ballObj.style.left = ballObj.x + "px"; //判斷小球的標誌量,對小球作出相應操作 if (ballObj.yflag) { //小球向下移動 ballObj.y += ballObj.speed; if (ballObj.y >= 800 - ballObj.offsetWidth) { ballObj.y = 800 - ballObj.offsetWidth; ballObj.yflag = false; } } else { //小球向上移動 ballObj.y -= ballObj.speed; if (ballObj.y <= 0) { ballObj.y = 0; ballObj.yflag = true; } } if (ballObj.xflag) { //小球向右移動 ballObj.x += ballObj.speed; if (ballObj.x >= 1300 - ballObj.offsetHeight) { ballObj.x = 1300 - ballObj.offsetHeight; ballObj.xflag = false; } } else { //小球向左移動 ballObj.x -= ballObj.speed; if (ballObj.x <= 0) { ballObj.x = 0; ballObj.xflag = true; } } crash(ballObj); }, 10); } var x1, y1, x2, y2; //碰撞函數 function crash(ballObj) { //通過傳過來的小球對象來擷取小球的X座標和Y座標 x1 = ballObj.x; y1 = ballObj.y; for (var i = 0; i < balls.length; i++) { //確保不和自己對比 if (ballObj != balls[i]) { x2 = balls[i].x; y2 = balls[i].y; //判斷位置的平方和小球的圓心座標的關係 if (Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) + 800 <= Math.pow(ballObj.offsetWidth + balls[i].offsetWidth, 2)) { //判斷傳過來的小球對象,相對於碰撞小球的哪個方位 if (ballObj.x < balls[i].x) { if (ballObj.y < balls[i].y) { //小球對象在被碰小球的左上方 ballObj.yflag = false; ballObj.xflag = false; } else if (ballObj.y > balls[i].y) { //小球對象在被碰小球的左下角 ballObj.xflag = false; ballObj.yflag = true; } else { //小球對象在被撞小球的正左方 ballObj.xflag = false; } } else if (ballObj.x > balls[i].x) { if (ballObj.y < balls[i].y) { //小球對象在被碰撞小球的右上方 ballObj.yflag = false; ballObj.xflag = true; } else if (ballObj.y > balls[i].y) { //小球對象在被碰撞小球的右下方 ballObj.xflag = true; ballObj.yflag = true; } else { //小球對象在被撞小球的正右方 ballObj.xflag = true; } } else if (ballObj.y > balls[i].y) { //小球對象在被撞小球的正下方 ballObj.yflag = true; } else if (ballObj.y < balls[i].y) { //小球對象在被撞小球的正上方 ballObj.yflag = false; } } } } } for (var i = 0; i < balls.length; i++) { //將所有的小球傳到函數中,來實現對小球的移動 moveBalls(balls[i]); } </script></html>
運行效果: