马黑PHP整站系统

canvas画布中小球碰撞简单处理

位置: 首页 > 代码集锦[ 发布时间: 2024.4.12  作者: 马黑  阅读: 103 ]

效果:点击方框任意处生成小球,限量10个 ——

代码:

<style> #mama {     margin: 20px auto;     width: 600px;     height: 400px;     border: 1px solid gray;     position: relative; } </style>   <div id="mama"></div>   <script> //创建画布 var canv = document.createElement('canvas'); //画布尺寸及宽高变量与父元素一致 var ww = canv.width = mama.offsetWidth; var hh = canv.height = mama.offsetHeight; //mama添加画布 mama.appendChild(canv); //获得画笔 var ctx = canv.getContext('2d');
/* 小球数组 用于实时记录小球数据 小球个体以对象形式存储圆心坐标、半径、颜色、xy方向移动速度 {x: x, y: y, r: r, color: color, speedX: speedX, speedY: speedY} */
var balls = []; //动画标识,小球总数 var raf = null, total = 10;   //获取运动速度函数 -1 或 1 var speed = () => Math.random() < 0.5 ? -1 : 1;   //绘制小球函数 圆心坐标+半径+填充颜色 var drawBall = (x,y,r,color) => {     ctx.save();     ctx.beginPath();     ctx.fillStyle = color;     ctx.arc(x,y,r,0,2*Math.PI);     ctx.fill();     ctx.restore(); };   //小球运动函数 依据圆心坐标和半径绘制 var move = (ball) => {     var x = ball.x,         y = ball.y,         r = ball.r,         color = ball.color,         spdX = ball.speedX,         spdY = ball.speedY;     x += spdX;     y += spdY;     //边界处理     if(x - r < 0 || x + r > ww) spdX = - spdX;     if(y - r < 0 || y + r > hh) spdY = - spdY;     //记录小球变更数据     ball.x = x;     ball.y = y;     ball.speedX = spdX;     ball.speedY = spdY;     //绘制变更后的小球     drawBall(x,y,r,color); };   //渲染函数 var render = () => {     ctx.clearRect(0,0,ww,hh); //擦除画布     //双for循环检测球与球间是否碰撞     for(var j = 0; j < balls.length; j ++) {         for(var k = 0; k < balls.length; k ++) {             //两球间的圆心点坐标间距             var dx = balls[j].x - balls[k].x, dy = balls[j].y - balls[k].y;             //两球间的圆心距离             var distance = Math.sqrt(dx * dx + dy * dy);             //若距离小于两球半径之和则判为碰撞,令运动方向和原来的互反             if(distance < (balls[j].r + balls[k].r)) {                 balls[j].speedX = -balls[j].speedX;             balls[j].speedY = -balls[j].speedY;             balls[k].speedX = -balls[k].speedX;             balls[k].speedY = -balls[k].speedY;             }         }         move(balls[j]); //移动小球     }     //请求关键帧动画     raf = requestAnimationFrame(render); };   //画布单击时生成小球 canv.onclick = (e) => {     total --;     if(total < 0) return;     cancelAnimationFrame(raf);     var x = e.offsetX, y = e.offsetY, r = 20, color = `#${Math.random().toString(16).substr(-6)}`;     //防止小球太靠近边缘     if(x < 25) x = 25;     if(x > ww - 25) x = ww - 25;     if(y < 25) y = 25;     if(y > hh - 25) y = hh - 25;     balls.push({x: x, y: y, r: r, color: color, speedX: speed(), speedY: speed()});     render(); }; </script>

前一篇: canvas放大镜(两种机制)
下一篇: 在canvas画布中绘制二次贝塞尔曲线

发表评论:

       

评论列表 [2条]

#2 | 飞飞 于 2024-4-13 10:37 发布: 这也太好玩了……小球颜色随机,挺好看的,自由自在跟鱼一样四处游弋……这次点出10个……

#1 | 悄然 于 2024-4-13 10:34 发布: 小球随机碰撞,手机点击生成7个,自由运动,碰撞返回,完美显示……

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com